<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://aznot.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Kenneth</id>
	<title>Omnia - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://aznot.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Kenneth"/>
	<link rel="alternate" type="text/html" href="https://aznot.com/Special:Contributions/Kenneth"/>
	<updated>2026-04-30T10:34:06Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.41.0</generator>
	<entry>
		<id>https://aznot.com/index.php?title=Go&amp;diff=9877</id>
		<title>Go</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=Go&amp;diff=9877"/>
		<updated>2026-04-30T08:48:54Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: /* Ungoogable */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Stub for Go programming language&lt;br /&gt;
&lt;br /&gt;
== Ungoogable ==&lt;br /&gt;
&lt;br /&gt;
 https://www.google.com/search?q=golang&lt;br /&gt;
&lt;br /&gt;
Issues:&lt;br /&gt;
* Name &amp;quot;Go&amp;quot; is ungoogable / hastagable (use golang) *** MOST ANNOYING ***&lt;br /&gt;
&lt;br /&gt;
== Go Version ==&lt;br /&gt;
&lt;br /&gt;
 go version&lt;br /&gt;
&lt;br /&gt;
== Hello World ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// Hello World&lt;br /&gt;
package main&lt;br /&gt;
&lt;br /&gt;
import &amp;quot;fmt&amp;quot;&lt;br /&gt;
&lt;br /&gt;
func main() {&lt;br /&gt;
	fmt.Println(&amp;quot;Hello, world&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Online Go Editor and Runner ==&lt;br /&gt;
&lt;br /&gt;
 https://go.dev/&lt;br /&gt;
&lt;br /&gt;
== Install ==&lt;br /&gt;
&lt;br /&gt;
=== Ubuntu ===&lt;br /&gt;
&lt;br /&gt;
Standard version:&lt;br /&gt;
 sudo apt update&lt;br /&gt;
 sudo apt install golang-go&lt;br /&gt;
&lt;br /&gt;
Latest via PPA:&lt;br /&gt;
 sudo add-apt-repository ppa:longsleep/golang-backports&lt;br /&gt;
 sudo apt update&lt;br /&gt;
 sudo apt install golang-go&lt;br /&gt;
&lt;br /&gt;
Via SNAP:&lt;br /&gt;
 sudo snap install go --classic&lt;br /&gt;
&lt;br /&gt;
== keywords ==&lt;br /&gt;
&lt;br /&gt;
[[Category:Go]]&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=Go&amp;diff=9876</id>
		<title>Go</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=Go&amp;diff=9876"/>
		<updated>2026-04-30T08:48:45Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: /* Online Go Editor and Runner */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Stub for Go programming language&lt;br /&gt;
&lt;br /&gt;
== Ungoogable ==&lt;br /&gt;
&lt;br /&gt;
 https://www.google.com/search?q=golang&lt;br /&gt;
&lt;br /&gt;
Issues:&lt;br /&gt;
* Name &amp;quot;Go&amp;quot; is ungoogable / hastagable (use golang) *** MOST ANNOYING ***&lt;br /&gt;
&lt;br /&gt;
== Hello World ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// Hello World&lt;br /&gt;
package main&lt;br /&gt;
&lt;br /&gt;
import &amp;quot;fmt&amp;quot;&lt;br /&gt;
&lt;br /&gt;
func main() {&lt;br /&gt;
	fmt.Println(&amp;quot;Hello, world&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Online Go Editor and Runner ==&lt;br /&gt;
&lt;br /&gt;
 https://go.dev/&lt;br /&gt;
&lt;br /&gt;
== Install ==&lt;br /&gt;
&lt;br /&gt;
=== Ubuntu ===&lt;br /&gt;
&lt;br /&gt;
Standard version:&lt;br /&gt;
 sudo apt update&lt;br /&gt;
 sudo apt install golang-go&lt;br /&gt;
&lt;br /&gt;
Latest via PPA:&lt;br /&gt;
 sudo add-apt-repository ppa:longsleep/golang-backports&lt;br /&gt;
 sudo apt update&lt;br /&gt;
 sudo apt install golang-go&lt;br /&gt;
&lt;br /&gt;
Via SNAP:&lt;br /&gt;
 sudo snap install go --classic&lt;br /&gt;
&lt;br /&gt;
== keywords ==&lt;br /&gt;
&lt;br /&gt;
[[Category:Go]]&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=RLM&amp;diff=9875</id>
		<title>RLM</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=RLM&amp;diff=9875"/>
		<updated>2026-04-28T18:03:48Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: /* OpenSSL 1.1.0 required */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Reprise License Manager (RLM) is considered a, or a spiritual successor to, FLEXlm (now FlexNet Publisher). It was founded in 2006 by the original developers of GLOBEtrotter, the company that created FLEXlm&lt;br /&gt;
&lt;br /&gt;
* https://www.openlm.com/blog/what-is-reprise-rlm/&lt;br /&gt;
* https://www.openlm.com/supported-software/reprise-license-management-rlm-and-optimization-with-openlm/&lt;br /&gt;
&lt;br /&gt;
{FlexLM} (now officially FlexNet Publisher) is the industry-standard software license management system developed by Flexera. It controls, monitors, and optimizes application usage across networks, typically utilizing a floating (concurrent) license model where a central server manages a pool of licenses for multiple users. It supports node-locked licenses, manages license files (often found at C:\flexlm\license on Windows), and allows for vendor-specific configurations.&lt;br /&gt;
&lt;br /&gt;
See [[FlexLM]]&lt;br /&gt;
&lt;br /&gt;
== OpenSSL 1.1.0 required ==&lt;br /&gt;
&lt;br /&gt;
Ubuntu 24 fails with:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ ./getiolid&lt;br /&gt;
./getiolid: /lib/x86_64-linux-gnu/libcrypto.so.1.1: version `OPENSSL_1_1_0&#039; not found (required by ./getiolid)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cause: Ubuntu 24.04 (Noble Numbat) does not include libcrypto.so.1.1 in its official repositories because it has migrated to OpenSSL 3.0. You must manually install the legacy libssl1.1 package to obtain this file. &amp;lt;ref&amp;gt;https://askubuntu.com/questions/1521032/libssl-so-1-1-missing-on-ubuntu-24-04#:~:text=2,this%20package%20and%20updating%20it.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
One solution: (no longer exists)&lt;br /&gt;
 curl -O http://security.ubuntu.com/ubuntu/pool/main/o/openssl/libssl1.1_1.1.1f-1ubuntu2.22_amd64.deb&lt;br /&gt;
 dpkg -i libssl1.1_1.1.1f-1ubuntu2.22_amd64.deb&lt;br /&gt;
&lt;br /&gt;
 # also works: libssl1.1_1.1.1w-0+deb11u1_amd64.deb.md5sum&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Docker Ubuntu 24 needed:&lt;br /&gt;
 apt install sudo curl libterm-readline-gnu-perl libterm-ui-perl dmidecode iproute2&lt;br /&gt;
&lt;br /&gt;
== Systemd Service ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# cat /etc/systemd/system/rlm.service&lt;br /&gt;
[Unit]&lt;br /&gt;
Description=RLM License Server&lt;br /&gt;
After=network-online.target&lt;br /&gt;
Wants=network-online.target&lt;br /&gt;
&lt;br /&gt;
[Service]&lt;br /&gt;
Type=simple&lt;br /&gt;
User=license&lt;br /&gt;
Group=license&lt;br /&gt;
WorkingDirectory=/opt/rlm&lt;br /&gt;
&lt;br /&gt;
ExecStart=/bin/bash -x /opt/rlm/rlm-wrapper.sh&lt;br /&gt;
ExecStop=/bin/kill -TERM $MAINPID&lt;br /&gt;
&lt;br /&gt;
Restart=on-failure&lt;br /&gt;
RestartSec=5&lt;br /&gt;
&lt;br /&gt;
# Hardening (safe defaults for RHEL 8)&lt;br /&gt;
#NoNewPrivileges=true&lt;br /&gt;
#PrivateTmp=true&lt;br /&gt;
#ProtectSystem=full&lt;br /&gt;
#ProtectHome=true&lt;br /&gt;
#LimitNOFILE=262144&lt;br /&gt;
&lt;br /&gt;
[Install]&lt;br /&gt;
WantedBy=multi-user.target&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# cat /opt/rlm/rlm-wrapper.sh&lt;br /&gt;
#!/usr/bin/env bash&lt;br /&gt;
#set -euo pipefail&lt;br /&gt;
set -e&lt;br /&gt;
&lt;br /&gt;
RLM_HOME=&amp;quot;/opt/rlm&amp;quot;&lt;br /&gt;
RLM_BIN=&amp;quot;${RLM_HOME}/rlm&amp;quot;&lt;br /&gt;
LICENSE_FILE=&amp;quot;${RLM_HOME}/license.lic&amp;quot;&lt;br /&gt;
LOG_DIR=&amp;quot;/var/log/rlm&amp;quot;&lt;br /&gt;
LOG_FILE=&amp;quot;${LOG_DIR}/rlm.log&amp;quot;&lt;br /&gt;
&lt;br /&gt;
mkdir -p &amp;quot;${LOG_DIR}&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# -nows disables Web UI&lt;br /&gt;
#     use -ws 5054 if you want Web UI&lt;br /&gt;
# -dlog with + adds timestamped debug&lt;br /&gt;
#exec &amp;quot;${RLM_BIN}&amp;quot; \&lt;br /&gt;
#    -c &amp;quot;${LICENSE_FILE}&amp;quot; \&lt;br /&gt;
#    -ws 5054 \&lt;br /&gt;
#    -dlog +&amp;quot;${LOG_FILE}&amp;quot;&lt;br /&gt;
&lt;br /&gt;
exec &amp;quot;${RLM_BIN}&amp;quot; \&lt;br /&gt;
    -c &amp;quot;${LICENSE_FILE}&amp;quot; \&lt;br /&gt;
    -ws 5054 \&lt;br /&gt;
    -dlog +&amp;quot;${LOG_FILE}&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== keywords ==&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=Docker&amp;diff=9874</id>
		<title>Docker</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=Docker&amp;diff=9874"/>
		<updated>2026-04-28T17:29:16Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: /* Ubuntu Docker Install Basic Tools */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{subpages}}&lt;br /&gt;
&lt;br /&gt;
== Docker ==&lt;br /&gt;
&lt;br /&gt;
 https://www.docker.com/&lt;br /&gt;
&lt;br /&gt;
== Installing Docker Community Edition ==&lt;br /&gt;
&lt;br /&gt;
=== Ubuntu ===&lt;br /&gt;
&lt;br /&gt;
=== RHEL ===&lt;br /&gt;
&lt;br /&gt;
 RHEL | Docker Docs&lt;br /&gt;
 https://docs.docker.com/engine/install/rhel/&lt;br /&gt;
&lt;br /&gt;
If missing dnf see [[RHEL#DNF]]&lt;br /&gt;
&lt;br /&gt;
 # Remove Non Docker-CE:&lt;br /&gt;
 sudo dnf remove docker \&lt;br /&gt;
                  docker-client \&lt;br /&gt;
                  docker-client-latest \&lt;br /&gt;
                  docker-common \&lt;br /&gt;
                  docker-latest \&lt;br /&gt;
                  docker-latest-logrotate \&lt;br /&gt;
                  docker-logrotate \&lt;br /&gt;
                  docker-engine \&lt;br /&gt;
                  podman \&lt;br /&gt;
                  runc&lt;br /&gt;
&lt;br /&gt;
 sudo dnf -y install dnf-plugins-core&lt;br /&gt;
 sudo dnf config-manager --add-repo https://download.docker.com/linux/rhel/docker-ce.repo&lt;br /&gt;
&lt;br /&gt;
 sudo dnf install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin&lt;br /&gt;
&lt;br /&gt;
 sudo systemctl enable --now docker&lt;br /&gt;
&lt;br /&gt;
 sudo docker run hello-world&lt;br /&gt;
&lt;br /&gt;
== Docker Hub ==&lt;br /&gt;
&lt;br /&gt;
 Docker Hub&lt;br /&gt;
 https://hub.docker.com/&lt;br /&gt;
&lt;br /&gt;
=== Search Hub ===&lt;br /&gt;
&lt;br /&gt;
 docker search [image]&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
 docker search ubuntu&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Usage:  docker search [OPTIONS] TERM&lt;br /&gt;
&lt;br /&gt;
Search Docker Hub for images&lt;br /&gt;
&lt;br /&gt;
Options:&lt;br /&gt;
  -f, --filter filter   Filter output based on conditions provided&lt;br /&gt;
      --format string   Pretty-print search using a Go template&lt;br /&gt;
      --limit int       Max number of search results&lt;br /&gt;
      --no-trunc        Don&#039;t truncate output&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Search Tags and Images ===&lt;br /&gt;
&lt;br /&gt;
==== docker-browse ====&lt;br /&gt;
&lt;br /&gt;
Show all images in registry&lt;br /&gt;
 docker-browse --registry [registry] images&lt;br /&gt;
&lt;br /&gt;
Show all tags of image:&lt;br /&gt;
 docker-browse --registry [registry] tags [image]&lt;br /&gt;
&lt;br /&gt;
Registry being that from ~/.docker/config.json&lt;br /&gt;
&lt;br /&gt;
Can change default registry with &amp;quot;save&amp;quot; to ~/.docker-browse.json&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ docker-browse save --registry myregistry.example.com:5000 --protocol https&lt;br /&gt;
&lt;br /&gt;
$ cat ~/.docker-browse.json&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;defRegistry&amp;quot;: &amp;quot;myregistry.example.com:5000&amp;quot;,&lt;br /&gt;
    &amp;quot;defProtocol&amp;quot;: &amp;quot;https&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Install with:&lt;br /&gt;
 # global&lt;br /&gt;
 sudo npm install -g docker-browse&lt;br /&gt;
&lt;br /&gt;
 # local:&lt;br /&gt;
 cd ~&lt;br /&gt;
 mkdir -p ~/.npm&lt;br /&gt;
 cd ~/.npm&lt;br /&gt;
 npm install --prefix `pwd` docker-browse&lt;br /&gt;
 cd ~/.bin&lt;br /&gt;
 ln -sfn ~/.npm/node_modules/docker-browse/bin/docker-browse.js ~/.local/bin/docker-browse&lt;br /&gt;
&lt;br /&gt;
Or local with:&lt;br /&gt;
 mkdir ~/.src/docker-browse&lt;br /&gt;
 cd ~/.src/docker-browse&lt;br /&gt;
 # npm install docker-browse  # umm did this ever work?&lt;br /&gt;
 npm install --prefix `pwd` docker-browse&lt;br /&gt;
 # cd ~/.bin&lt;br /&gt;
 cd ~/.local/bin&lt;br /&gt;
 # ln -s ../.src/docker-browse/node_modules/.bin/docker-browse  # umm did this change names?&lt;br /&gt;
 ln -s ../.src/docker-browse/node_modules/bin/docker-browse.js docker-browse&lt;br /&gt;
&lt;br /&gt;
Assuming ~/.local/bin or .bin is in your path&lt;br /&gt;
&lt;br /&gt;
ref: https://www.npmjs.com/package/docker-browse&lt;br /&gt;
&lt;br /&gt;
==== skopeo ====&lt;br /&gt;
&lt;br /&gt;
Install skopeo with apt:&lt;br /&gt;
 sudo apt install skopeo&lt;br /&gt;
&lt;br /&gt;
Login:&lt;br /&gt;
 skopeo login docker://[repo:port]&lt;br /&gt;
&lt;br /&gt;
Logout:&lt;br /&gt;
 skopeo login docker://[repo:port]&lt;br /&gt;
&lt;br /&gt;
List tags in registry:&lt;br /&gt;
 skopeo list-tags docker://[repo:port]/[image]/[tag]&lt;br /&gt;
&lt;br /&gt;
Inspect image:&lt;br /&gt;
 skopeo delete docker://[repo:port]/[image]/[tag]&lt;br /&gt;
&lt;br /&gt;
Copy image in registry:&lt;br /&gt;
 skopeo copy docker://[repo:port]/[image]/[tag]  docker://[repo:port]/[new_image]/[new_tag]&lt;br /&gt;
&lt;br /&gt;
Delete image in registry: (( WARNING - THIS DELETES THE IMAGE, NOT JUST THE TAG ))&lt;br /&gt;
 skopeo delete docker://[repo:port]/[image]/[tag]&lt;br /&gt;
&lt;br /&gt;
== What Is Docker ==&lt;br /&gt;
&lt;br /&gt;
Package your application into a standardized unit for software development&lt;br /&gt;
&lt;br /&gt;
:&amp;quot;Docker containers wrap a piece of software in a complete filesystem that contains everything needed to run: code, runtime, system tools, system libraries – anything that can be installed on a server. This guarantees that the software will always run the same, regardless of its environment.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
https://www.docker.com/what-docker&lt;br /&gt;
&lt;br /&gt;
--&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Docker is an open-source project that automates the deployment of applications inside software containers.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Docker provides an additional layer of abstraction and automation of operating-system-level virtualization on Linux. Docker uses the resource isolation features of the Linux kernel such as cgroups and kernel namespaces, and a union-capable file system such as OverlayFS and others to allow independent &amp;quot;containers&amp;quot; to run within a single Linux instance, avoiding the overhead of starting and maintaining virtual machines.&lt;br /&gt;
&lt;br /&gt;
The Linux kernel&#039;s support for namespaces mostly isolates an application&#039;s view of the operating environment, including process trees, network, user IDs and mounted file systems, while the kernel&#039;s cgroups provide resource limiting, including the CPU, memory, block I/O and network. Since version 0.9, Docker includes the libcontainer library as its own way to directly use virtualization facilities provided by the Linux kernel, in addition to using abstracted virtualization interfaces via libvirt, LXC (Linux Containers) and systemd-nspawn.&lt;br /&gt;
&lt;br /&gt;
As actions are done to a Docker base image, union file system layers are created and documented, such that each layer fully describes how to recreate an action. This strategy enables Docker&#039;s lightweight images, as only layer updates need to be propagated (compared to full VMs, for example).&lt;br /&gt;
&lt;br /&gt;
https://en.wikipedia.org/wiki/Docker_(software)&lt;br /&gt;
&lt;br /&gt;
== Removing all containers and images ==&lt;br /&gt;
&lt;br /&gt;
 #  Stop the container(s) using the following command:&lt;br /&gt;
 docker-compose down&lt;br /&gt;
 #  Delete all containers using the following command:&lt;br /&gt;
 docker rm -f $(docker ps -a -q)&lt;br /&gt;
 #  Delete all volumes using the following command:&lt;br /&gt;
 docker volume rm $(docker volume ls -q)&lt;br /&gt;
 #  Prune system images, included stopped:&lt;br /&gt;
 docker system prune -a&lt;br /&gt;
&lt;br /&gt;
Ref [https://docs.tibco.com/pub/mash-local/4.1.1/doc/html/docker/GUID-BD850566-5B79-4915-987E-430FC38DAAE4.html] [https://www.digitalocean.com/community/tutorials/how-to-remove-docker-images-containers-and-volumes]&lt;br /&gt;
&lt;br /&gt;
== A Docker Tutorial for Beginners ==&lt;br /&gt;
&lt;br /&gt;
A Docker Tutorial for Beginners&amp;lt;br&amp;gt;&lt;br /&gt;
https://docker-curriculum.com/&lt;br /&gt;
&lt;br /&gt;
Once you are done installing Docker, test your Docker installation by running the following:&lt;br /&gt;
 # docker run hello-world&lt;br /&gt;
&lt;br /&gt;
hello-world container: https://hub.docker.com/_/hello-world&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
root@server:~# docker run hello-world&lt;br /&gt;
Unable to find image &#039;hello-world:latest&#039; locally&lt;br /&gt;
latest: Pulling from library/hello-world&lt;br /&gt;
b8dfde127a29: Pull complete&lt;br /&gt;
Digest: sha256:9f6ad537c5132bcce57f7a0a20e317228d382c3cd61edae14650eec68b2b345c&lt;br /&gt;
Status: Downloaded newer image for hello-world:latest&lt;br /&gt;
&lt;br /&gt;
Hello from Docker!&lt;br /&gt;
This message shows that your installation appears to be working correctly.&lt;br /&gt;
&lt;br /&gt;
To generate this message, Docker took the following steps:&lt;br /&gt;
 1. The Docker client contacted the Docker daemon.&lt;br /&gt;
 2. The Docker daemon pulled the &amp;quot;hello-world&amp;quot; image from the Docker Hub.&lt;br /&gt;
    (amd64)&lt;br /&gt;
 3. The Docker daemon created a new container from that image which runs the&lt;br /&gt;
    executable that produces the output you are currently reading.&lt;br /&gt;
 4. The Docker daemon streamed that output to the Docker client, which sent it&lt;br /&gt;
    to your terminal.&lt;br /&gt;
&lt;br /&gt;
To try something more ambitious, you can run an Ubuntu container with:&lt;br /&gt;
 $ docker run -it ubuntu bash&lt;br /&gt;
&lt;br /&gt;
Share images, automate workflows, and more with a free Docker ID:&lt;br /&gt;
 https://hub.docker.com/&lt;br /&gt;
&lt;br /&gt;
For more examples and ideas, visit:&lt;br /&gt;
 https://docs.docker.com/get-started/&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example of Ubuntu container:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
root@mserver:~# docker run -it ubuntu bash&lt;br /&gt;
Unable to find image &#039;ubuntu:latest&#039; locally&lt;br /&gt;
latest: Pulling from library/ubuntu&lt;br /&gt;
c549ccf8d472: Pull complete&lt;br /&gt;
Digest: sha256:aba80b77e27148d99c034a987e7da3a287ed455390352663418c0f2ed40417fe&lt;br /&gt;
Status: Downloaded newer image for ubuntu:latest&lt;br /&gt;
root@4d827b59d198:/#&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Try Busybox container:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
## Fetch container&lt;br /&gt;
docker pull busybox&lt;br /&gt;
&lt;br /&gt;
## List containers&lt;br /&gt;
docker images&lt;br /&gt;
&lt;br /&gt;
## Run container (did nothing then exited)&lt;br /&gt;
docker run busybox&lt;br /&gt;
&lt;br /&gt;
## Run container with instructions to do something&lt;br /&gt;
docker run busybox echo &amp;quot;hello from busybox&amp;quot;&lt;br /&gt;
    hello from busybox&lt;br /&gt;
&lt;br /&gt;
## List running docker containers:&lt;br /&gt;
docker ps&lt;br /&gt;
    CONTAINER ID   IMAGE             COMMAND                  CREATED        STATUS       PORTS         NAMES&lt;br /&gt;
&lt;br /&gt;
## List all dockers containers that we have run:&lt;br /&gt;
docker ps -a&lt;br /&gt;
&lt;br /&gt;
## Run in interactive mode:&lt;br /&gt;
docker run -it busybox sh&lt;br /&gt;
&lt;br /&gt;
## Run and auto delete on exit&lt;br /&gt;
docker run --rm busybox echo &amp;quot;hello&amp;quot;&lt;br /&gt;
&lt;br /&gt;
## Remove docker containers (clean up after yourself&lt;br /&gt;
docker rm [CONTAINER_ID  CONTAINER_ID  ...]&lt;br /&gt;
&lt;br /&gt;
## Remove all exited docker containers:&lt;br /&gt;
docker rm $(docker ps -a -q -f status=exited)&lt;br /&gt;
# or in later editions&lt;br /&gt;
docker container prune&lt;br /&gt;
&lt;br /&gt;
## Remove docker images:&lt;br /&gt;
docker rmi [IMAGE_ID  IMAGE_ID ...]&lt;br /&gt;
&lt;br /&gt;
## Run a detached instance, and name it&lt;br /&gt;
docker run -d --name [NAME] [IMAGE]&lt;br /&gt;
# example:  docker run -d --rm --name u3 -it ubuntu bash&lt;br /&gt;
&lt;br /&gt;
## Attach to running container: [https://docs.docker.com/engine/reference/commandline/attach/]&lt;br /&gt;
docker attach [NAME]&lt;br /&gt;
&lt;br /&gt;
## Detach from a running container: [https://docs.docker.com/engine/reference/commandline/attach/]&lt;br /&gt;
CTRL-p CTRL-q&lt;br /&gt;
&lt;br /&gt;
## Stop detached instance&lt;br /&gt;
docker stop [NAME]&lt;br /&gt;
&lt;br /&gt;
## Pull a specific version:&lt;br /&gt;
docker pull ubuntu:latest&lt;br /&gt;
docker pull ubuntu:18.04&lt;br /&gt;
docker pull ubuntu:16.04&lt;br /&gt;
&lt;br /&gt;
## Run specific version&lt;br /&gt;
docker run ubuntu:16.04&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
root@server:~# docker pull busybox&lt;br /&gt;
Using default tag: latest&lt;br /&gt;
latest: Pulling from library/busybox&lt;br /&gt;
b71f96345d44: Pull complete&lt;br /&gt;
Digest: sha256:930490f97e5b921535c153e0e7110d251134cc4b72bbb8133c6a5065cc68580d&lt;br /&gt;
Status: Downloaded newer image for busybox:latest&lt;br /&gt;
docker.io/library/busybox:latest&lt;br /&gt;
&lt;br /&gt;
root@server:~# docker images&lt;br /&gt;
REPOSITORY             TAG            IMAGE ID       CREATED         SIZE&lt;br /&gt;
ubuntu                 latest         9873176a8ff5   13 days ago     72.7MB&lt;br /&gt;
busybox                latest         69593048aa3a   3 weeks ago     1.24MB&lt;br /&gt;
hello-world            latest         d1165f221234   3 months ago    13.3kB&lt;br /&gt;
&lt;br /&gt;
root@server:~# docker ps -a&lt;br /&gt;
CONTAINER ID   IMAGE                            COMMAND                  CREATED         STATUS                     PORTS                         NAMES&lt;br /&gt;
495cf502dde2   busybox                          &amp;quot;echo &#039;hello from bu…&amp;quot;   2 minutes ago   Exited (0) 2 minutes ago    &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Create Image ===&lt;br /&gt;
&lt;br /&gt;
All user images are based on a base image.&lt;br /&gt;
&lt;br /&gt;
Login to Docker Hub:&lt;br /&gt;
 docker login&lt;br /&gt;
&lt;br /&gt;
Sample Dockerfile:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FROM python:3&lt;br /&gt;
&lt;br /&gt;
# set a directory for the app&lt;br /&gt;
WORKDIR /usr/src/app&lt;br /&gt;
&lt;br /&gt;
# copy all the files to the container&lt;br /&gt;
COPY . .&lt;br /&gt;
&lt;br /&gt;
# install dependencies&lt;br /&gt;
RUN pip install --no-cache-dir -r requirements.txt&lt;br /&gt;
&lt;br /&gt;
# define the port number the container should expose&lt;br /&gt;
EXPOSE 5000&lt;br /&gt;
&lt;br /&gt;
# run the command&lt;br /&gt;
CMD [&amp;quot;python&amp;quot;, &amp;quot;./app.py&amp;quot;]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Simple Dockerfile:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FROM ubuntu&lt;br /&gt;
&lt;br /&gt;
RUN touch test.txt&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Build image:&lt;br /&gt;
 docker build -t [username]/[project] .&lt;br /&gt;
&lt;br /&gt;
Test imagE:&lt;br /&gt;
 docker run [username]/[project]&amp;lt;:version&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Push image to Docker Hub:&lt;br /&gt;
 docker push [username]/[project]&lt;br /&gt;
&lt;br /&gt;
See parent hash of image:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
docker history --format &#039;{{ .ID }}&#039; --no-trunc [USERNAME]/[PROJECT]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Pull Image ==&lt;br /&gt;
&lt;br /&gt;
 docker pull &lt;br /&gt;
&lt;br /&gt;
Hash specific: [https://docs.docker.com/engine/reference/commandline/pull/]&lt;br /&gt;
 docker pull ubuntu@sha256:26c68657ccce2cb0a31b330cb0be2b5e108d467f641c62e13ab40cbec258c68d&lt;br /&gt;
&lt;br /&gt;
Hash specific in Dockerfile: [https://docs.docker.com/engine/reference/commandline/pull/]&lt;br /&gt;
 FROM ubuntu@sha256:26c68657ccce2cb0a31b330cb0be2b5e108d467f641c62e13ab40cbec258c68d&lt;br /&gt;
&lt;br /&gt;
== Run Image ==&lt;br /&gt;
&lt;br /&gt;
 docker run -it --rm [image:tag] /bin/bash&lt;br /&gt;
&lt;br /&gt;
If you want to force a specific entry point:&lt;br /&gt;
 docker run -it --rm --entrypoint /bin/sh [image:tag]&lt;br /&gt;
&lt;br /&gt;
== Attach to Running Docker ==&lt;br /&gt;
&lt;br /&gt;
 docker attach [NAME]&lt;br /&gt;
&lt;br /&gt;
If it isn&#039;t running bash, you can do something like this:&lt;br /&gt;
 docker exec -it [NAME] /bin/bash&lt;br /&gt;
&lt;br /&gt;
== Run Docker Ubuntu Mounted to Current Directory ==&lt;br /&gt;
&lt;br /&gt;
 docker run --rm -it -v .:/mnt ubuntu bash&lt;br /&gt;
&lt;br /&gt;
== Running ARM on x86 ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Problem:&#039;&#039;&#039;&lt;br /&gt;
 uname -m # Display the host architecture&lt;br /&gt;
 #x86_64&lt;br /&gt;
&lt;br /&gt;
 docker run --rm -t arm64v8/ubuntu uname -m # Run an executable made for aarch64 on x86_64&lt;br /&gt;
 #standard_init_linux.go:211: exec user process caused &amp;quot;exec format error&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Solution:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
As expected the instructions are not recognized since the packages are not installed yet. Installing the following packages should allow you to enable support for aarch64 containers on your x86 workstation:&lt;br /&gt;
&lt;br /&gt;
 sudo apt-get install qemu binfmt-support qemu-user-static # Install the qemu packages&lt;br /&gt;
 docker run --rm --privileged multiarch/qemu-user-static --reset -p yes # This step will execute the registering scripts&lt;br /&gt;
&lt;br /&gt;
 docker run --rm -t arm64v8/ubuntu uname -m # Testing the emulation environment&lt;br /&gt;
 #aarch64&lt;br /&gt;
&lt;br /&gt;
ref: [https://www.stereolabs.com/docs/docker/building-arm-container-on-x86/]&lt;br /&gt;
&lt;br /&gt;
== Static MAC ==&lt;br /&gt;
&lt;br /&gt;
 docker run ... --mac-address 12:34:56:78:9a:bc&lt;br /&gt;
&lt;br /&gt;
ref: [https://docs.docker.com/engine/reference/run/#:~:text=By%20default%2C%20the%20MAC%20address,specified%20MAC%20addresses%20are%20unique.]&lt;br /&gt;
&lt;br /&gt;
== Exporting ==&lt;br /&gt;
&lt;br /&gt;
=== Save and Load Image ===&lt;br /&gt;
&lt;br /&gt;
 docker save -o [image.tar] [IMAGE]&lt;br /&gt;
 # or&lt;br /&gt;
 docker save [IMAGE] &amp;gt; [image.tar]&lt;br /&gt;
&lt;br /&gt;
 docker load -i [image.tar]&lt;br /&gt;
 # or&lt;br /&gt;
 cat [image.tar] | docker load&lt;br /&gt;
&lt;br /&gt;
=== Export and Import Container ===&lt;br /&gt;
&lt;br /&gt;
 docker export [CONTAINER_ID_OR_NAME] &amp;gt; [container.tar]&lt;br /&gt;
&lt;br /&gt;
 docker import [container.tar] [IMAGE_NAME:VER]&lt;br /&gt;
 # or&lt;br /&gt;
 cat [container.tar] | docker import - [IMAGE_NAME:VER]&lt;br /&gt;
&lt;br /&gt;
== Extract Build Steps ==&lt;br /&gt;
&lt;br /&gt;
Don&#039;t truncate the lines - gives you the FULL command line:&lt;br /&gt;
 docker history [IMAGE_ID] --no-trunc | tac&lt;br /&gt;
&lt;br /&gt;
Show only the docker step - full command line, no other details (.CreatedBy is the command that created the layer, not the author)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
docker history [IMAGE_ID] --format &#039;{{.CreatedBy}}&#039; --no-trunc | tac&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Show only the docker step - Don&#039;t truncate the lines and wrap lines at &amp;amp;&amp;amp; - really nice view&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
docker history --no-trunc [IMAGE_ID] | tac | tr -s &#039; &#039; | cut -d &amp;quot; &amp;quot; -f 5- | sed &#039;s,^/bin/sh -c #(nop) ,,g&#039; | sed &#039;s,^/bin/sh -c,RUN,g&#039; | sed &#039;s, &amp;amp;&amp;amp; ,\n  &amp;amp; ,g&#039; | sed &#039;s,\s*[0-9]*[\.]*[0-9]*\s*[kMG]*B\s*$,,g&#039; | head -n -1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ref: &amp;lt;ref&amp;gt;https://stackoverflow.com/questions/19104847/how-to-generate-a-dockerfile-from-an-image&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See parent hash of image:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
docker history --format &#039;{{ .ID }}&#039; --no-trunc [IMAGE_ID]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Docker Compose ==&lt;br /&gt;
&lt;br /&gt;
 apt install docker-compose docker-compose-plugin&lt;br /&gt;
 # docker-compose provides &amp;quot;docker-compose&amp;quot; command&lt;br /&gt;
 # docker-compose-plugin provides &amp;quot;docker compose&amp;quot; command&lt;br /&gt;
&lt;br /&gt;
 docker compose up -d&lt;br /&gt;
&lt;br /&gt;
Sample docker-compose.yml:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
version: &amp;quot;3.0&amp;quot;  # compose API version&lt;br /&gt;
services:&lt;br /&gt;
  license-service:&lt;br /&gt;
    container_name: license&lt;br /&gt;
    # Docker image name&lt;br /&gt;
    image: flexlm:v1&lt;br /&gt;
    build:&lt;br /&gt;
      context: .&lt;br /&gt;
    user: root&lt;br /&gt;
    restart: always&lt;br /&gt;
    # mac address tied to license file&lt;br /&gt;
    mac_address: xx:xx:xx:xx:xx:xx&lt;br /&gt;
    ports:&lt;br /&gt;
      # 27000 for lmgrd&lt;br /&gt;
      - 27000:27000&lt;br /&gt;
      # 27001 for armlmd&lt;br /&gt;
      - 27001:27001&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Docker BuildX ==&lt;br /&gt;
&lt;br /&gt;
buildx:&lt;br /&gt;
 https://github.com/docker/buildx&lt;br /&gt;
&lt;br /&gt;
apt package:&lt;br /&gt;
 docker-buildx/jammy-updates,jammy-security 0.12.1-0ubuntu1~22.04.2 amd64&lt;br /&gt;
   Docker CLI plugin for extended build capabilities with BuildKit&lt;br /&gt;
&lt;br /&gt;
Install buildx with apt:&lt;br /&gt;
 sudo apt install docker-buildx&lt;br /&gt;
&lt;br /&gt;
Set buildx as default builder:&lt;br /&gt;
 docker buildx install&lt;br /&gt;
&lt;br /&gt;
To remove buildx alias:&lt;br /&gt;
 docker buildx uninstall&lt;br /&gt;
&lt;br /&gt;
You can build multi-platform images using three different strategies that are supported by Buildx and Dockerfiles:&lt;br /&gt;
# Using the QEMU emulation support in the kernel&lt;br /&gt;
# Building on multiple native nodes using the same builder instance&lt;br /&gt;
# Using a stage in Dockerfile to cross-compile to different architectures&lt;br /&gt;
&lt;br /&gt;
If not using Docker Desktop:&lt;br /&gt;
 docker run --privileged --rm tonistiigi/binfmt --install all&lt;br /&gt;
&lt;br /&gt;
Add additional platforms:&lt;br /&gt;
 docker buildx create --use --name mybuild node-amd64&lt;br /&gt;
 docker buildx create --append --name mybuild node-arm64&lt;br /&gt;
 docker buildx build --platform linux/amd64,linux/arm64 .&lt;br /&gt;
&lt;br /&gt;
== Proxy ==&lt;br /&gt;
&lt;br /&gt;
Client:&lt;br /&gt;
 ~/.docker/config.json&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
 &amp;quot;proxies&amp;quot;: {&lt;br /&gt;
   &amp;quot;default&amp;quot;: {&lt;br /&gt;
     &amp;quot;httpProxy&amp;quot;: &amp;quot;http://proxy.example.com:3128&amp;quot;,&lt;br /&gt;
     &amp;quot;httpsProxy&amp;quot;: &amp;quot;https://proxy.example.com:3129&amp;quot;,&lt;br /&gt;
     &amp;quot;noProxy&amp;quot;: &amp;quot;*.test.example.com,.example.org,127.0.0.0/8&amp;quot;&lt;br /&gt;
   }&lt;br /&gt;
 }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ref: Configure Docker to use a proxy server | Docker Documentation - https://docs.docker.com/network/proxy/&lt;br /&gt;
&lt;br /&gt;
Configure Docker Service&lt;br /&gt;
&lt;br /&gt;
 systemctl edit docker.service&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[Service]&lt;br /&gt;
Environment=&amp;quot;HTTP_PROXY=http://proxy.example.com:3128&amp;quot;,&lt;br /&gt;
Environment=&amp;quot;HTTPS_PROXY=httpS://proxy.example.com:3129&amp;quot;,&lt;br /&gt;
Environment=&amp;quot;NO_PROXY=localhost,127.0.0.1&amp;quot;,&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 systemctl restart docker.service&lt;br /&gt;
&lt;br /&gt;
== Registry ==&lt;br /&gt;
&lt;br /&gt;
=== Registry API ===&lt;br /&gt;
&lt;br /&gt;
 HTTP API V2 | Docker Documentation&lt;br /&gt;
 https://docs.docker.com/registry/spec/api/&lt;br /&gt;
&lt;br /&gt;
List available images:&lt;br /&gt;
 GET /v2/_catalog&lt;br /&gt;
 GET https://registry.example.com/v2/_catalog&lt;br /&gt;
&lt;br /&gt;
Pretty print output:&lt;br /&gt;
 curl -s https://registry.example.com/v2/_catalog | jq&lt;br /&gt;
 curl -s https://registry.example.com/v2/_catalog | python3 -m json.tool&lt;br /&gt;
&lt;br /&gt;
Pagenation&lt;br /&gt;
 GET /v2/_catalog?n=&amp;lt;count&amp;gt;&lt;br /&gt;
 # using a name of repo in a previous result:&lt;br /&gt;
 GET /v2/_catalog?n=&amp;lt;count&amp;gt;&amp;amp;last=&amp;lt;name_repo_start_with&amp;gt;&lt;br /&gt;
&lt;br /&gt;
List tags: (pagination also works with tags)&lt;br /&gt;
 GET /v2/&amp;lt;image_name&amp;gt;/tags/list&lt;br /&gt;
&lt;br /&gt;
Delete image:&lt;br /&gt;
 # reference must be a digest or the delete will fail.&lt;br /&gt;
 DELETE /v2/&amp;lt;name&amp;gt;/manifests/&amp;lt;reference&amp;gt;&lt;br /&gt;
&lt;br /&gt;
API:&lt;br /&gt;
 Method	Path	Entity	Description&lt;br /&gt;
 GET	/v2/	Base	Check that the endpoint implements Docker Registry API V2.&lt;br /&gt;
 GET	/v2/&amp;lt;name&amp;gt;/tags/list	Tags	Fetch the tags under the repository identified by name.&lt;br /&gt;
 GET	/v2/&amp;lt;name&amp;gt;/manifests/&amp;lt;reference&amp;gt;	Manifest	Fetch the manifest identified by name and reference where reference can be a tag or digest. A HEAD request can also be issued to this endpoint to obtain resource information without receiving all data.&lt;br /&gt;
 PUT	/v2/&amp;lt;name&amp;gt;/manifests/&amp;lt;reference&amp;gt;	Manifest	Put the manifest identified by name and reference where reference can be a tag or digest.&lt;br /&gt;
 DELETE	/v2/&amp;lt;name&amp;gt;/manifests/&amp;lt;reference&amp;gt;	Manifest	Delete the manifest or tag identified by name and reference where reference can be a tag or digest. Note that a manifest can only be deleted by digest.&lt;br /&gt;
 GET	/v2/&amp;lt;name&amp;gt;/blobs/&amp;lt;digest&amp;gt;	Blob	Retrieve the blob from the registry identified by digest. A HEAD request can also be issued to this endpoint to obtain resource information without receiving all data.&lt;br /&gt;
 DELETE	/v2/&amp;lt;name&amp;gt;/blobs/&amp;lt;digest&amp;gt;	Blob	Delete the blob identified by name and digest&lt;br /&gt;
 POST	/v2/&amp;lt;name&amp;gt;/blobs/uploads/	Initiate Blob Upload	Initiate a resumable blob upload. If successful, an upload location will be provided to complete the upload. Optionally, if the digest parameter is present, the request body will be used to complete the upload in a single request.&lt;br /&gt;
 GET	/v2/&amp;lt;name&amp;gt;/blobs/uploads/&amp;lt;uuid&amp;gt;	Blob Upload	Retrieve status of upload identified by uuid. The primary purpose of this endpoint is to resolve the current status of a resumable upload.&lt;br /&gt;
 PATCH	/v2/&amp;lt;name&amp;gt;/blobs/uploads/&amp;lt;uuid&amp;gt;	Blob Upload	Upload a chunk of data for the specified upload.&lt;br /&gt;
 PUT	/v2/&amp;lt;name&amp;gt;/blobs/uploads/&amp;lt;uuid&amp;gt;	Blob Upload	Complete the upload specified by uuid, optionally appending the body as the final chunk.&lt;br /&gt;
 DELETE	/v2/&amp;lt;name&amp;gt;/blobs/uploads/&amp;lt;uuid&amp;gt;	Blob Upload	Cancel outstanding upload processes, releasing associated resources. If this is not called, the unfinished uploads will eventually timeout.&lt;br /&gt;
 GET	/v2/_catalog	Catalog	Retrieve a sorted, json list of repositories available in the registry.&lt;br /&gt;
&lt;br /&gt;
== Reducing Image Size ==&lt;br /&gt;
&lt;br /&gt;
1. Bundle Layers&lt;br /&gt;
&lt;br /&gt;
 RUN apt-get update -y \&lt;br /&gt;
   &amp;amp;&amp;amp; apt install -y package_one&lt;br /&gt;
&lt;br /&gt;
2. Avoid extra packages&lt;br /&gt;
&lt;br /&gt;
 apt install -y --no-install-recommends&lt;br /&gt;
&lt;br /&gt;
3. Clean up after install&lt;br /&gt;
&lt;br /&gt;
 apt ... \&lt;br /&gt;
 &amp;amp;&amp;amp; rm -rf /var/lib/apt/lists/*&lt;br /&gt;
&lt;br /&gt;
4. Pick smaller image&lt;br /&gt;
&lt;br /&gt;
 alpine vs ubuntu&lt;br /&gt;
&lt;br /&gt;
5. Use .dockerignore&lt;br /&gt;
&lt;br /&gt;
ref: [https://towardsdatascience.com/5-easy-to-implement-tricks-to-trim-down-your-docker-image-size-263978a6ed29]&lt;br /&gt;
&lt;br /&gt;
== Missing Docker Images Packages ==&lt;br /&gt;
&lt;br /&gt;
scp:&lt;br /&gt;
 apt update ; apt install openssh-clients&lt;br /&gt;
&lt;br /&gt;
== Issues ==&lt;br /&gt;
&lt;br /&gt;
=== apt getting stuck at configuring tzdata ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Configuring tzdata&lt;br /&gt;
------------------&lt;br /&gt;
&lt;br /&gt;
Please select the geographic area in which you live. Subsequent configuration&lt;br /&gt;
questions will narrow this down by presenting a list of cities, representing&lt;br /&gt;
the time zones in which they are located.&lt;br /&gt;
&lt;br /&gt;
  1. Africa      4. Australia  7. Atlantic  10. Pacific  13. Etc&lt;br /&gt;
  2. America     5. Arctic     8. Europe    11. SystemV&lt;br /&gt;
  3. Antarctica  6. Asia       9. Indian    12. US&lt;br /&gt;
Geographic area: &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Solution:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FROM ubuntu:20.04&lt;br /&gt;
&lt;br /&gt;
ENV TZ=Asia/Dubai&lt;br /&gt;
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime &amp;amp;&amp;amp; echo $TZ &amp;gt; /etc/timezone&lt;br /&gt;
&lt;br /&gt;
RUN apt update&lt;br /&gt;
RUN apt install -y tzdata&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ref: Fix: tzdata hangs during Docker image build - DEV Community - https://dev.to/grigorkh/fix-tzdata-hangs-during-docker-image-build-4o9m&lt;br /&gt;
&lt;br /&gt;
== Ubuntu Docker Install Basic Tools ==&lt;br /&gt;
&lt;br /&gt;
 apt update&lt;br /&gt;
&lt;br /&gt;
 # basic tools&lt;br /&gt;
 apt install sudo curl wget screen vim less&lt;br /&gt;
&lt;br /&gt;
 # more tools&lt;br /&gt;
 apt install dmidecode iproute2 net-tools&lt;br /&gt;
&lt;br /&gt;
 # even more tools&lt;br /&gt;
 apt install nmap&lt;br /&gt;
&lt;br /&gt;
== keywords ==&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=Docker&amp;diff=9873</id>
		<title>Docker</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=Docker&amp;diff=9873"/>
		<updated>2026-04-28T17:28:21Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: /* keywords */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{subpages}}&lt;br /&gt;
&lt;br /&gt;
== Docker ==&lt;br /&gt;
&lt;br /&gt;
 https://www.docker.com/&lt;br /&gt;
&lt;br /&gt;
== Installing Docker Community Edition ==&lt;br /&gt;
&lt;br /&gt;
=== Ubuntu ===&lt;br /&gt;
&lt;br /&gt;
=== RHEL ===&lt;br /&gt;
&lt;br /&gt;
 RHEL | Docker Docs&lt;br /&gt;
 https://docs.docker.com/engine/install/rhel/&lt;br /&gt;
&lt;br /&gt;
If missing dnf see [[RHEL#DNF]]&lt;br /&gt;
&lt;br /&gt;
 # Remove Non Docker-CE:&lt;br /&gt;
 sudo dnf remove docker \&lt;br /&gt;
                  docker-client \&lt;br /&gt;
                  docker-client-latest \&lt;br /&gt;
                  docker-common \&lt;br /&gt;
                  docker-latest \&lt;br /&gt;
                  docker-latest-logrotate \&lt;br /&gt;
                  docker-logrotate \&lt;br /&gt;
                  docker-engine \&lt;br /&gt;
                  podman \&lt;br /&gt;
                  runc&lt;br /&gt;
&lt;br /&gt;
 sudo dnf -y install dnf-plugins-core&lt;br /&gt;
 sudo dnf config-manager --add-repo https://download.docker.com/linux/rhel/docker-ce.repo&lt;br /&gt;
&lt;br /&gt;
 sudo dnf install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin&lt;br /&gt;
&lt;br /&gt;
 sudo systemctl enable --now docker&lt;br /&gt;
&lt;br /&gt;
 sudo docker run hello-world&lt;br /&gt;
&lt;br /&gt;
== Docker Hub ==&lt;br /&gt;
&lt;br /&gt;
 Docker Hub&lt;br /&gt;
 https://hub.docker.com/&lt;br /&gt;
&lt;br /&gt;
=== Search Hub ===&lt;br /&gt;
&lt;br /&gt;
 docker search [image]&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
 docker search ubuntu&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Usage:  docker search [OPTIONS] TERM&lt;br /&gt;
&lt;br /&gt;
Search Docker Hub for images&lt;br /&gt;
&lt;br /&gt;
Options:&lt;br /&gt;
  -f, --filter filter   Filter output based on conditions provided&lt;br /&gt;
      --format string   Pretty-print search using a Go template&lt;br /&gt;
      --limit int       Max number of search results&lt;br /&gt;
      --no-trunc        Don&#039;t truncate output&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Search Tags and Images ===&lt;br /&gt;
&lt;br /&gt;
==== docker-browse ====&lt;br /&gt;
&lt;br /&gt;
Show all images in registry&lt;br /&gt;
 docker-browse --registry [registry] images&lt;br /&gt;
&lt;br /&gt;
Show all tags of image:&lt;br /&gt;
 docker-browse --registry [registry] tags [image]&lt;br /&gt;
&lt;br /&gt;
Registry being that from ~/.docker/config.json&lt;br /&gt;
&lt;br /&gt;
Can change default registry with &amp;quot;save&amp;quot; to ~/.docker-browse.json&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ docker-browse save --registry myregistry.example.com:5000 --protocol https&lt;br /&gt;
&lt;br /&gt;
$ cat ~/.docker-browse.json&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;defRegistry&amp;quot;: &amp;quot;myregistry.example.com:5000&amp;quot;,&lt;br /&gt;
    &amp;quot;defProtocol&amp;quot;: &amp;quot;https&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Install with:&lt;br /&gt;
 # global&lt;br /&gt;
 sudo npm install -g docker-browse&lt;br /&gt;
&lt;br /&gt;
 # local:&lt;br /&gt;
 cd ~&lt;br /&gt;
 mkdir -p ~/.npm&lt;br /&gt;
 cd ~/.npm&lt;br /&gt;
 npm install --prefix `pwd` docker-browse&lt;br /&gt;
 cd ~/.bin&lt;br /&gt;
 ln -sfn ~/.npm/node_modules/docker-browse/bin/docker-browse.js ~/.local/bin/docker-browse&lt;br /&gt;
&lt;br /&gt;
Or local with:&lt;br /&gt;
 mkdir ~/.src/docker-browse&lt;br /&gt;
 cd ~/.src/docker-browse&lt;br /&gt;
 # npm install docker-browse  # umm did this ever work?&lt;br /&gt;
 npm install --prefix `pwd` docker-browse&lt;br /&gt;
 # cd ~/.bin&lt;br /&gt;
 cd ~/.local/bin&lt;br /&gt;
 # ln -s ../.src/docker-browse/node_modules/.bin/docker-browse  # umm did this change names?&lt;br /&gt;
 ln -s ../.src/docker-browse/node_modules/bin/docker-browse.js docker-browse&lt;br /&gt;
&lt;br /&gt;
Assuming ~/.local/bin or .bin is in your path&lt;br /&gt;
&lt;br /&gt;
ref: https://www.npmjs.com/package/docker-browse&lt;br /&gt;
&lt;br /&gt;
==== skopeo ====&lt;br /&gt;
&lt;br /&gt;
Install skopeo with apt:&lt;br /&gt;
 sudo apt install skopeo&lt;br /&gt;
&lt;br /&gt;
Login:&lt;br /&gt;
 skopeo login docker://[repo:port]&lt;br /&gt;
&lt;br /&gt;
Logout:&lt;br /&gt;
 skopeo login docker://[repo:port]&lt;br /&gt;
&lt;br /&gt;
List tags in registry:&lt;br /&gt;
 skopeo list-tags docker://[repo:port]/[image]/[tag]&lt;br /&gt;
&lt;br /&gt;
Inspect image:&lt;br /&gt;
 skopeo delete docker://[repo:port]/[image]/[tag]&lt;br /&gt;
&lt;br /&gt;
Copy image in registry:&lt;br /&gt;
 skopeo copy docker://[repo:port]/[image]/[tag]  docker://[repo:port]/[new_image]/[new_tag]&lt;br /&gt;
&lt;br /&gt;
Delete image in registry: (( WARNING - THIS DELETES THE IMAGE, NOT JUST THE TAG ))&lt;br /&gt;
 skopeo delete docker://[repo:port]/[image]/[tag]&lt;br /&gt;
&lt;br /&gt;
== What Is Docker ==&lt;br /&gt;
&lt;br /&gt;
Package your application into a standardized unit for software development&lt;br /&gt;
&lt;br /&gt;
:&amp;quot;Docker containers wrap a piece of software in a complete filesystem that contains everything needed to run: code, runtime, system tools, system libraries – anything that can be installed on a server. This guarantees that the software will always run the same, regardless of its environment.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
https://www.docker.com/what-docker&lt;br /&gt;
&lt;br /&gt;
--&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Docker is an open-source project that automates the deployment of applications inside software containers.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Docker provides an additional layer of abstraction and automation of operating-system-level virtualization on Linux. Docker uses the resource isolation features of the Linux kernel such as cgroups and kernel namespaces, and a union-capable file system such as OverlayFS and others to allow independent &amp;quot;containers&amp;quot; to run within a single Linux instance, avoiding the overhead of starting and maintaining virtual machines.&lt;br /&gt;
&lt;br /&gt;
The Linux kernel&#039;s support for namespaces mostly isolates an application&#039;s view of the operating environment, including process trees, network, user IDs and mounted file systems, while the kernel&#039;s cgroups provide resource limiting, including the CPU, memory, block I/O and network. Since version 0.9, Docker includes the libcontainer library as its own way to directly use virtualization facilities provided by the Linux kernel, in addition to using abstracted virtualization interfaces via libvirt, LXC (Linux Containers) and systemd-nspawn.&lt;br /&gt;
&lt;br /&gt;
As actions are done to a Docker base image, union file system layers are created and documented, such that each layer fully describes how to recreate an action. This strategy enables Docker&#039;s lightweight images, as only layer updates need to be propagated (compared to full VMs, for example).&lt;br /&gt;
&lt;br /&gt;
https://en.wikipedia.org/wiki/Docker_(software)&lt;br /&gt;
&lt;br /&gt;
== Removing all containers and images ==&lt;br /&gt;
&lt;br /&gt;
 #  Stop the container(s) using the following command:&lt;br /&gt;
 docker-compose down&lt;br /&gt;
 #  Delete all containers using the following command:&lt;br /&gt;
 docker rm -f $(docker ps -a -q)&lt;br /&gt;
 #  Delete all volumes using the following command:&lt;br /&gt;
 docker volume rm $(docker volume ls -q)&lt;br /&gt;
 #  Prune system images, included stopped:&lt;br /&gt;
 docker system prune -a&lt;br /&gt;
&lt;br /&gt;
Ref [https://docs.tibco.com/pub/mash-local/4.1.1/doc/html/docker/GUID-BD850566-5B79-4915-987E-430FC38DAAE4.html] [https://www.digitalocean.com/community/tutorials/how-to-remove-docker-images-containers-and-volumes]&lt;br /&gt;
&lt;br /&gt;
== A Docker Tutorial for Beginners ==&lt;br /&gt;
&lt;br /&gt;
A Docker Tutorial for Beginners&amp;lt;br&amp;gt;&lt;br /&gt;
https://docker-curriculum.com/&lt;br /&gt;
&lt;br /&gt;
Once you are done installing Docker, test your Docker installation by running the following:&lt;br /&gt;
 # docker run hello-world&lt;br /&gt;
&lt;br /&gt;
hello-world container: https://hub.docker.com/_/hello-world&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
root@server:~# docker run hello-world&lt;br /&gt;
Unable to find image &#039;hello-world:latest&#039; locally&lt;br /&gt;
latest: Pulling from library/hello-world&lt;br /&gt;
b8dfde127a29: Pull complete&lt;br /&gt;
Digest: sha256:9f6ad537c5132bcce57f7a0a20e317228d382c3cd61edae14650eec68b2b345c&lt;br /&gt;
Status: Downloaded newer image for hello-world:latest&lt;br /&gt;
&lt;br /&gt;
Hello from Docker!&lt;br /&gt;
This message shows that your installation appears to be working correctly.&lt;br /&gt;
&lt;br /&gt;
To generate this message, Docker took the following steps:&lt;br /&gt;
 1. The Docker client contacted the Docker daemon.&lt;br /&gt;
 2. The Docker daemon pulled the &amp;quot;hello-world&amp;quot; image from the Docker Hub.&lt;br /&gt;
    (amd64)&lt;br /&gt;
 3. The Docker daemon created a new container from that image which runs the&lt;br /&gt;
    executable that produces the output you are currently reading.&lt;br /&gt;
 4. The Docker daemon streamed that output to the Docker client, which sent it&lt;br /&gt;
    to your terminal.&lt;br /&gt;
&lt;br /&gt;
To try something more ambitious, you can run an Ubuntu container with:&lt;br /&gt;
 $ docker run -it ubuntu bash&lt;br /&gt;
&lt;br /&gt;
Share images, automate workflows, and more with a free Docker ID:&lt;br /&gt;
 https://hub.docker.com/&lt;br /&gt;
&lt;br /&gt;
For more examples and ideas, visit:&lt;br /&gt;
 https://docs.docker.com/get-started/&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example of Ubuntu container:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
root@mserver:~# docker run -it ubuntu bash&lt;br /&gt;
Unable to find image &#039;ubuntu:latest&#039; locally&lt;br /&gt;
latest: Pulling from library/ubuntu&lt;br /&gt;
c549ccf8d472: Pull complete&lt;br /&gt;
Digest: sha256:aba80b77e27148d99c034a987e7da3a287ed455390352663418c0f2ed40417fe&lt;br /&gt;
Status: Downloaded newer image for ubuntu:latest&lt;br /&gt;
root@4d827b59d198:/#&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Try Busybox container:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
## Fetch container&lt;br /&gt;
docker pull busybox&lt;br /&gt;
&lt;br /&gt;
## List containers&lt;br /&gt;
docker images&lt;br /&gt;
&lt;br /&gt;
## Run container (did nothing then exited)&lt;br /&gt;
docker run busybox&lt;br /&gt;
&lt;br /&gt;
## Run container with instructions to do something&lt;br /&gt;
docker run busybox echo &amp;quot;hello from busybox&amp;quot;&lt;br /&gt;
    hello from busybox&lt;br /&gt;
&lt;br /&gt;
## List running docker containers:&lt;br /&gt;
docker ps&lt;br /&gt;
    CONTAINER ID   IMAGE             COMMAND                  CREATED        STATUS       PORTS         NAMES&lt;br /&gt;
&lt;br /&gt;
## List all dockers containers that we have run:&lt;br /&gt;
docker ps -a&lt;br /&gt;
&lt;br /&gt;
## Run in interactive mode:&lt;br /&gt;
docker run -it busybox sh&lt;br /&gt;
&lt;br /&gt;
## Run and auto delete on exit&lt;br /&gt;
docker run --rm busybox echo &amp;quot;hello&amp;quot;&lt;br /&gt;
&lt;br /&gt;
## Remove docker containers (clean up after yourself&lt;br /&gt;
docker rm [CONTAINER_ID  CONTAINER_ID  ...]&lt;br /&gt;
&lt;br /&gt;
## Remove all exited docker containers:&lt;br /&gt;
docker rm $(docker ps -a -q -f status=exited)&lt;br /&gt;
# or in later editions&lt;br /&gt;
docker container prune&lt;br /&gt;
&lt;br /&gt;
## Remove docker images:&lt;br /&gt;
docker rmi [IMAGE_ID  IMAGE_ID ...]&lt;br /&gt;
&lt;br /&gt;
## Run a detached instance, and name it&lt;br /&gt;
docker run -d --name [NAME] [IMAGE]&lt;br /&gt;
# example:  docker run -d --rm --name u3 -it ubuntu bash&lt;br /&gt;
&lt;br /&gt;
## Attach to running container: [https://docs.docker.com/engine/reference/commandline/attach/]&lt;br /&gt;
docker attach [NAME]&lt;br /&gt;
&lt;br /&gt;
## Detach from a running container: [https://docs.docker.com/engine/reference/commandline/attach/]&lt;br /&gt;
CTRL-p CTRL-q&lt;br /&gt;
&lt;br /&gt;
## Stop detached instance&lt;br /&gt;
docker stop [NAME]&lt;br /&gt;
&lt;br /&gt;
## Pull a specific version:&lt;br /&gt;
docker pull ubuntu:latest&lt;br /&gt;
docker pull ubuntu:18.04&lt;br /&gt;
docker pull ubuntu:16.04&lt;br /&gt;
&lt;br /&gt;
## Run specific version&lt;br /&gt;
docker run ubuntu:16.04&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
root@server:~# docker pull busybox&lt;br /&gt;
Using default tag: latest&lt;br /&gt;
latest: Pulling from library/busybox&lt;br /&gt;
b71f96345d44: Pull complete&lt;br /&gt;
Digest: sha256:930490f97e5b921535c153e0e7110d251134cc4b72bbb8133c6a5065cc68580d&lt;br /&gt;
Status: Downloaded newer image for busybox:latest&lt;br /&gt;
docker.io/library/busybox:latest&lt;br /&gt;
&lt;br /&gt;
root@server:~# docker images&lt;br /&gt;
REPOSITORY             TAG            IMAGE ID       CREATED         SIZE&lt;br /&gt;
ubuntu                 latest         9873176a8ff5   13 days ago     72.7MB&lt;br /&gt;
busybox                latest         69593048aa3a   3 weeks ago     1.24MB&lt;br /&gt;
hello-world            latest         d1165f221234   3 months ago    13.3kB&lt;br /&gt;
&lt;br /&gt;
root@server:~# docker ps -a&lt;br /&gt;
CONTAINER ID   IMAGE                            COMMAND                  CREATED         STATUS                     PORTS                         NAMES&lt;br /&gt;
495cf502dde2   busybox                          &amp;quot;echo &#039;hello from bu…&amp;quot;   2 minutes ago   Exited (0) 2 minutes ago    &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Create Image ===&lt;br /&gt;
&lt;br /&gt;
All user images are based on a base image.&lt;br /&gt;
&lt;br /&gt;
Login to Docker Hub:&lt;br /&gt;
 docker login&lt;br /&gt;
&lt;br /&gt;
Sample Dockerfile:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FROM python:3&lt;br /&gt;
&lt;br /&gt;
# set a directory for the app&lt;br /&gt;
WORKDIR /usr/src/app&lt;br /&gt;
&lt;br /&gt;
# copy all the files to the container&lt;br /&gt;
COPY . .&lt;br /&gt;
&lt;br /&gt;
# install dependencies&lt;br /&gt;
RUN pip install --no-cache-dir -r requirements.txt&lt;br /&gt;
&lt;br /&gt;
# define the port number the container should expose&lt;br /&gt;
EXPOSE 5000&lt;br /&gt;
&lt;br /&gt;
# run the command&lt;br /&gt;
CMD [&amp;quot;python&amp;quot;, &amp;quot;./app.py&amp;quot;]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Simple Dockerfile:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FROM ubuntu&lt;br /&gt;
&lt;br /&gt;
RUN touch test.txt&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Build image:&lt;br /&gt;
 docker build -t [username]/[project] .&lt;br /&gt;
&lt;br /&gt;
Test imagE:&lt;br /&gt;
 docker run [username]/[project]&amp;lt;:version&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Push image to Docker Hub:&lt;br /&gt;
 docker push [username]/[project]&lt;br /&gt;
&lt;br /&gt;
See parent hash of image:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
docker history --format &#039;{{ .ID }}&#039; --no-trunc [USERNAME]/[PROJECT]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Pull Image ==&lt;br /&gt;
&lt;br /&gt;
 docker pull &lt;br /&gt;
&lt;br /&gt;
Hash specific: [https://docs.docker.com/engine/reference/commandline/pull/]&lt;br /&gt;
 docker pull ubuntu@sha256:26c68657ccce2cb0a31b330cb0be2b5e108d467f641c62e13ab40cbec258c68d&lt;br /&gt;
&lt;br /&gt;
Hash specific in Dockerfile: [https://docs.docker.com/engine/reference/commandline/pull/]&lt;br /&gt;
 FROM ubuntu@sha256:26c68657ccce2cb0a31b330cb0be2b5e108d467f641c62e13ab40cbec258c68d&lt;br /&gt;
&lt;br /&gt;
== Run Image ==&lt;br /&gt;
&lt;br /&gt;
 docker run -it --rm [image:tag] /bin/bash&lt;br /&gt;
&lt;br /&gt;
If you want to force a specific entry point:&lt;br /&gt;
 docker run -it --rm --entrypoint /bin/sh [image:tag]&lt;br /&gt;
&lt;br /&gt;
== Attach to Running Docker ==&lt;br /&gt;
&lt;br /&gt;
 docker attach [NAME]&lt;br /&gt;
&lt;br /&gt;
If it isn&#039;t running bash, you can do something like this:&lt;br /&gt;
 docker exec -it [NAME] /bin/bash&lt;br /&gt;
&lt;br /&gt;
== Run Docker Ubuntu Mounted to Current Directory ==&lt;br /&gt;
&lt;br /&gt;
 docker run --rm -it -v .:/mnt ubuntu bash&lt;br /&gt;
&lt;br /&gt;
== Running ARM on x86 ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Problem:&#039;&#039;&#039;&lt;br /&gt;
 uname -m # Display the host architecture&lt;br /&gt;
 #x86_64&lt;br /&gt;
&lt;br /&gt;
 docker run --rm -t arm64v8/ubuntu uname -m # Run an executable made for aarch64 on x86_64&lt;br /&gt;
 #standard_init_linux.go:211: exec user process caused &amp;quot;exec format error&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Solution:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
As expected the instructions are not recognized since the packages are not installed yet. Installing the following packages should allow you to enable support for aarch64 containers on your x86 workstation:&lt;br /&gt;
&lt;br /&gt;
 sudo apt-get install qemu binfmt-support qemu-user-static # Install the qemu packages&lt;br /&gt;
 docker run --rm --privileged multiarch/qemu-user-static --reset -p yes # This step will execute the registering scripts&lt;br /&gt;
&lt;br /&gt;
 docker run --rm -t arm64v8/ubuntu uname -m # Testing the emulation environment&lt;br /&gt;
 #aarch64&lt;br /&gt;
&lt;br /&gt;
ref: [https://www.stereolabs.com/docs/docker/building-arm-container-on-x86/]&lt;br /&gt;
&lt;br /&gt;
== Static MAC ==&lt;br /&gt;
&lt;br /&gt;
 docker run ... --mac-address 12:34:56:78:9a:bc&lt;br /&gt;
&lt;br /&gt;
ref: [https://docs.docker.com/engine/reference/run/#:~:text=By%20default%2C%20the%20MAC%20address,specified%20MAC%20addresses%20are%20unique.]&lt;br /&gt;
&lt;br /&gt;
== Exporting ==&lt;br /&gt;
&lt;br /&gt;
=== Save and Load Image ===&lt;br /&gt;
&lt;br /&gt;
 docker save -o [image.tar] [IMAGE]&lt;br /&gt;
 # or&lt;br /&gt;
 docker save [IMAGE] &amp;gt; [image.tar]&lt;br /&gt;
&lt;br /&gt;
 docker load -i [image.tar]&lt;br /&gt;
 # or&lt;br /&gt;
 cat [image.tar] | docker load&lt;br /&gt;
&lt;br /&gt;
=== Export and Import Container ===&lt;br /&gt;
&lt;br /&gt;
 docker export [CONTAINER_ID_OR_NAME] &amp;gt; [container.tar]&lt;br /&gt;
&lt;br /&gt;
 docker import [container.tar] [IMAGE_NAME:VER]&lt;br /&gt;
 # or&lt;br /&gt;
 cat [container.tar] | docker import - [IMAGE_NAME:VER]&lt;br /&gt;
&lt;br /&gt;
== Extract Build Steps ==&lt;br /&gt;
&lt;br /&gt;
Don&#039;t truncate the lines - gives you the FULL command line:&lt;br /&gt;
 docker history [IMAGE_ID] --no-trunc | tac&lt;br /&gt;
&lt;br /&gt;
Show only the docker step - full command line, no other details (.CreatedBy is the command that created the layer, not the author)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
docker history [IMAGE_ID] --format &#039;{{.CreatedBy}}&#039; --no-trunc | tac&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Show only the docker step - Don&#039;t truncate the lines and wrap lines at &amp;amp;&amp;amp; - really nice view&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
docker history --no-trunc [IMAGE_ID] | tac | tr -s &#039; &#039; | cut -d &amp;quot; &amp;quot; -f 5- | sed &#039;s,^/bin/sh -c #(nop) ,,g&#039; | sed &#039;s,^/bin/sh -c,RUN,g&#039; | sed &#039;s, &amp;amp;&amp;amp; ,\n  &amp;amp; ,g&#039; | sed &#039;s,\s*[0-9]*[\.]*[0-9]*\s*[kMG]*B\s*$,,g&#039; | head -n -1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ref: &amp;lt;ref&amp;gt;https://stackoverflow.com/questions/19104847/how-to-generate-a-dockerfile-from-an-image&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See parent hash of image:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
docker history --format &#039;{{ .ID }}&#039; --no-trunc [IMAGE_ID]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Docker Compose ==&lt;br /&gt;
&lt;br /&gt;
 apt install docker-compose docker-compose-plugin&lt;br /&gt;
 # docker-compose provides &amp;quot;docker-compose&amp;quot; command&lt;br /&gt;
 # docker-compose-plugin provides &amp;quot;docker compose&amp;quot; command&lt;br /&gt;
&lt;br /&gt;
 docker compose up -d&lt;br /&gt;
&lt;br /&gt;
Sample docker-compose.yml:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
version: &amp;quot;3.0&amp;quot;  # compose API version&lt;br /&gt;
services:&lt;br /&gt;
  license-service:&lt;br /&gt;
    container_name: license&lt;br /&gt;
    # Docker image name&lt;br /&gt;
    image: flexlm:v1&lt;br /&gt;
    build:&lt;br /&gt;
      context: .&lt;br /&gt;
    user: root&lt;br /&gt;
    restart: always&lt;br /&gt;
    # mac address tied to license file&lt;br /&gt;
    mac_address: xx:xx:xx:xx:xx:xx&lt;br /&gt;
    ports:&lt;br /&gt;
      # 27000 for lmgrd&lt;br /&gt;
      - 27000:27000&lt;br /&gt;
      # 27001 for armlmd&lt;br /&gt;
      - 27001:27001&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Docker BuildX ==&lt;br /&gt;
&lt;br /&gt;
buildx:&lt;br /&gt;
 https://github.com/docker/buildx&lt;br /&gt;
&lt;br /&gt;
apt package:&lt;br /&gt;
 docker-buildx/jammy-updates,jammy-security 0.12.1-0ubuntu1~22.04.2 amd64&lt;br /&gt;
   Docker CLI plugin for extended build capabilities with BuildKit&lt;br /&gt;
&lt;br /&gt;
Install buildx with apt:&lt;br /&gt;
 sudo apt install docker-buildx&lt;br /&gt;
&lt;br /&gt;
Set buildx as default builder:&lt;br /&gt;
 docker buildx install&lt;br /&gt;
&lt;br /&gt;
To remove buildx alias:&lt;br /&gt;
 docker buildx uninstall&lt;br /&gt;
&lt;br /&gt;
You can build multi-platform images using three different strategies that are supported by Buildx and Dockerfiles:&lt;br /&gt;
# Using the QEMU emulation support in the kernel&lt;br /&gt;
# Building on multiple native nodes using the same builder instance&lt;br /&gt;
# Using a stage in Dockerfile to cross-compile to different architectures&lt;br /&gt;
&lt;br /&gt;
If not using Docker Desktop:&lt;br /&gt;
 docker run --privileged --rm tonistiigi/binfmt --install all&lt;br /&gt;
&lt;br /&gt;
Add additional platforms:&lt;br /&gt;
 docker buildx create --use --name mybuild node-amd64&lt;br /&gt;
 docker buildx create --append --name mybuild node-arm64&lt;br /&gt;
 docker buildx build --platform linux/amd64,linux/arm64 .&lt;br /&gt;
&lt;br /&gt;
== Proxy ==&lt;br /&gt;
&lt;br /&gt;
Client:&lt;br /&gt;
 ~/.docker/config.json&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
 &amp;quot;proxies&amp;quot;: {&lt;br /&gt;
   &amp;quot;default&amp;quot;: {&lt;br /&gt;
     &amp;quot;httpProxy&amp;quot;: &amp;quot;http://proxy.example.com:3128&amp;quot;,&lt;br /&gt;
     &amp;quot;httpsProxy&amp;quot;: &amp;quot;https://proxy.example.com:3129&amp;quot;,&lt;br /&gt;
     &amp;quot;noProxy&amp;quot;: &amp;quot;*.test.example.com,.example.org,127.0.0.0/8&amp;quot;&lt;br /&gt;
   }&lt;br /&gt;
 }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ref: Configure Docker to use a proxy server | Docker Documentation - https://docs.docker.com/network/proxy/&lt;br /&gt;
&lt;br /&gt;
Configure Docker Service&lt;br /&gt;
&lt;br /&gt;
 systemctl edit docker.service&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[Service]&lt;br /&gt;
Environment=&amp;quot;HTTP_PROXY=http://proxy.example.com:3128&amp;quot;,&lt;br /&gt;
Environment=&amp;quot;HTTPS_PROXY=httpS://proxy.example.com:3129&amp;quot;,&lt;br /&gt;
Environment=&amp;quot;NO_PROXY=localhost,127.0.0.1&amp;quot;,&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 systemctl restart docker.service&lt;br /&gt;
&lt;br /&gt;
== Registry ==&lt;br /&gt;
&lt;br /&gt;
=== Registry API ===&lt;br /&gt;
&lt;br /&gt;
 HTTP API V2 | Docker Documentation&lt;br /&gt;
 https://docs.docker.com/registry/spec/api/&lt;br /&gt;
&lt;br /&gt;
List available images:&lt;br /&gt;
 GET /v2/_catalog&lt;br /&gt;
 GET https://registry.example.com/v2/_catalog&lt;br /&gt;
&lt;br /&gt;
Pretty print output:&lt;br /&gt;
 curl -s https://registry.example.com/v2/_catalog | jq&lt;br /&gt;
 curl -s https://registry.example.com/v2/_catalog | python3 -m json.tool&lt;br /&gt;
&lt;br /&gt;
Pagenation&lt;br /&gt;
 GET /v2/_catalog?n=&amp;lt;count&amp;gt;&lt;br /&gt;
 # using a name of repo in a previous result:&lt;br /&gt;
 GET /v2/_catalog?n=&amp;lt;count&amp;gt;&amp;amp;last=&amp;lt;name_repo_start_with&amp;gt;&lt;br /&gt;
&lt;br /&gt;
List tags: (pagination also works with tags)&lt;br /&gt;
 GET /v2/&amp;lt;image_name&amp;gt;/tags/list&lt;br /&gt;
&lt;br /&gt;
Delete image:&lt;br /&gt;
 # reference must be a digest or the delete will fail.&lt;br /&gt;
 DELETE /v2/&amp;lt;name&amp;gt;/manifests/&amp;lt;reference&amp;gt;&lt;br /&gt;
&lt;br /&gt;
API:&lt;br /&gt;
 Method	Path	Entity	Description&lt;br /&gt;
 GET	/v2/	Base	Check that the endpoint implements Docker Registry API V2.&lt;br /&gt;
 GET	/v2/&amp;lt;name&amp;gt;/tags/list	Tags	Fetch the tags under the repository identified by name.&lt;br /&gt;
 GET	/v2/&amp;lt;name&amp;gt;/manifests/&amp;lt;reference&amp;gt;	Manifest	Fetch the manifest identified by name and reference where reference can be a tag or digest. A HEAD request can also be issued to this endpoint to obtain resource information without receiving all data.&lt;br /&gt;
 PUT	/v2/&amp;lt;name&amp;gt;/manifests/&amp;lt;reference&amp;gt;	Manifest	Put the manifest identified by name and reference where reference can be a tag or digest.&lt;br /&gt;
 DELETE	/v2/&amp;lt;name&amp;gt;/manifests/&amp;lt;reference&amp;gt;	Manifest	Delete the manifest or tag identified by name and reference where reference can be a tag or digest. Note that a manifest can only be deleted by digest.&lt;br /&gt;
 GET	/v2/&amp;lt;name&amp;gt;/blobs/&amp;lt;digest&amp;gt;	Blob	Retrieve the blob from the registry identified by digest. A HEAD request can also be issued to this endpoint to obtain resource information without receiving all data.&lt;br /&gt;
 DELETE	/v2/&amp;lt;name&amp;gt;/blobs/&amp;lt;digest&amp;gt;	Blob	Delete the blob identified by name and digest&lt;br /&gt;
 POST	/v2/&amp;lt;name&amp;gt;/blobs/uploads/	Initiate Blob Upload	Initiate a resumable blob upload. If successful, an upload location will be provided to complete the upload. Optionally, if the digest parameter is present, the request body will be used to complete the upload in a single request.&lt;br /&gt;
 GET	/v2/&amp;lt;name&amp;gt;/blobs/uploads/&amp;lt;uuid&amp;gt;	Blob Upload	Retrieve status of upload identified by uuid. The primary purpose of this endpoint is to resolve the current status of a resumable upload.&lt;br /&gt;
 PATCH	/v2/&amp;lt;name&amp;gt;/blobs/uploads/&amp;lt;uuid&amp;gt;	Blob Upload	Upload a chunk of data for the specified upload.&lt;br /&gt;
 PUT	/v2/&amp;lt;name&amp;gt;/blobs/uploads/&amp;lt;uuid&amp;gt;	Blob Upload	Complete the upload specified by uuid, optionally appending the body as the final chunk.&lt;br /&gt;
 DELETE	/v2/&amp;lt;name&amp;gt;/blobs/uploads/&amp;lt;uuid&amp;gt;	Blob Upload	Cancel outstanding upload processes, releasing associated resources. If this is not called, the unfinished uploads will eventually timeout.&lt;br /&gt;
 GET	/v2/_catalog	Catalog	Retrieve a sorted, json list of repositories available in the registry.&lt;br /&gt;
&lt;br /&gt;
== Reducing Image Size ==&lt;br /&gt;
&lt;br /&gt;
1. Bundle Layers&lt;br /&gt;
&lt;br /&gt;
 RUN apt-get update -y \&lt;br /&gt;
   &amp;amp;&amp;amp; apt install -y package_one&lt;br /&gt;
&lt;br /&gt;
2. Avoid extra packages&lt;br /&gt;
&lt;br /&gt;
 apt install -y --no-install-recommends&lt;br /&gt;
&lt;br /&gt;
3. Clean up after install&lt;br /&gt;
&lt;br /&gt;
 apt ... \&lt;br /&gt;
 &amp;amp;&amp;amp; rm -rf /var/lib/apt/lists/*&lt;br /&gt;
&lt;br /&gt;
4. Pick smaller image&lt;br /&gt;
&lt;br /&gt;
 alpine vs ubuntu&lt;br /&gt;
&lt;br /&gt;
5. Use .dockerignore&lt;br /&gt;
&lt;br /&gt;
ref: [https://towardsdatascience.com/5-easy-to-implement-tricks-to-trim-down-your-docker-image-size-263978a6ed29]&lt;br /&gt;
&lt;br /&gt;
== Missing Docker Images Packages ==&lt;br /&gt;
&lt;br /&gt;
scp:&lt;br /&gt;
 apt update ; apt install openssh-clients&lt;br /&gt;
&lt;br /&gt;
== Issues ==&lt;br /&gt;
&lt;br /&gt;
=== apt getting stuck at configuring tzdata ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Configuring tzdata&lt;br /&gt;
------------------&lt;br /&gt;
&lt;br /&gt;
Please select the geographic area in which you live. Subsequent configuration&lt;br /&gt;
questions will narrow this down by presenting a list of cities, representing&lt;br /&gt;
the time zones in which they are located.&lt;br /&gt;
&lt;br /&gt;
  1. Africa      4. Australia  7. Atlantic  10. Pacific  13. Etc&lt;br /&gt;
  2. America     5. Arctic     8. Europe    11. SystemV&lt;br /&gt;
  3. Antarctica  6. Asia       9. Indian    12. US&lt;br /&gt;
Geographic area: &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Solution:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FROM ubuntu:20.04&lt;br /&gt;
&lt;br /&gt;
ENV TZ=Asia/Dubai&lt;br /&gt;
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime &amp;amp;&amp;amp; echo $TZ &amp;gt; /etc/timezone&lt;br /&gt;
&lt;br /&gt;
RUN apt update&lt;br /&gt;
RUN apt install -y tzdata&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ref: Fix: tzdata hangs during Docker image build - DEV Community - https://dev.to/grigorkh/fix-tzdata-hangs-during-docker-image-build-4o9m&lt;br /&gt;
&lt;br /&gt;
== Ubuntu Docker Install Basic Tools ==&lt;br /&gt;
&lt;br /&gt;
 apt update&lt;br /&gt;
 apt install sudo curl wget screen vim less&lt;br /&gt;
 apt install dmidecode iproute2 net-tools&lt;br /&gt;
&lt;br /&gt;
== keywords ==&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=Python&amp;diff=9872</id>
		<title>Python</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=Python&amp;diff=9872"/>
		<updated>2026-04-27T20:28:38Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: /* Variable Directory = */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{subtop}}&lt;br /&gt;
&lt;br /&gt;
== Python ==&lt;br /&gt;
&lt;br /&gt;
Python (programming language) - Wikipedia - http://en.wikipedia.org/wiki/Python_(programming_language)&lt;br /&gt;
: Python is an interpreted, general-purpose high-level programming language whose design philosophy emphasizes code readability. Python aims to combine &amp;quot;remarkable power with very clear syntax&amp;quot;, and its standard library is large and comprehensive. Its use of indentation for block delimiters is unique among popular programming languages.&lt;br /&gt;
: Python supports multiple programming paradigms, primarily but not limited to object-oriented, imperative and, to a lesser extent, functional programming styles. It features a fully dynamic type system and automatic memory management, similar to that of Scheme, Ruby, Perl, and Tcl. Like other dynamic languages, Python is often used as a scripting language, but is also used in a wide range of non-scripting contexts.&lt;br /&gt;
: The reference implementation of Python ([http://en.wikipedia.org/wiki/CPython CPython]) is free and open source software and has a community-based development model, as do all or nearly all of its alternative implementations. CPython is managed by the non-profit Python Software Foundation.&lt;br /&gt;
: Python interpreters are available for many operating systems, and Python programs can be packaged into stand-alone executable code for many systems using various tools.&lt;br /&gt;
&lt;br /&gt;
Author:&lt;br /&gt;
:&amp;quot;Python was conceived in the late 1980s and its implementation was started in December 1989 by &#039;&#039;&#039;[http://www.python.org/~guido/ Guido van Rossum]&#039;&#039;&#039; at CWI in the Netherlands as a successor to the ABC programming language (itself inspired by SETL) capable of exception handling and interfacing with the Amoeba operating system. Van Rossum is Python&#039;s principal author, and his continuing central role in deciding the direction of Python is reflected in the title given to him by the Python community, Benevolent Dictator for Life (BDFL).&amp;quot; [http://en.wikipedia.org/wiki/Python_(programming_language)]&lt;br /&gt;
&lt;br /&gt;
Name:&lt;br /&gt;
:&amp;quot;The language is named after the BBC show “Monty Python’s Flying Circus” and has nothing to do with reptiles. Making references to Monty Python skits in documentation is not only allowed, it is encouraged!&amp;quot; [http://docs.python.org/py3k/tutorial/appetite.html]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
We as people are &amp;quot;Pythonites&amp;quot; [http://raspi.tv/2013/how-to-use-interrupts-with-python-on-the-raspberry-pi-and-rpi-gpio-part-2]&lt;br /&gt;
&lt;br /&gt;
== [http://www.python.org/dev/peps/pep-0020/ The Zen of Python] ==&lt;br /&gt;
&lt;br /&gt;
&amp;quot;The core philosophy of the language is summarized by the document &#039;PEP 20 (The Zen of Python)&#039;&amp;quot; [http://en.wikipedia.org/wiki/Python_%28programming_language%29]&lt;br /&gt;
* PEP 20 -- The Zen of Python - http://www.python.org/dev/peps/pep-0020/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Abstract&lt;br /&gt;
&lt;br /&gt;
    Long time Pythoneer Tim Peters succinctly channels the BDFL&#039;s&lt;br /&gt;
    guiding principles for Python&#039;s design into 20 aphorisms, only 19&lt;br /&gt;
    of which have been written down.&lt;br /&gt;
&lt;br /&gt;
The Zen of Python&lt;br /&gt;
&lt;br /&gt;
    Beautiful is better than ugly.&lt;br /&gt;
    Explicit is better than implicit.&lt;br /&gt;
    Simple is better than complex.&lt;br /&gt;
    Complex is better than complicated.&lt;br /&gt;
    Flat is better than nested.&lt;br /&gt;
    Sparse is better than dense.&lt;br /&gt;
    Readability counts.&lt;br /&gt;
    Special cases aren&#039;t special enough to break the rules.&lt;br /&gt;
    Although practicality beats purity.&lt;br /&gt;
    Errors should never pass silently.&lt;br /&gt;
    Unless explicitly silenced.&lt;br /&gt;
    In the face of ambiguity, refuse the temptation to guess.&lt;br /&gt;
    There should be one-- and preferably only one --obvious way to do it.&lt;br /&gt;
    Although that way may not be obvious at first unless you&#039;re Dutch.&lt;br /&gt;
    Now is better than never.&lt;br /&gt;
    Although never is often better than *right* now.&lt;br /&gt;
    If the implementation is hard to explain, it&#039;s a bad idea.&lt;br /&gt;
    If the implementation is easy to explain, it may be a good idea.&lt;br /&gt;
    Namespaces are one honking great idea -- let&#039;s do more of those!&lt;br /&gt;
&lt;br /&gt;
Easter Egg&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import this&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Other Sources:&lt;br /&gt;
* http://www.python.org/doc/humor/&lt;br /&gt;
* The Zen of Python – as a Poster « CODE POETRY - http://codepoetry.wordpress.com/2010/03/23/the-zen-of-python-as-a-poster/&lt;br /&gt;
** Zen of Python (PDF) http://codepoetry.files.wordpress.com/2010/03/zen-of-python.pdf&lt;br /&gt;
&lt;br /&gt;
== Documentation ==&lt;br /&gt;
&lt;br /&gt;
* Overview — Python v2.7.1 documentation - http://docs.python.org/index.html&lt;br /&gt;
** Download — Python v2.7.1 documentation - http://docs.python.org/download.html&lt;br /&gt;
&lt;br /&gt;
* Overview — Python v3.2 documentation - http://docs.python.org/py3k/&lt;br /&gt;
**  Download — Python v3.2 documentation - http://docs.python.org/py3k/download.html&lt;br /&gt;
&lt;br /&gt;
* PEP 8 -- Style Guide for Python Code - http://www.python.org/dev/peps/pep-0008/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Tutorials ==&lt;br /&gt;
&lt;br /&gt;
* The Python Tutorial — Python v2.7.1 documentation - http://docs.python.org/tutorial/&lt;br /&gt;
&lt;br /&gt;
* Python 101 -- Introduction to Python - http://www.rexx.com/~dkuhlman/python_101/python_101.html&lt;br /&gt;
&lt;br /&gt;
* 4. More Control Flow Tools — Python v2.7.1 documentation - http://docs.python.org/tutorial/controlflow.html&lt;br /&gt;
&lt;br /&gt;
== Linux Installation ==&lt;br /&gt;
&lt;br /&gt;
RHEL Distribution installation:&lt;br /&gt;
 yum -y install python python-setuptools&lt;br /&gt;
&lt;br /&gt;
Ubuntu Distribution installation: [https://help.ubuntu.com/community/Mercurial]&lt;br /&gt;
 # enable &#039;universe&#039; in the sources.list&lt;br /&gt;
 # &amp;quot;Mercurial is included in the Universe repository - activate this repo first&amp;quot;&lt;br /&gt;
 sudo apt-get install mercurial&lt;br /&gt;
&lt;br /&gt;
CentOS 5 Option Recommended Dependencies:&lt;br /&gt;
 yum -y install gcc make sudo readline-devel openssl-devel ncurses-devel zlib-devel gdbm-devel sqlite-devel bzip2-devel tk-devel tcl-devel&lt;br /&gt;
&lt;br /&gt;
 # this leaves: 2.6.6: _bsddb, bsddb185, dl, imageop, sunaudiodev&lt;br /&gt;
 # this leaves: 2.7.1: _bsddb, bsddb185, dl, imageop, sunaudiodev&lt;br /&gt;
 # this leaves: 3.2: none&lt;br /&gt;
&lt;br /&gt;
CentOS 9 Option Recommended Dependencies:&lt;br /&gt;
 # gdbm-devel not found in centos9?&lt;br /&gt;
 yum -y install gcc make sudo readline-devel openssl-devel ncurses-devel zlib-devel sqlite-devel bzip2-devel tk-devel tcl-devel&lt;br /&gt;
&lt;br /&gt;
Ubuntu 12.04 LTS 64bit dependencies:&lt;br /&gt;
 apt-get install gcc make sudo lib64bz2-dev tcl-dev lib64ncurses5-dev libssl-dev libreadline-dev tk-dev libsqlite3-dev libgdbm-dev&lt;br /&gt;
&lt;br /&gt;
 # maybe: lib64readline-dev libsqlite3-dev tk-dev&lt;br /&gt;
&lt;br /&gt;
 # this leaves: 2.7: _bsddb, bsddb185, dl, imageop, sunaudiodev&lt;br /&gt;
&lt;br /&gt;
=== 2.x ===&lt;br /&gt;
&lt;br /&gt;
CentOS dependencies:&lt;br /&gt;
 sudo yum -y install gcc make sudo readline-devel openssl-devel ncurses-devel zlib-devel gdbm-devel sqlite-devel bzip2-devel tk-devel tcl-devel&lt;br /&gt;
&lt;br /&gt;
Ubuntu 12.04 LTS 64bit dependencies:&lt;br /&gt;
 sudo apt-get update&lt;br /&gt;
 sudo apt-get install gcc make sudo lib64bz2-dev tcl-dev lib64ncurses5-dev libssl-dev libreadline-dev tk-dev libsqlite3-dev libgdbm-dev&lt;br /&gt;
&lt;br /&gt;
Ubuntu 24.04 LTS 64bit dependencies:&lt;br /&gt;
 sudo apt-get update&lt;br /&gt;
 sudo apt-get install gcc make sudo libbz2-dev tcl-dev libncurses-dev libssl-dev libreadline-dev tk-dev libsqlite3-dev libgdbm-dev libffi-dev&lt;br /&gt;
 # optional install&lt;br /&gt;
 sudo apt-get install checkinstall&lt;br /&gt;
&lt;br /&gt;
2.7.15:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#  PYVER=2.6.6&lt;br /&gt;
#  PYVER=2.7.5&lt;br /&gt;
#  PYVER=2.7.6&lt;br /&gt;
#  PYVER=2.7.9&lt;br /&gt;
#  PYVER=2.7.10&lt;br /&gt;
#  PYVER=2.7.15&lt;br /&gt;
PYVER=2.7.18&lt;br /&gt;
mkdir -p ~/.src ; cd ~/.src&lt;br /&gt;
wget --no-check-certificate http://www.python.org/ftp/python/$PYVER/Python-$PYVER.tgz&lt;br /&gt;
tar -zvxf Python-$PYVER.tgz&lt;br /&gt;
cd Python-$PYVER&lt;br /&gt;
#  ./configure --prefix=/opt/python-$PYVER&lt;br /&gt;
#  make clean &amp;amp;&amp;amp; make&lt;br /&gt;
./configure --prefix=/opt/python-$PYVER &amp;amp;&amp;amp; make clean &amp;amp;&amp;amp; make&lt;br /&gt;
sudo make install&lt;br /&gt;
&lt;br /&gt;
sudo /opt/python-$PYVER/bin/python -m ensurepip --upgrade&lt;br /&gt;
sudo /opt/python-$PYVER/bin/pip install --upgrade pip&lt;br /&gt;
sudo /opt/python-$PYVER/bin/pip install requests&lt;br /&gt;
&lt;br /&gt;
export PATH=/opt/python-$PYVER/bin:$PATH&lt;br /&gt;
echo -e &amp;quot;\n\nexport PATH=/opt/python-$PYVER/bin:\$PATH\n&amp;quot; &amp;gt;&amp;gt; ~/.bash_profile&lt;br /&gt;
#  echo -e &amp;quot;\n\nexport PATH=/opt/python27/bin:\$PATH\n&amp;quot; &amp;gt;&amp;gt; ~/.bashrc&lt;br /&gt;
&lt;br /&gt;
#  NOTE: remove any old versions from your .bash_profile&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Bootstrapping the pip installer - https://docs.python.org/2/library/ensurepip.html&lt;br /&gt;
&lt;br /&gt;
=== 3.x ===&lt;br /&gt;
&lt;br /&gt;
3.8.16:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#VER=3.7.0&lt;br /&gt;
#VER=3.8.15&lt;br /&gt;
#VER=3.10.9&lt;br /&gt;
VER=3.8.16&lt;br /&gt;
mkdir -p ~/.src ; cd ~/.src&lt;br /&gt;
wget http://www.python.org/ftp/python/${VER}/Python-${VER}.tgz&lt;br /&gt;
tar -zvxf Python-${VER}.tgz&lt;br /&gt;
cd Python-${VER}&lt;br /&gt;
./configure --prefix=/opt/python${VER}&lt;br /&gt;
make&lt;br /&gt;
&lt;br /&gt;
sudo make install&lt;br /&gt;
&lt;br /&gt;
## OPTIONAL alternative install path:&lt;br /&gt;
sudo checkinstall&lt;br /&gt;
## note: &#039;checkinstall&#039; makes a .deb, which you can uninstall with easier, but if you are using --prefix, you do need to&lt;br /&gt;
##       premake the folders&lt;br /&gt;
sudo mkdir -p /opt/python${VER}/bin&lt;br /&gt;
sudo mkdir -p /opt/python${VER}/lib&lt;br /&gt;
shortVER=`echo $VER | cut -d &#039;.&#039; -f 1-2`  # get short version eg. 3.10 from 3.10.9&lt;br /&gt;
sudo mkdir -p /opt/python${VER}/lib/python${shortVER}&lt;br /&gt;
sudo mkdir -p /opt/python${VER}/lib/python${shortVER}/test&lt;br /&gt;
# sudo checkinstall    # hit Y, and enter twice&lt;br /&gt;
## note: older versions have problems with the virtualization of the file system, so do FS Translation = no&lt;br /&gt;
checkinstall --fstrans=no&lt;br /&gt;
&lt;br /&gt;
export PATH=/opt/python${VER}/bin:$PATH&lt;br /&gt;
echo -e &amp;quot;\n\nexport PATH=/opt/python${VER}/bin:\$PATH\n&amp;quot; &amp;gt;&amp;gt; ~/.bash_profile&lt;br /&gt;
&lt;br /&gt;
# have to manually update version&lt;br /&gt;
rm /opt/python${VER}/bin/python&lt;br /&gt;
ln -sfn python3.8 /opt/python${VER}/bin/python&lt;br /&gt;
#cp /opt/python${VER}/bin/python3.8 /opt/python${VER}/bin/python&lt;br /&gt;
&lt;br /&gt;
# DEPENDENCIES&lt;br /&gt;
sudo apt install ...&lt;br /&gt;
yum install libffi-devel openssl-devel&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note, if you want the libraries to be shared (like python-dev):&lt;br /&gt;
 ./configure --enable-shared&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
 VER=3.6.9&lt;br /&gt;
&lt;br /&gt;
 VER=3.6.8&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
3.2.0:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir -p ~/src ; cd ~/src&lt;br /&gt;
wget http://www.python.org/ftp/python/3.2/Python-3.2.tgz&lt;br /&gt;
tar -zvxf Python-3.2.tgz&lt;br /&gt;
cd Python-3.2&lt;br /&gt;
./configure --prefix=/opt/python32&lt;br /&gt;
make&lt;br /&gt;
sudo make install&lt;br /&gt;
&lt;br /&gt;
export PATH=/opt/python32/bin:$PATH&lt;br /&gt;
echo -e &amp;quot;\n\nexport PATH=/opt/python32/bin:\$PATH\n&amp;quot; &amp;gt;&amp;gt; ~/.bash_profile&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3.3.0:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir -p ~/src ; cd ~/src&lt;br /&gt;
wget http://www.python.org/ftp/python/3.3.0/Python-3.3.0.tgz&lt;br /&gt;
tar -zvxf Python-3.3.0.tgz&lt;br /&gt;
cd Python-3.3.0&lt;br /&gt;
./configure --prefix=/opt/python3.3.0&lt;br /&gt;
make&lt;br /&gt;
sudo make install&lt;br /&gt;
&lt;br /&gt;
export PATH=/opt/python3.3.0/bin:$PATH&lt;br /&gt;
echo -e &amp;quot;\n\nexport PATH=/opt/python3.3.0/bin:\$PATH\n&amp;quot; &amp;gt;&amp;gt; ~/.bash_profile&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3.3.4:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir -p ~/.src ; cd ~/.src&lt;br /&gt;
wget http://www.python.org/ftp/python/3.3.4/Python-3.3.4.tgz&lt;br /&gt;
tar -zvxf Python-3.3.4.tgz&lt;br /&gt;
cd Python-3.3.4&lt;br /&gt;
./configure --prefix=/opt/python3.3.4&lt;br /&gt;
make clean&lt;br /&gt;
make&lt;br /&gt;
sudo make install&lt;br /&gt;
&lt;br /&gt;
export PATH=/opt/python3.3.4/bin:$PATH&lt;br /&gt;
echo -e &amp;quot;\n\nexport PATH=/opt/python3.3.4/bin:\$PATH\n&amp;quot; &amp;gt;&amp;gt; ~/.bash_profile&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3.4.0:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir -p ~/.src ; cd ~/.src&lt;br /&gt;
wget http://www.python.org/ftp/python/3.4.0/Python-3.4.0.tgz&lt;br /&gt;
tar -zvxf Python-3.4.0.tgz&lt;br /&gt;
cd Python-3.4.0&lt;br /&gt;
./configure --prefix=/opt/python3.4.0&lt;br /&gt;
make&lt;br /&gt;
sudo make install&lt;br /&gt;
&lt;br /&gt;
export PATH=/opt/python3.4.0/bin:$PATH&lt;br /&gt;
echo -e &amp;quot;\n\nexport PATH=/opt/python3.4.0/bin:\$PATH\n&amp;quot; &amp;gt;&amp;gt; ~/.bash_profile&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== setuptools ===&lt;br /&gt;
&lt;br /&gt;
Purpose: to install pip&lt;br /&gt;
&lt;br /&gt;
Note: required for several &#039;python setup.py install&#039; installations.&lt;br /&gt;
&lt;br /&gt;
Python Package Index : setuptools 0.6c11 - http://pypi.python.org/pypi/setuptools&lt;br /&gt;
&lt;br /&gt;
By Package Manager:&lt;br /&gt;
 yum install python-setuptools&lt;br /&gt;
&lt;br /&gt;
By Source:&lt;br /&gt;
 #VER=2.0.1&lt;br /&gt;
 #VER=2.2&lt;br /&gt;
 VER=3.4.4&lt;br /&gt;
 mkdir -p ~/.src ; cd ~/.src&lt;br /&gt;
 wget --no-check-certificate http://pypi.python.org/packages/source/s/setuptools/setuptools-$VER.tar.gz&lt;br /&gt;
 tar -zvxf setuptools-$VER.tar.gz&lt;br /&gt;
 cd setuptools-$VER&lt;br /&gt;
 # sudo python setup.py install&lt;br /&gt;
 sudo /opt/python-2.7.9/bin/python setup.py install&lt;br /&gt;
&lt;br /&gt;
Fix header:&lt;br /&gt;
 # Only needed on older versions&lt;br /&gt;
 sed -i &#039;s#!/usr/bin/python#!/usr/bin/env python#g&#039; /opt/python279/bin/easy_install&lt;br /&gt;
&lt;br /&gt;
Install pip:&lt;br /&gt;
 sudo /opt/python-2.7.9/bin/easy_install pip&lt;br /&gt;
&lt;br /&gt;
Sample pip usage:&lt;br /&gt;
 sudo /opt/python-2.7.9/bin/pip install paramiko&lt;br /&gt;
&lt;br /&gt;
== IDLE and Interactive Mode ==&lt;br /&gt;
&lt;br /&gt;
Interactive Mode - &amp;quot;When commands are read from a tty, the interpreter is said to be in interactive mode. In this mode it prompts for the next command with the primary prompt, usually three greater-than signs (&amp;gt;&amp;gt;&amp;gt;); for continuation lines it prompts with the secondary prompt, by default three dots (...).&amp;quot; [http://docs.python.org/2/tutorial/interpreter.html#invoking-the-interpreter]&lt;br /&gt;
&lt;br /&gt;
Can use &#039;_&#039; to reference last output:&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; 5 + 6&lt;br /&gt;
 11&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; print _&lt;br /&gt;
 11&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* 2. Using the Python Interpreter — Python v2.7.3 documentation - http://docs.python.org/2/tutorial/interpreter.html&lt;br /&gt;
&lt;br /&gt;
== Python 2.7 EOL ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
DEPRECATION: Python 2.7 will reach the end of its life on January 1st, 2020. Please upgrade your Python as Python 2.7 won&#039;t be maintained after that date. A future version of pip will drop support for Python 2.7.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Show All Python in Path ==&lt;br /&gt;
&lt;br /&gt;
 compgen -c | grep -i &amp;quot;python&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
&lt;br /&gt;
=== Hello World ===&lt;br /&gt;
&lt;br /&gt;
[http://en.wikipedia.org/wiki/Shebang_%28Unix%29 shebang] (also called a hashbang) of Python:&lt;br /&gt;
 #!/usr/bin/env python&lt;br /&gt;
 print &amp;quot;Hello World&amp;quot;&lt;br /&gt;
&lt;br /&gt;
NOTE: can also just use &amp;quot;#!/usr/bin/python&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Standard Script ===&lt;br /&gt;
&lt;br /&gt;
Standard Script:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def main(args):&lt;br /&gt;
  # do logic&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
  sys.exit(main(sys.argv))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Needed for things like pylint&lt;br /&gt;
&lt;br /&gt;
=== White Space ===&lt;br /&gt;
&lt;br /&gt;
Python uses white space to indicate code blocks.  Instead of &#039;&#039;{&#039;&#039; use a &#039;&#039;:&#039;&#039; and indent consistently (4 spaces).&lt;br /&gt;
&lt;br /&gt;
 if a == b:&lt;br /&gt;
     print &#039;equal&#039;&lt;br /&gt;
&lt;br /&gt;
Convert tabs to spaces:&lt;br /&gt;
 sed -i &#039;s/\t/    /g&#039; *.py&lt;br /&gt;
&lt;br /&gt;
Remove trailing whitespace:&lt;br /&gt;
 sed -i &#039;s/\s*$//&#039; *.py&lt;br /&gt;
 sed --in-place &#039;s/[[:space:]]\+$//&#039; fileName&lt;br /&gt;
&lt;br /&gt;
Clean project:&lt;br /&gt;
 # find . -name &amp;quot;*py&amp;quot; -exec dos2unix {} \;&lt;br /&gt;
 # find . -name &amp;quot;*py&amp;quot; -exec sed -i &#039;s/\t/    /g&#039; {} \;&lt;br /&gt;
 # find . -name &amp;quot;*py&amp;quot; -exec sed -i &#039;s/\s*$//&#039; {} \;&lt;br /&gt;
 find . -name &amp;quot;*py&amp;quot; -exec dos2unix {} \; -exec sed -i &#039;s/\t/    /g&#039; {} \; -exec sed -i &#039;s/\s*$//&#039; {} \;&lt;br /&gt;
&lt;br /&gt;
==== Trim Tailing White Space ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sed -e &#039;s/[[:space:]]*$//&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
find . -name &amp;quot;*.py&amp;quot; -exec sed -i -e &#039;s/[[:space:]]*$//&#039; {} \;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ref: [https://stackoverflow.com/questions/369758/how-to-trim-whitespace-from-a-bash-variable]&lt;br /&gt;
&lt;br /&gt;
=== Print ===&lt;br /&gt;
&lt;br /&gt;
print - http://docs.python.org/tutorial/inputoutput.html&lt;br /&gt;
&lt;br /&gt;
Print:  # include new line&lt;br /&gt;
 print(&amp;quot;Hello World&amp;quot;)&lt;br /&gt;
 print &amp;quot;Hello World&amp;quot;   # python 2 only&lt;br /&gt;
&lt;br /&gt;
Suppress new line: [http://stackoverflow.com/questions/493386/how-to-print-in-python-without-newline-or-space]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
print(&#039;#&#039;, end=&#039;&#039;)    # python 3&lt;br /&gt;
print &amp;quot;Hello World&amp;quot;,  # python 2 only (does produce a single separating white space though)&lt;br /&gt;
&lt;br /&gt;
import sys&lt;br /&gt;
sys.stdout.write(&#039;.&#039;)  # no separating white space&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 # flush output&lt;br /&gt;
 # optional, if new line won&#039;t come for some time&lt;br /&gt;
 import sys&lt;br /&gt;
 sys.stdout.flush()&lt;br /&gt;
&lt;br /&gt;
Multiple with separator:&lt;br /&gt;
 print(&amp;quot;hello&amp;quot;, &amp;quot;world&amp;quot;)  # separated by spaces&lt;br /&gt;
 print(&amp;quot;hello&amp;quot;, &amp;quot;world&amp;quot;, sep = &#039;.&#039;)  # separated by period&lt;br /&gt;
&lt;br /&gt;
Formatting:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mystr = &amp;quot;abc&amp;quot;&lt;br /&gt;
myint = 5&lt;br /&gt;
myflt = 3.141592&lt;br /&gt;
print( &amp;quot;%s %d %.3f&amp;quot; % (mystr, myint, myflt) )&lt;br /&gt;
print( &amp;quot;{0} {1} {2}&amp;quot;.format(mystr, myint, myflt) )  # string&#039;s format function (python &amp;gt; 2.7)&lt;br /&gt;
print( &amp;quot;{a} {b} {c}&amp;quot;.format( b = myint, a = mystr, c = myflt) )  # by name&lt;br /&gt;
print( &amp;quot;={a:4s}={b:3d}={c:10.3f}=&amp;quot;.format( b = myint, a = mystr, c = myflt) )  # type and padding&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Padded floating point decimal number: (rounds)&lt;br /&gt;
 print &amp;quot;%06.2f&amp;quot; % 2.319         # &amp;quot;002.32&amp;quot;&lt;br /&gt;
 print &amp;quot;%6.2f&amp;quot; % 2.311          # &amp;quot;  2.31&amp;quot;&lt;br /&gt;
 print &amp;quot;{:06.2f}&amp;quot;.format(2.319) # &amp;quot;002.32&amp;quot;&lt;br /&gt;
 print &amp;quot;{:6.2f}&amp;quot;.format(2.319)  # &amp;quot;  2.32&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 # Python 3 version where var=2.321234&lt;br /&gt;
 print(f&amp;quot;{var:.2f}&amp;quot;)  # &amp;quot;2.32&amp;quot;&lt;br /&gt;
 print(f&amp;quot;{var:6.2f}&amp;quot;)  # &amp;quot;  2.32&amp;quot;&lt;br /&gt;
 print(f&amp;quot;{var:06.2f}&amp;quot;)  # &amp;quot;002.32&amp;quot;&lt;br /&gt;
 print(f&amp;quot;{var:08.2f}&amp;quot;)  # &amp;quot;00002.32&amp;quot;&lt;br /&gt;
 print(f&amp;quot;{var:08.4f}&amp;quot;)  # &amp;quot;002.3212&amp;quot;&lt;br /&gt;
 # Python 3 version where var=2.329 - rounding&lt;br /&gt;
 print(f&amp;quot;{var:06.2f}&amp;quot;)  # &amp;quot;002.33&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Comments ===&lt;br /&gt;
&lt;br /&gt;
 # this is a comment&lt;br /&gt;
 # this is a comment&lt;br /&gt;
 x = y  # this is a comment&lt;br /&gt;
&lt;br /&gt;
Using a non assigned string constant as a comment: (also used for doc strings, not generally recommended)&lt;br /&gt;
 &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
 multi line comment&lt;br /&gt;
 &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;&#039;&lt;br /&gt;
 multi line comment can comment out &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
 &#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This can be used like a C &amp;quot;#if 0&amp;quot; concept to comment out whole sections of code.&lt;br /&gt;
&lt;br /&gt;
Using false block to comment out a block code: (does not ignore bad syntax though)&lt;br /&gt;
 if False:&lt;br /&gt;
    # code in this block is ignored&lt;br /&gt;
&lt;br /&gt;
=== doc strings ===&lt;br /&gt;
&lt;br /&gt;
Using a non assigned string constant as a comment: (also used for doc strings, not generally recommended)&lt;br /&gt;
 &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
 multi line comment&lt;br /&gt;
 &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Variable Type ===&lt;br /&gt;
&lt;br /&gt;
 print( type(myvar).__name__ )&lt;br /&gt;
&lt;br /&gt;
Used to be able to just print the type(myvar), but this doesn&#039;t seem to work anymore :-(&lt;br /&gt;
&lt;br /&gt;
=== Variable Directory ===&lt;br /&gt;
&lt;br /&gt;
All of the properties and functions of a variable or object&lt;br /&gt;
&lt;br /&gt;
 print( dir(myvar) )&lt;br /&gt;
&lt;br /&gt;
=== Help ===&lt;br /&gt;
&lt;br /&gt;
dir - list functions and properties of objects:&lt;br /&gt;
 import math&lt;br /&gt;
 dir(math)  # module&lt;br /&gt;
 dir(dir)   # function&lt;br /&gt;
 dir(&amp;quot;&amp;quot;)    # object  - &amp;quot;&amp;quot;, [], {}, etc...&lt;br /&gt;
 dir(__builtins__)  # built in functions&lt;br /&gt;
 dir()      # list imported objects, and dunder methods&lt;br /&gt;
&lt;br /&gt;
Note: dunder (double under) methods determine special functionality (eg. __add__ for +)&lt;br /&gt;
&lt;br /&gt;
help - manual printout: (class doc string, function doc string, data, etc)&lt;br /&gt;
 import math&lt;br /&gt;
 help(math)    # full module info&lt;br /&gt;
 help(len)     # full function info&lt;br /&gt;
 help([&amp;quot;foo&amp;quot;]) # full object info&lt;br /&gt;
&lt;br /&gt;
Pydoc: (command line, same as &#039;import math, help(math)&#039;&lt;br /&gt;
 $ pydoc math&lt;br /&gt;
&lt;br /&gt;
Documentation String: (aka docstring, doc string)&lt;br /&gt;
 print(math.pow.__doc__)  # module doc string&lt;br /&gt;
 print(len.__doc__)       # function doc string&lt;br /&gt;
&lt;br /&gt;
Object or function type:&lt;br /&gt;
 type(x)&lt;br /&gt;
&lt;br /&gt;
 mylist = []&lt;br /&gt;
 isinstance(mylist, list)  # True&lt;br /&gt;
 type(s) is list           # True&lt;br /&gt;
&lt;br /&gt;
Note: isinstance() and type() not equivalent when objects and subclass get involved&lt;br /&gt;
&lt;br /&gt;
IDLE interactive help:&lt;br /&gt;
 help()&lt;br /&gt;
&lt;br /&gt;
=== Variables ===&lt;br /&gt;
&lt;br /&gt;
Basic Data Types&lt;br /&gt;
 str = &amp;quot;string&amp;quot;  # string&lt;br /&gt;
 num = 5         # integer&lt;br /&gt;
 flt = 5.0       # float&lt;br /&gt;
 nothing = None  # None  (not the same as undefined)&lt;br /&gt;
&lt;br /&gt;
Undefined.  Variables start off in an &#039;undefined&#039; state.  It is always better to initially set the variable to None to avoid this state.  To check if undefined: [http://code.activestate.com/recipes/59892-testing-if-a-variable-is-defined/] [http://code.activestate.com/recipes/59892/]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 try:&lt;br /&gt;
   x&lt;br /&gt;
 except NameError:&lt;br /&gt;
   x = None&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Rules: [http://www.python.org/dev/peps/pep-0008/ PEP8 - Method Names and Instance Variables]&lt;br /&gt;
* any length&lt;br /&gt;
* letters, numbers, underscore&lt;br /&gt;
* first character can&#039;t be number&lt;br /&gt;
* case sensitive&lt;br /&gt;
* cannot use keywords&lt;br /&gt;
&lt;br /&gt;
Multiple assignment:&lt;br /&gt;
 x = y = z = 0              # Zero x, y and z&lt;br /&gt;
 x, y, z = 1, &amp;quot;two&amp;quot;, 3.0    # x = 1, y = &amp;quot;two&amp;quot;, z = 3.0&lt;br /&gt;
&lt;br /&gt;
Swap variables: (done in parallel)&lt;br /&gt;
 a, b = b, a&lt;br /&gt;
&lt;br /&gt;
Unpack variables: (requires equal items on each side)&lt;br /&gt;
 a, b, c = [1, 2, 3]&lt;br /&gt;
&lt;br /&gt;
Other Data Types:&lt;br /&gt;
* tuple&lt;br /&gt;
* list&lt;br /&gt;
* dictionary&lt;br /&gt;
* set&lt;br /&gt;
* objects&lt;br /&gt;
&lt;br /&gt;
Everything in Python is an object that has:&lt;br /&gt;
* identity:  id(obj)&lt;br /&gt;
* type:  type(obj)&lt;br /&gt;
* value:  obj&lt;br /&gt;
** mutable - id() stays the same on modification (dictionary, lists, objects)&lt;br /&gt;
** immutable - id() changes on modification as new object is created (string, integer, tuple)&lt;br /&gt;
&lt;br /&gt;
==== Check if Variable Exists ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
try:&lt;br /&gt;
    a # does a exist in the current namespace&lt;br /&gt;
except NameError:&lt;br /&gt;
    a = 10 # nope&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &#039;a&#039; in vars() or &#039;a&#039; in globals()&lt;br /&gt;
 &#039;a&#039; in vars(__builtins__)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if hasattr(a, &#039;property&#039;):&lt;br /&gt;
    doStuff(a.property)&lt;br /&gt;
else:&lt;br /&gt;
    otherStuff()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ref: [https://stackoverflow.com/questions/1592565/determine-if-variable-is-defined-in-python] [https://stackoverflow.com/questions/610883/how-to-know-if-an-object-has-an-attribute-in-python]&lt;br /&gt;
&lt;br /&gt;
=== Numbers ===&lt;br /&gt;
&lt;br /&gt;
 num = 5&lt;br /&gt;
 print &amp;quot;num: %d&amp;quot; % num&lt;br /&gt;
&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; print &amp;quot;Today&#039;s stock price: %f&amp;quot; % 50.4625   1&lt;br /&gt;
 50.462500&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; print &amp;quot;Today&#039;s stock price: %.2f&amp;quot; % 50.4625 2&lt;br /&gt;
 50.46&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; print &amp;quot;Change since yesterday: %+.2f&amp;quot; % 1.5 3&lt;br /&gt;
 +1.50&lt;br /&gt;
&lt;br /&gt;
Arithmetic:&lt;br /&gt;
 + - * /&lt;br /&gt;
 //  # integer division&lt;br /&gt;
 %   # modulus&lt;br /&gt;
 **  # exponent&lt;br /&gt;
&lt;br /&gt;
Compact Arithmetic:&lt;br /&gt;
 i+=1  # Increment - Note, there is no &#039;i++&#039;&lt;br /&gt;
 i*=2  # Multiply&lt;br /&gt;
 i%=2  # modulus&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
Math Functions:&lt;br /&gt;
 import math&lt;br /&gt;
 math.ceil(x)&lt;br /&gt;
 math.floor(x)&lt;br /&gt;
 math.trunc(x)&lt;br /&gt;
 math.pow(x,y)&lt;br /&gt;
&lt;br /&gt;
 abs(x)  # built in&lt;br /&gt;
&lt;br /&gt;
String interpolation:&lt;br /&gt;
 %% % character&lt;br /&gt;
 %d integer&lt;br /&gt;
 %x hex&lt;br /&gt;
 %X hex (upper)&lt;br /&gt;
 %f float&lt;br /&gt;
 %s string&lt;br /&gt;
&lt;br /&gt;
 x = 1/81&lt;br /&gt;
 print(&#039;value: %.2f&#039; % x)  # 0.01&lt;br /&gt;
 print(&#039;value: %.5f&#039; % x)  # 0.012345&lt;br /&gt;
 print(&#039;%d %d %d&#039; % (1, 2, 3))&lt;br /&gt;
&lt;br /&gt;
Type check:&lt;br /&gt;
 if not isinstance(myvar, (int, float)): ...&lt;br /&gt;
&lt;br /&gt;
=== Strings ===&lt;br /&gt;
&lt;br /&gt;
STRINGS ARE IMMUTABLE!  (to modify convert to a list)&lt;br /&gt;
&lt;br /&gt;
Strings: (String Constants)&lt;br /&gt;
 str = &amp;quot;Hello&amp;quot;&lt;br /&gt;
 str = &#039;Hello&#039;&lt;br /&gt;
 str = &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
   Hello&lt;br /&gt;
   World&lt;br /&gt;
 &amp;quot;&amp;quot;&amp;quot;      # can also use &#039;&#039;&#039;...&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
String literals can span multiple lines: (no wrapping when \ used)&lt;br /&gt;
 hello = &amp;quot;hello\&lt;br /&gt;
 world&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Length:&lt;br /&gt;
 len(&amp;quot;str&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Raw string: (back slashes are not escaped)&lt;br /&gt;
 myrawstr = r&amp;quot;hello\nworld\&lt;br /&gt;
 how are you&amp;quot;&lt;br /&gt;
 myrawstr = r&amp;quot;C:\&amp;quot;  # ERROR - limitation of what won&#039;t be escaped&lt;br /&gt;
&lt;br /&gt;
Concatenation:&lt;br /&gt;
 str = &#039;hot&#039; + &#039;dog&#039;&lt;br /&gt;
 print &amp;quot;Hello&amp;quot; &amp;quot;World&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Can&#039;t concat numbers&lt;br /&gt;
 str = 5 + &#039;test&#039;  # error&lt;br /&gt;
 num = 5&lt;br /&gt;
 str = num + &#039;test&#039;  # error&lt;br /&gt;
 str = str(5) + str(num) + &#039;test&#039;  # ok&lt;br /&gt;
&lt;br /&gt;
Repeated Concatenation:&lt;br /&gt;
 str = 10 * &#039;ha&#039;&lt;br /&gt;
 str = &#039;ha&#039; * 10  # same&lt;br /&gt;
 print &#039;-&#039;*60  # --------------------&lt;br /&gt;
&lt;br /&gt;
String Indexing:&lt;br /&gt;
 s = &#039;hello&#039;&lt;br /&gt;
 print( s[0] )    # is &#039;h&#039;&lt;br /&gt;
 print( s[-1] )   # is &#039;o&#039;&lt;br /&gt;
 print( s[len(s) - 1 ] )  # is also &#039;o&#039;&lt;br /&gt;
&lt;br /&gt;
Modify Strings: [http://stackoverflow.com/questions/1228299/change-one-character-in-a-string-in-python]&lt;br /&gt;
 s[1] = &#039;x&#039;  # ERROR!&lt;br /&gt;
 ERROR: can&#039;t modify string by index&lt;br /&gt;
 &lt;br /&gt;
 # solution:&lt;br /&gt;
 s = list(&amp;quot;Hello World&amp;quot;)&lt;br /&gt;
 s[0] = &#039;C&#039;&lt;br /&gt;
 print( &amp;quot;&amp;quot;.join(s) )&lt;br /&gt;
&lt;br /&gt;
String Slicing:&lt;br /&gt;
 s = &#039;hello&#039;&lt;br /&gt;
 print( s[0:3] )  # &#039;hel&#039;&lt;br /&gt;
 i = 1&lt;br /&gt;
 print( s[i:i+1] )  # &#039;e&#039;&lt;br /&gt;
 print( s[:3] )  # 0:3 &#039;hel&#039;&lt;br /&gt;
 print( s[4:] )  # 4:end &#039;o&#039;&lt;br /&gt;
 print( s[:] )  # start:end &#039;hello&#039;&lt;br /&gt;
 print( s[-2:] )  # -2:end &#039;lo&#039;&lt;br /&gt;
&lt;br /&gt;
For loop:&lt;br /&gt;
 s = &#039;hello&#039;&lt;br /&gt;
 for c in s:&lt;br /&gt;
   print c  # c = &#039;h&#039; first time&lt;br /&gt;
&lt;br /&gt;
Escape characters:&lt;br /&gt;
 \\  \&#039;  \&amp;quot;  \n  \r  \t&lt;br /&gt;
&lt;br /&gt;
Alternate loop:&lt;br /&gt;
 s = &#039;hello&#039;&lt;br /&gt;
 for i in range( len(s) ):&lt;br /&gt;
   print s[i]&lt;br /&gt;
&lt;br /&gt;
Ord and Char (ASCII):&lt;br /&gt;
 ord(&#039;a&#039;)  # 97&lt;br /&gt;
 chr(97)   # &#039;a&#039;&lt;br /&gt;
&lt;br /&gt;
 0-9 : 48-57&lt;br /&gt;
 A-Z : 65-90&lt;br /&gt;
 a-z : 97-122&lt;br /&gt;
&lt;br /&gt;
List Functions:  (dir on any string)&lt;br /&gt;
 dir(&#039;&#039;)&lt;br /&gt;
 dir(str)&lt;br /&gt;
&lt;br /&gt;
Help:&lt;br /&gt;
 help(&#039;&#039;)&lt;br /&gt;
 help(str)&lt;br /&gt;
&lt;br /&gt;
Padding:&lt;br /&gt;
 &amp;quot;a&amp;quot;.rjust(2, &#039;0&#039;)  # &#039;0a&#039;&lt;br /&gt;
 &amp;quot;1&amp;quot;.ljust(4, &#039;0&#039;)  # &#039;1000&#039;&lt;br /&gt;
&lt;br /&gt;
String Test Functions:&lt;br /&gt;
 &amp;quot;HELLO&amp;quot;.isupper()   # True&lt;br /&gt;
 &amp;quot;hello&amp;quot;.islower()   # True&lt;br /&gt;
 &amp;quot;hello&amp;quot;.isalpha()   # True&lt;br /&gt;
 &amp;quot;12.22&amp;quot;.isdigit()   # False (because of &#039;.&#039;)&lt;br /&gt;
 &amp;quot;12.22&amp;quot;.isnumeric() # False (because of &#039;.&#039;)&lt;br /&gt;
 &amp;quot;hel2&amp;quot;.isalnum()    # True&lt;br /&gt;
 &amp;quot;e&amp;quot; in &amp;quot;hello&amp;quot;      # True&lt;br /&gt;
 &amp;quot;hello&amp;quot;.startswith(&#039;he&#039;)  # True&lt;br /&gt;
 &amp;quot;hello&amp;quot;.endswith(&#039;lo&#039;)    # True&lt;br /&gt;
&lt;br /&gt;
Note: To check for floats: [http://stackoverflow.com/questions/354038/how-do-i-check-if-a-string-is-a-number-in-python]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def is_number(s):&lt;br /&gt;
    try:&lt;br /&gt;
        float(s)&lt;br /&gt;
        return True&lt;br /&gt;
    except ValueError:&lt;br /&gt;
        return False&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
String Modify Functions: (sort of... Strings are immutable)&lt;br /&gt;
 &amp;quot;HELLO&amp;quot;.lower()           # &#039;hello&#039;&lt;br /&gt;
 &amp;quot;hello&amp;quot;.upper()           # &#039;HELLO&#039;&lt;br /&gt;
 &amp;quot; hello &amp;quot;.strip()         # &#039;hello&#039; remove leading/tailing whitespace&lt;br /&gt;
 &amp;quot; hello &amp;quot;.lstrip()        # &#039;hello &#039; remove left whitespace&lt;br /&gt;
 &amp;quot; hello &amp;quot;.rstrip()        # &#039; hello&#039; remove right whitespace&lt;br /&gt;
 &amp;quot;www.com&amp;quot;.split(&#039;.&#039;)      # [&#039;www&#039;, &#039;com&#039;]   &amp;lt;- list&lt;br /&gt;
 &amp;quot;www.com&amp;quot;.partition(&#039;.&#039;)  # (&#039;www&#039;, &#039;.&#039;, &#039;com&#039;)  &amp;lt;- tuple&lt;br /&gt;
 &amp;quot;&amp;quot;.join( (&#039;a&#039;,&#039;b&#039;,&#039;c&#039;) )  # &amp;quot;abc&amp;quot;  join strings, list or tuple&lt;br /&gt;
 &amp;quot;-&amp;quot;.join( (&#039;a&#039;,&#039;b&#039;,&#039;c&#039;) ) # &amp;quot;a-b-c&amp;quot;  join with separator&lt;br /&gt;
 &amp;quot;23&amp;quot;.zfill(4)             # &amp;quot;0023&amp;quot;&lt;br /&gt;
&lt;br /&gt;
String Search Functions:&lt;br /&gt;
 &amp;quot;hello&amp;quot;.find(&#039;lo&#039;)   # 3  (-1 on fail)&lt;br /&gt;
 &amp;quot;hello&amp;quot;.index(&#039;lo&#039;)  # 3 (exception on fail)&lt;br /&gt;
 &amp;quot;hello&amp;quot;.rfind(&#039;lo&#039;)  # 3 right to left (-1 on fail)&lt;br /&gt;
 &amp;quot;hello&amp;quot;.rindex(&#039;lo&#039;) # 3 right to left (exception on fail)&lt;br /&gt;
&lt;br /&gt;
Formatting: (form of concatenation)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mystr = &amp;quot;abc&amp;quot;&lt;br /&gt;
myint = 5&lt;br /&gt;
myflt = 3.141592&lt;br /&gt;
print( &amp;quot;%s %d %.3f&amp;quot; % (mystr, myint, myflt) )&lt;br /&gt;
print( &amp;quot;{0} {1} {2}&amp;quot;.format(mystr, myint, myflt) )  # pep 3101 style - string&#039;s format function (python &amp;gt; 2.7)&lt;br /&gt;
print( &amp;quot;{a} {b} {c}&amp;quot;.format( b = myint, a = mystr, c = myflt) )  # by name&lt;br /&gt;
print( &amp;quot;={a:4s}={b:3d}={c:10.3f}=&amp;quot;.format( b = myint, a = mystr, c = myflt) )  # type and padding&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Split multi line string:&lt;br /&gt;
 for line in str.split(&#039;\n&#039;):  print(line)&lt;br /&gt;
 lines = str.splitlines()      # returns list&lt;br /&gt;
 lines = str.splitlines(True)  # returns list (each includes new line characters)&lt;br /&gt;
&lt;br /&gt;
Input a string:&lt;br /&gt;
 name = input(&#039;What is your name: &#039;).strip()  # python 3&lt;br /&gt;
 name = raw_input(&#039;What is your name: &#039;).strip()  # python 2&lt;br /&gt;
&lt;br /&gt;
Leet Speak:&lt;br /&gt;
 leet_table = &#039;&#039;.maketrans(&#039;EIOBT&#039;, &#039;31087&#039;)&lt;br /&gt;
 &#039;BE COOL. SPEAK LEET!&#039;.translate(leet_table)&lt;br /&gt;
&lt;br /&gt;
String Functions:&lt;br /&gt;
 newstr = mystr.strip()             # remove white space on both sides&lt;br /&gt;
 newstr = mystr.rstrip()            # remove white space on right side&lt;br /&gt;
 newstr = mystr.lstrip()            # remove white space on left side&lt;br /&gt;
 newstr = mystr.replace(&#039;\n&#039;, &#039; &#039;)  # replace string with another&lt;br /&gt;
 newstr = mystr.replace(&#039;jello&#039;, &#039;hello&#039;)  # replace string with another&lt;br /&gt;
&lt;br /&gt;
==== String Formatting ====&lt;br /&gt;
&lt;br /&gt;
PyFormat: Using % and .format() for great good! - https://pyformat.info/&lt;br /&gt;
&lt;br /&gt;
===== Zero Padding =====&lt;br /&gt;
&lt;br /&gt;
3 zero padding:&lt;br /&gt;
 &amp;quot;{:03}&amp;quot;.format(1)  # 003&lt;br /&gt;
&lt;br /&gt;
3 zero padding, specify position:&lt;br /&gt;
 &amp;quot;{1:03}&amp;quot;.format(1, 2)  # 002&lt;br /&gt;
&lt;br /&gt;
Old method:&lt;br /&gt;
 &amp;quot;%03d&amp;quot; % 2  # 002&lt;br /&gt;
&lt;br /&gt;
=== chr and ord ===&lt;br /&gt;
&lt;br /&gt;
Ord and Char (ASCII):&lt;br /&gt;
 ord(&#039;a&#039;)  # 97&lt;br /&gt;
 chr(97)   # &#039;a&#039;&lt;br /&gt;
&lt;br /&gt;
=== Range ===&lt;br /&gt;
&lt;br /&gt;
Creates a list of numbers.  Remember: range always ends one less than you want!&lt;br /&gt;
&lt;br /&gt;
Count:&lt;br /&gt;
 ten = 10&lt;br /&gt;
 one = 1&lt;br /&gt;
 range(ten)               # [0,1,...,9]   starts with zero by default&lt;br /&gt;
 range(one, ten + 1)      # [1,...,10]    actually get 1 to 10&lt;br /&gt;
 range(ten, one - 1, -1)  # [10,9,...,1]  count down&lt;br /&gt;
 range(2, 10 + 1, 2)      # [2,4,...,10]  even numbers&lt;br /&gt;
&lt;br /&gt;
=== drange ===&lt;br /&gt;
&lt;br /&gt;
Solution for decimal range() step value:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def drange(start, stop, step):&lt;br /&gt;
    r = start&lt;br /&gt;
    while r &amp;lt; stop:&lt;br /&gt;
        yield r&lt;br /&gt;
    r += step&lt;br /&gt;
&lt;br /&gt;
sub_ten = drange(0.0, 1.0, 0.1)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* floating point - Python decimal range() step value - Stack Overflow - http://stackoverflow.com/questions/477486/python-decimal-range-step-value&lt;br /&gt;
&lt;br /&gt;
=== Casting ===&lt;br /&gt;
&lt;br /&gt;
Convert:&lt;br /&gt;
 float(3)&lt;br /&gt;
 str(85)&lt;br /&gt;
 int(8.6)&lt;br /&gt;
 round(5.5)&lt;br /&gt;
&lt;br /&gt;
Check Type:&lt;br /&gt;
 type(5)     # &amp;lt;class &#039;int&#039;&amp;gt;&lt;br /&gt;
 type(5.0)   # &amp;lt;class &#039;float&#039;&amp;gt;&lt;br /&gt;
 type(&#039;5&#039;)   # &amp;lt;class &#039;str&#039;&amp;gt;&lt;br /&gt;
 type(None)  # &amp;lt;class &#039;NoneType&#039;&amp;gt;&lt;br /&gt;
 type(print) # &amp;lt;class &#039;builtin_function_or_method&#039;&amp;gt;&lt;br /&gt;
 type(())    # &amp;lt;class &#039;tuple&#039;&amp;gt;&lt;br /&gt;
 type([])    # &amp;lt;class &#039;list&#039;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 mytype = int&lt;br /&gt;
 if type(1) is mytype: ...&lt;br /&gt;
&lt;br /&gt;
=== Boolean Logic ===&lt;br /&gt;
&lt;br /&gt;
True and False:&lt;br /&gt;
 bol = True&lt;br /&gt;
 bol = False&lt;br /&gt;
&lt;br /&gt;
Boolean Operators: (in order precedence)&lt;br /&gt;
 a == b&lt;br /&gt;
 a != b&lt;br /&gt;
 not a&lt;br /&gt;
 a and b&lt;br /&gt;
 a or b&lt;br /&gt;
&lt;br /&gt;
Note: Short-circuit evaluated - &#039;and&#039; and &#039;or&#039;&lt;br /&gt;
&lt;br /&gt;
Return Boolean:&lt;br /&gt;
 return myint &amp;gt;= 16&lt;br /&gt;
&lt;br /&gt;
Get Boolean from string: [http://stackoverflow.com/questions/715417/converting-from-a-string-to-boolean-in-python]&lt;br /&gt;
 # Note: no built in way to do this&lt;br /&gt;
&lt;br /&gt;
 myString = &amp;quot;false&amp;quot;&lt;br /&gt;
 val = (myString == &amp;quot;true&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
 True if myString==&amp;quot;True&amp;quot; else False&lt;br /&gt;
&lt;br /&gt;
 s in [&#039;true&#039;, &#039;1&#039;, &#039;t&#039;, &#039;y&#039;, &#039;yes&#039;, &#039;yeah&#039;, &#039;yup&#039;, &#039;certainly&#039;, &#039;uh-huh&#039;]&lt;br /&gt;
&lt;br /&gt;
 def str2bool(v):&lt;br /&gt;
   return v.lower() in (&amp;quot;yes&amp;quot;, &amp;quot;true&amp;quot;, &amp;quot;t&amp;quot;, &amp;quot;1&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
=== None ===&lt;br /&gt;
&lt;br /&gt;
None is Python&#039;s version of NULL or NIL.&lt;br /&gt;
&lt;br /&gt;
None is a singleton (Python only has one copy of None in the interpreter).&lt;br /&gt;
&lt;br /&gt;
 if myvar is None:&lt;br /&gt;
     ...&lt;br /&gt;
&lt;br /&gt;
=== If Conditionals ===&lt;br /&gt;
&lt;br /&gt;
Operators:&lt;br /&gt;
 ==, !=, not, and, or, &amp;lt;, &amp;gt;, &amp;lt;&amp;gt;, &amp;lt;=, &amp;gt;=, in, not in, is, is not&lt;br /&gt;
&lt;br /&gt;
If statement:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if a == b:&lt;br /&gt;
  ...&lt;br /&gt;
elif c &amp;lt; age &amp;lt; d:&lt;br /&gt;
  ...&lt;br /&gt;
else:&lt;br /&gt;
  ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Shorthand conditional: (ternary operator)&lt;br /&gt;
 val = True if a == b else False&lt;br /&gt;
&lt;br /&gt;
is - checks for identical objects - same id()&lt;br /&gt;
 # None is a singleton, so this works great for None&lt;br /&gt;
 if myvar is None:&lt;br /&gt;
     ...&lt;br /&gt;
&lt;br /&gt;
Other shorthand:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def mycmp(x, y):&lt;br /&gt;
  if x &amp;gt; y: return True&lt;br /&gt;
  else: return False&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Switch/Case statement:&lt;br /&gt;
* there is no built in switch/case statement, use &amp;quot;if ... elif ... elif ...&amp;quot; sequence instead&lt;br /&gt;
&lt;br /&gt;
=== For Loop ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;for&#039;&#039; is used for iterating over an iterable sequence (eg. lists, dictionaries, tuples). (for each)&lt;br /&gt;
&lt;br /&gt;
# range(start, end + 1, skip)&lt;br /&gt;
&lt;br /&gt;
 for i in range(10):&lt;br /&gt;
   print(i)  # 0 .. 9&lt;br /&gt;
&lt;br /&gt;
 for i in range(5, 10):&lt;br /&gt;
   print(i)  # 5 .. 9&lt;br /&gt;
&lt;br /&gt;
 for i in range(10, 0, -1):&lt;br /&gt;
   print(i)  # 10 .. 1&lt;br /&gt;
&lt;br /&gt;
 for i in [1, 2, 3]:  # iterate over list&lt;br /&gt;
   print(i)  # 1 2 3&lt;br /&gt;
&lt;br /&gt;
Discard variable: [http://bytes.com/topic/python/answers/757444-loop-without-variable]&lt;br /&gt;
 for _ in range(10):  # repeat and discard variable (good for pep8 check)&lt;br /&gt;
   print &amp;quot;hello world&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 for key in my_dict.keys(): ...&lt;br /&gt;
 for value in my_dict.values(): ...&lt;br /&gt;
 for key, value in my_dict.items(): ...&lt;br /&gt;
&lt;br /&gt;
Compact version:&lt;br /&gt;
 for i in range(10): print(i)    # 0 .. 9&lt;br /&gt;
&lt;br /&gt;
Access index: [http://stackoverflow.com/questions/522563/accessing-the-index-in-python-for-loops]&lt;br /&gt;
 # using enumeration&lt;br /&gt;
 for idx, val in enumerate(mylist):&lt;br /&gt;
   print idx, val&lt;br /&gt;
&lt;br /&gt;
 # using range&lt;br /&gt;
 for ix in range(len(mylist)):&lt;br /&gt;
   print mylist[ix]&lt;br /&gt;
&lt;br /&gt;
 # list comprehension&lt;br /&gt;
 [ (ix, mylist[ix]) for ix in range(len(mylist))]&lt;br /&gt;
&lt;br /&gt;
=== While Loop ===&lt;br /&gt;
&lt;br /&gt;
 i = 0&lt;br /&gt;
 while i &amp;lt; 10:&lt;br /&gt;
   i = i + 1&lt;br /&gt;
&lt;br /&gt;
 while True:&lt;br /&gt;
   ...  # infinite loop&lt;br /&gt;
&lt;br /&gt;
=== Breaking Loops ===&lt;br /&gt;
&lt;br /&gt;
break statement:&lt;br /&gt;
 while True:&lt;br /&gt;
   if s == &#039;done&#039;:&lt;br /&gt;
     break  # jump out of the loop&lt;br /&gt;
   ...&lt;br /&gt;
&lt;br /&gt;
continue statement: (works with while too)&lt;br /&gt;
  for i in range(10):&lt;br /&gt;
    if i == 2:&lt;br /&gt;
      continue  # skip 2&lt;br /&gt;
    ...&lt;br /&gt;
&lt;br /&gt;
=== Functions ===&lt;br /&gt;
&lt;br /&gt;
No return value:  (None)&lt;br /&gt;
 x = print(&#039;&#039;)&lt;br /&gt;
 # x is &#039;None&#039;&lt;br /&gt;
&lt;br /&gt;
Note: specifying no return value is the same as this:&lt;br /&gt;
 return None&lt;br /&gt;
&lt;br /&gt;
No Operation - &#039;pass&#039;:&lt;br /&gt;
 def noop():&lt;br /&gt;
   pass&lt;br /&gt;
&lt;br /&gt;
Function:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def area(radius):&lt;br /&gt;
  &amp;quot;&amp;quot;&amp;quot; This is a doc string &amp;quot;&amp;quot;&amp;quot;   # can be &amp;quot; ... &amp;quot; also...&lt;br /&gt;
  import math&lt;br /&gt;
  return math.pi * radius ** 2&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Function Doc string:&lt;br /&gt;
 print(area.__doc__)&lt;br /&gt;
 foo.func_doc&lt;br /&gt;
&lt;br /&gt;
Function name:&lt;br /&gt;
  foo.func_name&lt;br /&gt;
&lt;br /&gt;
Local variable:&lt;br /&gt;
 name = &amp;quot;old&amp;quot;&lt;br /&gt;
 def cname():&lt;br /&gt;
   name = &amp;quot;new&amp;quot;&lt;br /&gt;
 print(name)  # is still &#039;old&#039;&lt;br /&gt;
&lt;br /&gt;
Global variable:&lt;br /&gt;
 name = &amp;quot;old&amp;quot;&lt;br /&gt;
 def cname():&lt;br /&gt;
   global name&lt;br /&gt;
   name = &amp;quot;new&amp;quot;&lt;br /&gt;
 cname()&lt;br /&gt;
 print(name)  # is now &#039;new&#039;&lt;br /&gt;
&lt;br /&gt;
By convention starting point is: (not required)&lt;br /&gt;
 def main():&lt;br /&gt;
&lt;br /&gt;
Parameters: (with default)&lt;br /&gt;
 def foo(x, y, z = &amp;quot;default&amp;quot;):&lt;br /&gt;
&lt;br /&gt;
Note: don&#039;t use mutable for defaults, as the object is remembered across runs! (unless that is what you want)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# each call to t() will increase list&lt;br /&gt;
def t(foo=[]):&lt;br /&gt;
   foo.append(&#039;1&#039;)&lt;br /&gt;
   print(foo)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# fix mutable issue&lt;br /&gt;
def named_param(a, foo=None):&lt;br /&gt;
  foo = foo or []&lt;br /&gt;
  if not foo:&lt;br /&gt;
    foo.append(a)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Parameters by keyword:&lt;br /&gt;
 def foo(x = &#039;1&#039;, y = &#039;2&#039;, z = &#039;3&#039;):&lt;br /&gt;
   ...&lt;br /&gt;
 foo(y = &#039;a&#039;, x = &#039;b&#039;)   # order is not important with keywords&lt;br /&gt;
&lt;br /&gt;
Trick for optional parameter:&lt;br /&gt;
 def do(x = None):&lt;br /&gt;
   if x == None:&lt;br /&gt;
&lt;br /&gt;
Function tests - functions are callable&lt;br /&gt;
 callable(myfunc)&lt;br /&gt;
&lt;br /&gt;
=== Type Hints ===&lt;br /&gt;
&lt;br /&gt;
: &amp;quot;Note The Python runtime does not enforce function and variable type annotations. They can be used by third party tools such as type checkers, IDEs, linters, etc.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 def surface_area_of_cube(edge_length: float) -&amp;gt; str:&lt;br /&gt;
     return f&amp;quot;The surface area of the cube is {6 * edge_length ** 2}.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Without the hints:&lt;br /&gt;
 def surface_area_of_cube(edge_length):&lt;br /&gt;
     ...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ref: https://docs.python.org/3/library/typing.html&lt;br /&gt;
&lt;br /&gt;
=== Pass ===&lt;br /&gt;
&lt;br /&gt;
Pass is a null operation (noop):&lt;br /&gt;
&lt;br /&gt;
Do nothing, noop, take no action:&lt;br /&gt;
 pass&lt;br /&gt;
&lt;br /&gt;
Great for creating minimal classes:&lt;br /&gt;
 class MyEmptyClass:&lt;br /&gt;
   pass&lt;br /&gt;
&lt;br /&gt;
Greate for making stub functions/methods:&lt;br /&gt;
 def initlog(*args):&lt;br /&gt;
   pass  # remember to implement this!&lt;br /&gt;
&lt;br /&gt;
=== Slice ===&lt;br /&gt;
&lt;br /&gt;
Take take a slice of strings, lists, tuples, etc...&lt;br /&gt;
 a = [0,1,2,3,4,5]&lt;br /&gt;
 a[0]    # 0 - not a slice&lt;br /&gt;
 a[-1]   # 5 - not a slice&lt;br /&gt;
 a[0:1]  # [0]&lt;br /&gt;
 a[1:3]  # [1, 2]&lt;br /&gt;
 a[:2]   # [0, 1]&lt;br /&gt;
 a[:-1]  # [0, 1, 2, 3, 4] - all but last&lt;br /&gt;
 a[2:]   # [2, 3, 4, 5]&lt;br /&gt;
 a[::2]  # [0, 2, 4] - stride&lt;br /&gt;
 a[::-1] # [5, 4, 3, 2, 1, 0] - reverse&lt;br /&gt;
 range(0,10)[::2]  # [0, 2, 4, 6, 8] - stride&lt;br /&gt;
&lt;br /&gt;
 a = &#039;012345&#039;&lt;br /&gt;
 a[1:3]  # &#039;12&#039;&lt;br /&gt;
 a[::2]  # &#039;024&#039;&lt;br /&gt;
&lt;br /&gt;
=== [http://docs.python.org/reference/compound_stmts.html Compound Statements] ===&lt;br /&gt;
&lt;br /&gt;
Compound statements: (generally discouraged)&lt;br /&gt;
 fun1(); fun2(); fun3()&lt;br /&gt;
&lt;br /&gt;
Compound with statements: [http://docs.python.org/reference/compound_stmts.html#the-with-statement]&lt;br /&gt;
 with A() as a, B() as b: ...&lt;br /&gt;
&lt;br /&gt;
 #is equivalent to&lt;br /&gt;
 with A() as a:&lt;br /&gt;
     with B() as b:&lt;br /&gt;
         ...&lt;br /&gt;
&lt;br /&gt;
[http://www.python.org/dev/peps/pep-0343 PEP 0343] - The “with” statement&lt;br /&gt;
&lt;br /&gt;
 f = open(&#039;file&#039;)&lt;br /&gt;
 with f: ...&lt;br /&gt;
&lt;br /&gt;
Try: (quick ignore all exceptions, very dangerous)&lt;br /&gt;
 try: my_broken_function()&lt;br /&gt;
 except: pass&lt;br /&gt;
&lt;br /&gt;
=== Passing Command Line Arguments ===&lt;br /&gt;
&lt;br /&gt;
Parameters are stored in the &#039;sys.argv&#039; variable:&lt;br /&gt;
 import sys&lt;br /&gt;
 print( sys.argv[0] )  # name of script&lt;br /&gt;
 print( sys.argv[1] )  # first argument&lt;br /&gt;
 for arg in sys.argv: print( arg )  # list all arguments&lt;br /&gt;
&lt;br /&gt;
Print script name:&lt;br /&gt;
 os.path.basename(sys.argv[0])&lt;br /&gt;
&lt;br /&gt;
Print path to script:&lt;br /&gt;
 print sys.path[0]&lt;br /&gt;
&lt;br /&gt;
Paths: [http://code.activestate.com/recipes/474083-get-the-path-of-the-currently-executing-python-scr/]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import os,sys&lt;br /&gt;
print &amp;quot;CWD: &amp;quot;,os.getcwd()&lt;br /&gt;
print &amp;quot;Script: &amp;quot;,sys.argv[0]&lt;br /&gt;
print &amp;quot;.EXE: &amp;quot;,os.path.dirname(sys.executable)&lt;br /&gt;
print &amp;quot;Script dir: &amp;quot;, os.path.realpath(os.path.dirname(sys.argv[0]))&lt;br /&gt;
pathname, scriptname = os.path.split(sys.argv[0])&lt;br /&gt;
print &amp;quot;Relative script dir: &amp;quot;,pathname&lt;br /&gt;
print &amp;quot;Script dir: &amp;quot;, os.path.abspath(pathname)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 os.path.realpath(__file__)&lt;br /&gt;
&lt;br /&gt;
 print &#039;sys.argv[0] =&#039;, sys.argv[0]             &lt;br /&gt;
 pathname = os.path.dirname(sys.argv[0])        &lt;br /&gt;
 print &#039;path =&#039;, pathname&lt;br /&gt;
 print &#039;full path =&#039;, os.path.abspath(pathname)&lt;br /&gt;
&lt;br /&gt;
=== Environment Variables ===&lt;br /&gt;
&lt;br /&gt;
 import os&lt;br /&gt;
 a = os.environ.get(&#039;MYVAR&#039;)               # get environment var&lt;br /&gt;
 a = os.environ.get(&#039;MYVAR&#039;,&#039;default&#039;)     # get environment var&lt;br /&gt;
 a = os.environ[&#039;MYVAR&#039;]                   # get environment var&lt;br /&gt;
 os.environ[&#039;MYVAR&#039;] = &#039;something&#039;         # set environment var&lt;br /&gt;
 os.environ.update({&#039;MYVAR&#039;:&#039;something&#039;})  # set environment var&lt;br /&gt;
&lt;br /&gt;
 for env in os.environ:&lt;br /&gt;
   print &amp;quot;%s = %s&amp;quot; % (env, os.environ[env])&lt;br /&gt;
&lt;br /&gt;
 with open(&amp;quot;environment.txt&amp;quot;, &amp;quot;w&amp;quot;) as f:&lt;br /&gt;
   for env in os.environ:&lt;br /&gt;
      f.write(&amp;quot;%s = %s\n&amp;quot; % (env, os.environ[env]))&lt;br /&gt;
&lt;br /&gt;
=== PYTHONPATH ===&lt;br /&gt;
&lt;br /&gt;
Environment Search path:&lt;br /&gt;
 PYTHONPATH=...&lt;br /&gt;
&lt;br /&gt;
From Code:&lt;br /&gt;
 sys.path.append(&#039;...&#039;)&lt;br /&gt;
&lt;br /&gt;
Get site-package directory from shell: [http://stackoverflow.com/questions/122327/how-do-i-find-the-location-of-my-python-site-packages-directory]&lt;br /&gt;
 python -c &amp;quot;from distutils.sysconfig import get_python_lib; print(get_python_lib())&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Import and Modules ===&lt;br /&gt;
&lt;br /&gt;
Import and Modules - http://docs.python.org/tutorial/modules.html&lt;br /&gt;
&lt;br /&gt;
Import module:&lt;br /&gt;
 import package            # standard import&lt;br /&gt;
 import package.code       # nested name space&lt;br /&gt;
 from package import code  # import specifics from module&lt;br /&gt;
 import module             # standard import&lt;br /&gt;
 from math import sin      # import specifics from module&lt;br /&gt;
 from module import myfunc as fun1  # alias function/object&lt;br /&gt;
 import math as other_math # alias module&lt;br /&gt;
 import longname as ln     # alias module&lt;br /&gt;
 from module import *      # BAD BAD BAD!&lt;br /&gt;
&lt;br /&gt;
 import math&lt;br /&gt;
 math.pow(x,y)&lt;br /&gt;
&lt;br /&gt;
Group and organize by:&lt;br /&gt;
* stdlib libraries&lt;br /&gt;
* local libraries&lt;br /&gt;
* 3rd party libraries&lt;br /&gt;
&lt;br /&gt;
Remove import:&lt;br /&gt;
 del math&lt;br /&gt;
&lt;br /&gt;
 from math import *&lt;br /&gt;
 pow(x,y)&lt;br /&gt;
&lt;br /&gt;
 from math import pow&lt;br /&gt;
 pow(x,y)&lt;br /&gt;
&lt;br /&gt;
 import math as math_lib   # rename&lt;br /&gt;
 math_lib.pow(x,y)&lt;br /&gt;
&lt;br /&gt;
List functions in module:&lt;br /&gt;
 import math&lt;br /&gt;
 dir(math)&lt;br /&gt;
&lt;br /&gt;
List all built in functions:&lt;br /&gt;
 dir(__builtins__)&lt;br /&gt;
&lt;br /&gt;
Note: Modules have the extension .py&lt;br /&gt;
&lt;br /&gt;
Simply module Example:&lt;br /&gt;
&lt;br /&gt;
 # mymod.py:&lt;br /&gt;
 def hello():&lt;br /&gt;
   &amp;quot;&amp;quot;&amp;quot; this is a doc string &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
   print &amp;quot;Hello World&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 # Use the module:&lt;br /&gt;
 import mymod&lt;br /&gt;
 mymod.hello():&lt;br /&gt;
&lt;br /&gt;
 # Use everything in the the module, except for names beginning with &#039;_&#039;:  (bad practice!)&lt;br /&gt;
 from mymod import *&lt;br /&gt;
 hello()&lt;br /&gt;
&lt;br /&gt;
 # Use specific functions in the module:&lt;br /&gt;
 from mymod import hello, hi&lt;br /&gt;
 hello()&lt;br /&gt;
&lt;br /&gt;
 # Function assignment:&lt;br /&gt;
 h = mymod.hello&lt;br /&gt;
 h()&lt;br /&gt;
&lt;br /&gt;
 # module name&lt;br /&gt;
 mymod.__name__   # mymod&lt;br /&gt;
 __name__         # used inside of module will print current module or &amp;quot;__main__&amp;quot; if directly called&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Note: careful when building own modules, as the import literally imports and executes the code, so any code not in functions is executed!&lt;br /&gt;
&lt;br /&gt;
Check if being called directly or indirectly:&lt;br /&gt;
 if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
   # execute tests...&lt;br /&gt;
&lt;br /&gt;
Standard Script Setup:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def main(args):&lt;br /&gt;
  # do logic&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
  sys.exit(main(sys.argv))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Easter egg:&lt;br /&gt;
 # The Zen of Python&lt;br /&gt;
 import this&lt;br /&gt;
&lt;br /&gt;
Search path:&lt;br /&gt;
* environment variable &#039;PYTHONPATH&#039;   (on Unix, this is usually .:/usr/local/lib/python)&lt;br /&gt;
* sys.path  (list of paths, initialized to PYTHONPATH)&lt;br /&gt;
** sys.path.append(&#039;path&#039;)&lt;br /&gt;
&lt;br /&gt;
Module folder: [http://stackoverflow.com/questions/391879/organising-my-python-project] [http://stackoverflow.com/questions/279237/python-import-a-module-from-a-folder] [http://stackoverflow.com/questions/72852/how-to-do-relative-imports-in-python]&lt;br /&gt;
 /kenlib/kenmod.py&lt;br /&gt;
 # so you can do &amp;quot;import kenlib.kenmod&amp;quot;&lt;br /&gt;
 # create file &#039;__init__.py&#039; in kenlib/&lt;br /&gt;
&lt;br /&gt;
Check if package exists:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
try:&lt;br /&gt;
    import argparse&lt;br /&gt;
except ImportError:&lt;br /&gt;
    print &amp;gt;&amp;gt; sys.stderr, &amp;quot;Please install argparse from http://code.google.com/p/&lt;br /&gt;
argparse.&amp;quot;&lt;br /&gt;
    exit(1)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== ifmain ===&lt;br /&gt;
&lt;br /&gt;
 if __name__ == &#039;__main__&#039;:&lt;br /&gt;
     sys.exit(main(sys.argv))&lt;br /&gt;
&lt;br /&gt;
 if __name__ == &#039;__main__&#039;:&lt;br /&gt;
     sys.exit(main(sys.argv[1:]) or 0)&lt;br /&gt;
&lt;br /&gt;
=== Lists ===&lt;br /&gt;
&lt;br /&gt;
* Lists can be modified (mutable)&lt;br /&gt;
* Tuples are constant (immutable)&lt;br /&gt;
&lt;br /&gt;
List: (mutable or modifiable)&lt;br /&gt;
 x = []  # empty list&lt;br /&gt;
 x = [5] # singleton list&lt;br /&gt;
&lt;br /&gt;
 s = list(&amp;quot;Hello World&amp;quot;)&lt;br /&gt;
 print(s)  # s = [&#039;H&#039;, &#039;e&#039;, &#039;l&#039;, &#039;l&#039;, &#039;o&#039;, &#039; &#039;, &#039;W&#039;, &#039;o&#039;, &#039;r&#039;, &#039;l&#039;, &#039;d&#039;]&lt;br /&gt;
 s[0] = &#039;X&#039;&lt;br /&gt;
&lt;br /&gt;
 s.append(x)     # append x&lt;br /&gt;
 s.insert(i, x)  # insert x at i&lt;br /&gt;
 del(s[i])       # delete item at i&lt;br /&gt;
 s.sort()        # sort (modify in place!)&lt;br /&gt;
 s.reverse()     # reverse&lt;br /&gt;
 s.index(x)      # index of x in s&lt;br /&gt;
 new = old[:]    # create copy of list&lt;br /&gt;
 new = list(old) # create copy of list&lt;br /&gt;
&lt;br /&gt;
Check if item in list:&lt;br /&gt;
 if x in s: ...&lt;br /&gt;
&lt;br /&gt;
Filter list of strings based on contents: [https://stackoverflow.com/questions/2152898/filtering-a-list-of-strings-based-on-contents]&lt;br /&gt;
 res = [k for k in lst if &#039;ab&#039; in k]&lt;br /&gt;
&lt;br /&gt;
List comprehension&lt;br /&gt;
 [n * n for n in range(1, 11)]   # squares of numbers 1 to 10&lt;br /&gt;
 [c for c in &#039;pizza&#039;]            # list of string &#039;pizza&#039;&lt;br /&gt;
 [c.upper() for c in &#039;pizza&#039;]    # list of string &#039;pizza&#039; uppercase&lt;br /&gt;
 [n for n in nums if n &amp;gt; 0]      # filters out only positive numbers in nums list&lt;br /&gt;
 [fname for fname in os.listdir(path)  # on multiple lines&lt;br /&gt;
    if os.path.isfile(fname)&lt;br /&gt;
    if fname.endswith(&#039;.py&#039;)]&lt;br /&gt;
&lt;br /&gt;
Enumeration&lt;br /&gt;
 for index, value in enumerate(mylist):  print index, value&lt;br /&gt;
&lt;br /&gt;
Length:&lt;br /&gt;
 len(x)&lt;br /&gt;
&lt;br /&gt;
Concatenation:&lt;br /&gt;
 x + s&lt;br /&gt;
 x * 2&lt;br /&gt;
&lt;br /&gt;
Convert list to string:&lt;br /&gt;
 &amp;quot;&amp;quot;.join(mylist)  # no separator&lt;br /&gt;
 &amp;quot; &amp;quot;.join(mylist) # space separator&lt;br /&gt;
 &amp;quot;,&amp;quot;.join(mylist) # comma separator&lt;br /&gt;
&lt;br /&gt;
Test Membership&lt;br /&gt;
 x in s&lt;br /&gt;
&lt;br /&gt;
Multi dimensional list:&lt;br /&gt;
 mylist = [ [0,&amp;quot;hi&amp;quot;], [1,&amp;quot;bye&amp;quot;] ]&lt;br /&gt;
 print( mylist[0][1] )&lt;br /&gt;
&lt;br /&gt;
Sorting: (see lambda)&lt;br /&gt;
 data.sort()  # alpha numerica sort&lt;br /&gt;
 data.reverse()  # alpha numerica sort&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# custom sort&lt;br /&gt;
data = [1, 5, 3, 9]&lt;br /&gt;
def mylistcmp(x, y):&lt;br /&gt;
  if x == y: return 0&lt;br /&gt;
  if x &amp;lt; y:&lt;br /&gt;
    return -1&lt;br /&gt;
  else:  # swap 1 and -1 here to reverse&lt;br /&gt;
    return 1&lt;br /&gt;
&lt;br /&gt;
data.sort(cmp=mylistcmp)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Slices:&lt;br /&gt;
 lst = [&#039;1a&#039;, &#039;2b&#039;, &#039;3c&#039;, &#039;4d&#039;, &#039;5e&#039;, &#039;6f&#039;]&lt;br /&gt;
 lst[0]     # &#039;1a&#039;&lt;br /&gt;
 lst[-1]    # &#039;6f&#039; last item&lt;br /&gt;
 lst[0:2]   # [&#039;1a&#039;, &#039;2b&#039;]&lt;br /&gt;
 lst[0:2] = [&#039;11&#039;, &#039;22&#039;]   # lst = [&#039;11&#039;, &#039;22&#039;, &#039;3c&#039;, &#039;4d&#039;, &#039;5e&#039;, &#039;6f&#039;] - assignment to slice&lt;br /&gt;
 lst[0:2] = []   # remove items&lt;br /&gt;
 lst[0:0] = [&#039;1a&#039;, &#039;2b&#039;]   # insert items (at beginning)&lt;br /&gt;
 lst[-1:-1] = [&#039;7g&#039;, &#039;8h&#039;]   # insert items (at item BEFORE last), not really what you want, use append()&lt;br /&gt;
 lst[-1:] = [&#039;7g&#039;, &#039;8h&#039;]   # replace last item&lt;br /&gt;
 lst[:] = []   # clear entire list&lt;br /&gt;
 del(lst[0:2])  # delete slice items&lt;br /&gt;
&lt;br /&gt;
Note: it is not safe to modify a sequence while being iterated over.  Create a copy first:&lt;br /&gt;
 for x in mylst[:]:  # make a slice copy of the entire list&lt;br /&gt;
   if len(x) &amp;gt; 6: a.insert(0,x)&lt;br /&gt;
&lt;br /&gt;
Make list from tuple:&lt;br /&gt;
 list( range(10) )&lt;br /&gt;
&lt;br /&gt;
Merge multiple lists: [http://www.testingreflections.com/node/view/4930]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def merge(seq):&lt;br /&gt;
    merged = []&lt;br /&gt;
    for s in seq:&lt;br /&gt;
        for x in s:&lt;br /&gt;
            merged.append(x)&lt;br /&gt;
    return merged&lt;br /&gt;
&lt;br /&gt;
# sample usage:&lt;br /&gt;
foo = [[&#039;a&#039;, &#039;b&#039;],[&#039;c&#039;],[&#039;d&#039;, &#039;e&#039;, &#039;f&#039;]]&lt;br /&gt;
print merge(foo)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt;[&#039;a&#039;, &#039;b&#039;, &#039;c&#039;, &#039;d&#039;, &#039;e&#039;, &#039;f&#039;]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Tuple ===&lt;br /&gt;
&lt;br /&gt;
Tuple: (immutable or constant)&lt;br /&gt;
 x = ()    # empty tuple&lt;br /&gt;
 x = (5,)  # singleton tuple&lt;br /&gt;
 x = (5)   # NOTE: integer with parenthesis, not tuple&lt;br /&gt;
 &lt;br /&gt;
 s = tuple(&amp;quot;Hello World&amp;quot;)&lt;br /&gt;
 print(s)  # s = (&#039;H&#039;, &#039;e&#039;, &#039;l&#039;, &#039;l&#039;, &#039;o&#039;, &#039; &#039;, &#039;W&#039;, &#039;o&#039;, &#039;r&#039;, &#039;l&#039;, &#039;d&#039;)&lt;br /&gt;
 # ERROR: s[0] = &#039;X&#039;&lt;br /&gt;
&lt;br /&gt;
Make list from tuple:&lt;br /&gt;
 list( range(10) )&lt;br /&gt;
&lt;br /&gt;
Use in conditionals:&lt;br /&gt;
 if answer in (&#039;y&#039;, &#039;ye&#039;, &#039;yes&#039;): ...&lt;br /&gt;
&lt;br /&gt;
Convert tuple string to tuple: [http://stackoverflow.com/questions/3945856/converting-string-to-tuple-and-adding-to-tuple]&lt;br /&gt;
 x = &amp;quot;(1,2,3)&amp;quot;&lt;br /&gt;
 t = tuple(int(v) for v in re.findall(&amp;quot;[0-9]+&amp;quot;, x))&lt;br /&gt;
&lt;br /&gt;
Another Convert tuple string to tuple: [http://stackoverflow.com/questions/3945856/converting-string-to-tuple-and-adding-to-tuple]&lt;br /&gt;
 import ast&lt;br /&gt;
 ast.literal_eval(&amp;quot;(1,2,3,4)&amp;quot;) # (1,2,3,4)&lt;br /&gt;
&lt;br /&gt;
=== Named Tuple ===&lt;br /&gt;
&lt;br /&gt;
What are &amp;quot;named tuples&amp;quot; in Python? - Stack Overflow - http://stackoverflow.com/questions/2970608/what-are-named-tuples-in-python&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from collections import namedtuple&lt;br /&gt;
Point = namedtuple(&#039;Point&#039;, &#039;x y&#039;)&lt;br /&gt;
pt1 = Point(1.0, 5.0)&lt;br /&gt;
pt2 = Point(2.5, 1.5)&lt;br /&gt;
print p1     # point(x=1, y=5)&lt;br /&gt;
print p1.x   # 1.0&lt;br /&gt;
print p1[0]  # 1.0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Dictionary ===&lt;br /&gt;
&lt;br /&gt;
NOTE: Dictionaries are also known as associative arrays, maps or hash tables.&lt;br /&gt;
&lt;br /&gt;
Dictionary: (mutable or modifiable)&lt;br /&gt;
&lt;br /&gt;
 color = {}                      # empty dictionary&lt;br /&gt;
 color = {&#039;red&#039; : 1, &#039;blue&#039;, 2}&lt;br /&gt;
 print( color[&#039;red&#039;] )           # 1&lt;br /&gt;
 print( color.get(&#039;red&#039;) )       # 1&lt;br /&gt;
 print( color.get(&#039;red&#039;, &#039;default&#039;) )       # red if found, or return &#039;default&#039;&lt;br /&gt;
 color[&#039;green&#039;] = 3              # able to add new item on the fly!&lt;br /&gt;
 &#039;red&#039; in color                  # True - check if index exists&lt;br /&gt;
 del(color[&amp;quot;red&amp;quot;])               # delete item&lt;br /&gt;
 len(color)                      # 2 - count of items&lt;br /&gt;
&lt;br /&gt;
List in dictionary&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
d.setdefault(key,[]).append(member)  # tricky!&lt;br /&gt;
&lt;br /&gt;
# more tricky: set default type as list&lt;br /&gt;
from from collections import defaultdict&lt;br /&gt;
d = defaultdict(list)&lt;br /&gt;
d[key].append(member)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Enumeration:&lt;br /&gt;
 for index, key in enumerate(mylist):  print index, key&lt;br /&gt;
&lt;br /&gt;
functions:&lt;br /&gt;
 d.clear()&lt;br /&gt;
 d.copy()&lt;br /&gt;
 d.get(key)&lt;br /&gt;
 d.get(key, default_val)&lt;br /&gt;
 d.update(e)   # update with (key, value) pairs in e&lt;br /&gt;
 d.setdefault(key, value)  # only update if not exist, and return set value&lt;br /&gt;
&lt;br /&gt;
Views: (adjust on the fly as dictionary changes)&lt;br /&gt;
 d.items()  (key, values)&lt;br /&gt;
 for k, v in d.items(): print(k, v)&lt;br /&gt;
 &lt;br /&gt;
 d.keys()&lt;br /&gt;
 for k in d.keys(): print(k)&lt;br /&gt;
 &lt;br /&gt;
 d.values()&lt;br /&gt;
 for v in d.values(): print(v)&lt;br /&gt;
&lt;br /&gt;
Sorting: (see also lambda)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# custom sort of dictionaries in list&lt;br /&gt;
data = [dict(number=x) for x in &#039;036149&#039;]  # create list of dictionaries&lt;br /&gt;
def mydictcmp(x, y):&lt;br /&gt;
  if x[&#039;number&#039;] == y[&#039;number&#039;]: return 0&lt;br /&gt;
  if x[&#039;number&#039;] &amp;lt; y[&#039;number&#039;]:&lt;br /&gt;
    return -1&lt;br /&gt;
  else:  # swap 1 and -1 here to reverse&lt;br /&gt;
    return 1&lt;br /&gt;
&lt;br /&gt;
# data.sort(cmp=mydictcmp)  # modifies data&lt;br /&gt;
&lt;br /&gt;
new_data = sorted(data, cmp=mydictcmp)  # better solution&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sorting:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
my_dict = {&#039;a&#039;:1, &#039;b&#039;:4, &#039;c&#039;:3, &#039;d&#039;:9}&lt;br /&gt;
my_dict_keys = my_dict.keys()&lt;br /&gt;
&lt;br /&gt;
def my_dict_sort(x, y):&lt;br /&gt;
    if my_dict[x] == my_dict[y]: return 0&lt;br /&gt;
    if my_dict[x] &amp;lt; my_dict[y]: return -1&lt;br /&gt;
    if my_dict[x] &amp;gt; my_dict[y]: return 1&lt;br /&gt;
&lt;br /&gt;
#sorted_my_dict = sorted(my_dict_keys, cmp=my_dict_sort, reverse=True)&lt;br /&gt;
sorted_tuple = sorted(my_dict_keys, cmp=my_dict_sort)&lt;br /&gt;
print &amp;quot;Sorted Dictionary:&amp;quot;&lt;br /&gt;
for key in sorted_tuple:&lt;br /&gt;
    print &amp;quot;%s: %d&amp;quot; % (key, my_dict[key])&lt;br /&gt;
&lt;br /&gt;
# a: 1, c: 3, b: 4, d: 9,&lt;br /&gt;
# reverse: d: 9, b: 4, c: 3, a: 1,&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sort and keys:&lt;br /&gt;
 keys = sorted(mydict.keys())&lt;br /&gt;
&lt;br /&gt;
Sort by value: [http://stackoverflow.com/questions/613183/python-sort-a-dictionary-by-value]&lt;br /&gt;
 import operator&lt;br /&gt;
 x = {1: 2, 3: 4, 4:3, 2:1, 0:0}&lt;br /&gt;
 sorted_x = sorted(x.iteritems(), key=operator.itemgetter(1))&lt;br /&gt;
&lt;br /&gt;
Sort options:&lt;br /&gt;
 # LIST.sort(cmp=None, key=None, reverse=False) -- stable sort *IN PLACE*;&lt;br /&gt;
 # sorted(iterable, cmp=None, key=None, reverse=False)&lt;br /&gt;
&lt;br /&gt;
Another: (works well!)&lt;br /&gt;
 sorted(my_dict.items(), key=lambda x: x[1])&lt;br /&gt;
&lt;br /&gt;
See: http://wiki.python.org/moin/HowTo/Sorting/&lt;br /&gt;
&lt;br /&gt;
=== Sets ===&lt;br /&gt;
&lt;br /&gt;
Sets are special lists with unique values (good for removing duplicates)&lt;br /&gt;
 lst = [1, 1, 6, 8, 1, 5]&lt;br /&gt;
 s = set(lst)&lt;br /&gt;
 print(s)  # set([8, 1, 5, 6])&lt;br /&gt;
 s.add(item)&lt;br /&gt;
 item in s  # true&lt;br /&gt;
 s.remove(item)&lt;br /&gt;
&lt;br /&gt;
Union (return combination of all):&lt;br /&gt;
 s.union(t)&lt;br /&gt;
&lt;br /&gt;
Intersection (return matching):&lt;br /&gt;
 s.intersection(t)&lt;br /&gt;
&lt;br /&gt;
Symmetric Difference (return only items not matching either, inverse of intersection):&lt;br /&gt;
 s.symmetric_difference(t)&lt;br /&gt;
 list( set(mylist).symmetric_difference(set(mylist2)) )&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Operation		   Equivalent	Result&lt;br /&gt;
len(s) 	  				cardinality of set s&lt;br /&gt;
x in s 	  				test x for membership in s&lt;br /&gt;
x not in s 	  			test x for non-membership in s&lt;br /&gt;
s.issubset(t) 		   s &amp;lt;= t       test whether every element in s is in t&lt;br /&gt;
s.issuperset(t) 	   s &amp;gt;= t 	test whether every element in t is in s&lt;br /&gt;
s.union(t) 		   s | t 	new set with elements from both s and t&lt;br /&gt;
s.intersection(t)	   s &amp;amp; t 	new set with elements common to s and t&lt;br /&gt;
s.difference(t) 	   s - t	new set with elements in s but not in t&lt;br /&gt;
s.symmetric_difference(t)  s ^ t 	new set with elements in either s or t but not both&lt;br /&gt;
s.copy() 	  			new set with a shallow copy of s&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* sets — Unordered collections of unique elements - http://docs.python.org/library/sets.html&lt;br /&gt;
&lt;br /&gt;
=== Files ===&lt;br /&gt;
&lt;br /&gt;
Open file, get file descriptor:&lt;br /&gt;
 fd = open(&#039;/dev/null&#039;)&lt;br /&gt;
&lt;br /&gt;
File Modes:&lt;br /&gt;
 &#039;r&#039; read (default)&lt;br /&gt;
 &#039;w&#039; write (truncate and create if needed)&lt;br /&gt;
 &#039;a&#039; append (create if needed)&lt;br /&gt;
 &lt;br /&gt;
 &#039;b&#039; binary&lt;br /&gt;
 &#039;t&#039; text (default)&lt;br /&gt;
 &lt;br /&gt;
 &#039;+&#039; read and write&lt;br /&gt;
&lt;br /&gt;
Common Functions: (fd)&lt;br /&gt;
&lt;br /&gt;
 f.read()       # read whole file to string&lt;br /&gt;
 f.read(n)      # read n bytes from file to string&lt;br /&gt;
 f.readline()   # read single line as string (while loop)&lt;br /&gt;
 f.readlines()  # read all lines to list&lt;br /&gt;
&lt;br /&gt;
 f.write(str)   # write string to file (does not auto include new line)&lt;br /&gt;
 f.writelines(list)  # write list to file (does not auto include new lines)&lt;br /&gt;
&lt;br /&gt;
 f.seek(0)      # seek to start of file&lt;br /&gt;
 f.seek(pos)    # seek to position&lt;br /&gt;
 f.truncate()   # truncate file&lt;br /&gt;
&lt;br /&gt;
 f.close()      # close file (fd)&lt;br /&gt;
 f.closed       # True/False flag that reports if file is closed&lt;br /&gt;
&lt;br /&gt;
Help:&lt;br /&gt;
 help(open(&#039;/dev/null&#039;))&lt;br /&gt;
 pydoc file&lt;br /&gt;
&lt;br /&gt;
Read Text File Line by Line&lt;br /&gt;
 f = open(fname, &#039;r&#039;)  # (&#039;r&#039; optional)&lt;br /&gt;
 for line in f:  # or f.readlines()&lt;br /&gt;
   print(line)&lt;br /&gt;
 f.close()  # optional&lt;br /&gt;
&lt;br /&gt;
Write list to file (with new lines):&lt;br /&gt;
 f.writelines(&#039;\n&#039;.join(mylist))&lt;br /&gt;
&lt;br /&gt;
One liner read whole file:&lt;br /&gt;
 print( open( fname, &#039;r&#039; ).read() )&lt;br /&gt;
&lt;br /&gt;
Write text file:&lt;br /&gt;
 # f = open(fname, &#039;a&#039;)  # append text file&lt;br /&gt;
 f = open(fname, &#039;w&#039;)&lt;br /&gt;
 f.write(&amp;quot;Hello\n&amp;quot;)&lt;br /&gt;
 f.write( str(10) )  # convert numbers to strings first&lt;br /&gt;
 f.writelines([&amp;quot;line one\n&amp;quot;, &amp;quot;line two\n&amp;quot;])&lt;br /&gt;
 f.close&lt;br /&gt;
&lt;br /&gt;
Read binary file:&lt;br /&gt;
 def is_gif(fname):&lt;br /&gt;
   f = open(fname, &#039;br&#039;)  # not sure &#039;b&#039; is correct&lt;br /&gt;
   first4 = tuple(f.read(4))&lt;br /&gt;
   return first4 == (0x47, 0x49, 0x46, 0x38)&lt;br /&gt;
&lt;br /&gt;
Read all characters of file:&lt;br /&gt;
 c = f.read(1)&lt;br /&gt;
 while c:&lt;br /&gt;
   # if c == ... logic&lt;br /&gt;
   c = f.read(1)&lt;br /&gt;
&lt;br /&gt;
Reading file in while loop: [http://ubuntuforums.org/showthread.php?t=1092300]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
f=open(&amp;quot;file&amp;quot;)&lt;br /&gt;
while True:&lt;br /&gt;
  line=f.readline()&lt;br /&gt;
  if not line: break&lt;br /&gt;
  print line  &lt;br /&gt;
f.close()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
with - implicit close - [http://www.python.org/dev/peps/pep-0343/ PEP 343 -- The &amp;quot;with&amp;quot; Statement]: [http://docs.python.org/reference/compound_stmts.html#the-with-statement] (python &amp;gt;= 2.5)&lt;br /&gt;
 with open(&amp;quot;/etc/passwd&amp;quot;) as f:&lt;br /&gt;
   # ..., f.read(), etc&lt;br /&gt;
&lt;br /&gt;
With statement: (promptly close open handle at end of block)&lt;br /&gt;
 with open(fname, &#039;r&#039;) as f:&lt;br /&gt;
   for ...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# eqivalent to:&lt;br /&gt;
f = open(&amp;quot;/etc/passwd&amp;quot;)&lt;br /&gt;
f.__enter__()&lt;br /&gt;
try:&lt;br /&gt;
  ...&lt;br /&gt;
finally:&lt;br /&gt;
  f.__exit__()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
cat: (for grabbing a configuration line)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def cat(filename):&lt;br /&gt;
    with open(filename) as f:&lt;br /&gt;
        return f.readline().strip()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== With ===&lt;br /&gt;
&lt;br /&gt;
PEP 343 -- The &amp;quot;with&amp;quot; Statement - http://www.python.org/dev/peps/pep-0343/&lt;br /&gt;
&lt;br /&gt;
&#039;with&#039; structure:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
with EXPR as VAR:&lt;br /&gt;
  BLOCK&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
translates to:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
VAR = EXPR&lt;br /&gt;
VAR.__enter__()&lt;br /&gt;
try:&lt;br /&gt;
  BLOCK&lt;br /&gt;
finally:&lt;br /&gt;
  VAR.__exit__()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: The &amp;quot;as VAR&amp;quot; part is optional.  Good for locking:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
with locking(myLock):&lt;br /&gt;
  BLOCK&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
with - implicit close - [http://www.python.org/dev/peps/pep-0343/ PEP 343 -- The &amp;quot;with&amp;quot; Statement]: [http://docs.python.org/reference/compound_stmts.html#the-with-statement] (python &amp;gt;= 2.5)&lt;br /&gt;
 with open(&amp;quot;/etc/passwd&amp;quot;) as f:&lt;br /&gt;
   ...&lt;br /&gt;
&lt;br /&gt;
With statement: (promptly close open handle at end of block)&lt;br /&gt;
 with open(fname, &#039;r&#039;) as f:&lt;br /&gt;
   for ...&lt;br /&gt;
&lt;br /&gt;
See also [[#Files]]&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* PEP 343 -- The &amp;quot;with&amp;quot; Statement - http://www.python.org/dev/peps/pep-0343/&lt;br /&gt;
* PEP 340 -- Anonymous Block Statements - http://www.python.org/dev/peps/pep-0340/&lt;br /&gt;
&lt;br /&gt;
=== Try Exception Handling ===&lt;br /&gt;
&lt;br /&gt;
Exception Handling - http://docs.python.org/release/2.6.6/tutorial/errors.html&lt;br /&gt;
&lt;br /&gt;
throw execption:&lt;br /&gt;
 raise [EXCEPTION]&lt;br /&gt;
 raise IOError(&amp;quot;This is a test!&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Catch exceptions:&lt;br /&gt;
 try:&lt;br /&gt;
 except ( [EXCEPTION], [EXCEPTION] ):&lt;br /&gt;
 except [EXCEPTION]:&lt;br /&gt;
 except [EXCEPTION] as err:  # use &amp;quot;[EXCEPTION], err&amp;quot; in python &amp;lt; 2.6&lt;br /&gt;
   print(&amp;quot;Error: {}&amp;quot;.format(err))&lt;br /&gt;
 except:&lt;br /&gt;
   raise   # reraise caught error that is not handled&lt;br /&gt;
 else:     # if no exception caught&lt;br /&gt;
 finally:  # always executed&lt;br /&gt;
&lt;br /&gt;
Note: Usually a good idea to re-raise exception if you don&#039;t handle it (just &#039;raise&#039;)&lt;br /&gt;
&lt;br /&gt;
General Exception: (all exceptions inherit from Exception)&lt;br /&gt;
 try:&lt;br /&gt;
   raise Exception(&#039;spam&#039;, &#039;eggs&#039;)&lt;br /&gt;
 except Exception as e:&lt;br /&gt;
   pass&lt;br /&gt;
&lt;br /&gt;
Custom Exception Class:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class MyError(Exception):&lt;br /&gt;
  &amp;quot;&amp;quot;&amp;quot;My Error Exception&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
class MyException(Exception):&lt;br /&gt;
    pass&lt;br /&gt;
&lt;br /&gt;
rasie MyError(&amp;quot;My Error&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class ValidationError(Exception):&lt;br /&gt;
    def __init__(self, message, Errors):&lt;br /&gt;
&lt;br /&gt;
        # Call the base class constructor with the parameters it needs&lt;br /&gt;
        Exception.__init__(self, message)&lt;br /&gt;
&lt;br /&gt;
        # Now for your custom code...&lt;br /&gt;
        self.Errors = Errors&lt;br /&gt;
    def __str__(self):&lt;br /&gt;
        return &amp;quot;MyErrors - %s&amp;quot; % self.Errors&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Rename standard exception:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Failure(StandardError):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;Exception for unexpected failures.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: a good place to hide the exception classes in the __init__.py file.&lt;br /&gt;
&lt;br /&gt;
==== exception line number ====&lt;br /&gt;
&lt;br /&gt;
Python When I catch an exception, how do I get the type, file, and line number? - Stack Overflow [http://stackoverflow.com/questions/1278705/python-when-i-catch-an-exception-how-do-i-get-the-type-file-and-line-number]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import sys, os&lt;br /&gt;
&lt;br /&gt;
try:&lt;br /&gt;
    raise NotImplementedError(&amp;quot;No error&amp;quot;)&lt;br /&gt;
except Exception as e:&lt;br /&gt;
    exc_type, exc_obj, exc_tb = sys.exc_info()&lt;br /&gt;
    fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]&lt;br /&gt;
    print(exc_type, fname, exc_tb.tb_lineno)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== traceback ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import traceback&lt;br /&gt;
    try:&lt;br /&gt;
    ...&lt;br /&gt;
    except Exception as E:&lt;br /&gt;
        ...&lt;br /&gt;
        print &#039;Traceback: %s&#039;, traceback.format_exc()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Catching multiple exceptions and getting properties from the exception:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import traceback&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
class MyError(Exception):&lt;br /&gt;
  &amp;quot;&amp;quot;&amp;quot;My Error Exception&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
try:&lt;br /&gt;
  #raise ValueError(&amp;quot;a value error&amp;quot;)  # &amp;lt;type &#039;exceptions.ValueError&#039;&amp;gt;&lt;br /&gt;
  raise MyError(&amp;quot;a my error&amp;quot;)         # &amp;lt;class &#039;__main__.MyError&#039;&amp;gt;&lt;br /&gt;
  raise Exception(&amp;quot;won&#039;t be caught&amp;quot;)  # &amp;lt;type &#039;exceptions.Exception&#039;&amp;gt;&lt;br /&gt;
except (ValueError, MyError) as e:&lt;br /&gt;
  print type(e)       # &amp;lt;class &#039;__main__.MyError&#039;&amp;gt;&lt;br /&gt;
  print e             # __str__() = a my error&lt;br /&gt;
  msg = str(e)        # msg = &#039;a my error&#039;&lt;br /&gt;
  print e.__doc__     # My Error Exception&lt;br /&gt;
  print e.__str__()   # a my error&lt;br /&gt;
  print e.__repr__()  # MyError(&#039;a my error&#039;,)&lt;br /&gt;
  print e.args        # (&#039;a my error&#039;,)&lt;br /&gt;
  x = e               # __getitem__() allows args to be unpacked directly&lt;br /&gt;
  # x, y = e          # if two args were passed, use len(e.args) to see count&lt;br /&gt;
&lt;br /&gt;
  # manually print stack trace (import traceback, sys)&lt;br /&gt;
  print &amp;quot;Exception in user code:&amp;quot;&lt;br /&gt;
  print &#039;-&#039;*60&lt;br /&gt;
  traceback.print_exc(file=sys.stdout)&lt;br /&gt;
  # stack_trace = traceback.format_exc()&lt;br /&gt;
  print &#039;-&#039;*60&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Object Oriented Programming ===&lt;br /&gt;
&lt;br /&gt;
Terms:&lt;br /&gt;
* encapsulates&lt;br /&gt;
* inheritance&lt;br /&gt;
* polymorphism&lt;br /&gt;
* method overriding&lt;br /&gt;
&lt;br /&gt;
==== class ====&lt;br /&gt;
&lt;br /&gt;
class animal.py:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Animal(object):  # default &amp;quot;(object)&amp;quot; not required&lt;br /&gt;
  &amp;quot; Animal class &amp;quot;&lt;br /&gt;
  def __init__(self, name):&lt;br /&gt;
    self.name = name       # name is private variable&lt;br /&gt;
    self.__iam = &amp;quot;animal&amp;quot;  # __iam is private variable&lt;br /&gt;
  def __str__(self):       # string representation&lt;br /&gt;
    return &amp;quot;name = &#039;%s&#039;&amp;quot; % (self.name)&lt;br /&gt;
  def __repr__(self):      # object representation (just typing instance in IDLE, or repr())&lt;br /&gt;
    return &#039;Animal(%s)&#039; % str(self)  # returns __str__&lt;br /&gt;
  def speak(self, msg=&#039;Nothing to say&#039;):&lt;br /&gt;
    print(msg)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: if no __str__ defined, but __repr__ is, then:  __str__ = __repr__&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from animal import Animal&lt;br /&gt;
a = Animal(&#039;good&#039;)&lt;br /&gt;
print(a.__doc__)  # Animal class&lt;br /&gt;
print(a)          # name = &#039;good&#039;&lt;br /&gt;
a                 # Animal(name = &#039;good&#039;)&lt;br /&gt;
print(a.name)     # good&lt;br /&gt;
a.speak(&#039;hi&#039;)     # hi&lt;br /&gt;
print(a._Animal__iam)  # animal - access to private variable (shouldn&#039;t do)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
subclass dog.py:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from animal import Animal&lt;br /&gt;
class Dog(Animal):&lt;br /&gt;
  &amp;quot; Dog class &amp;quot;&lt;br /&gt;
  def __init__(self, name):&lt;br /&gt;
    self.name = name      # name is private variable&lt;br /&gt;
    self.__iam = &amp;quot;dog&amp;quot;    # __iam is private variable&lt;br /&gt;
  # NOTICE: no __str__, inherited from super class&lt;br /&gt;
  def __repr__(self):     # override to reflect &amp;quot;dog&amp;quot;&lt;br /&gt;
    return &#039;Dog(%s)&#039; % str(self)  # returns __str__&lt;br /&gt;
  def speak(self, msg=&#039;Nothing to say&#039;):   # override method&lt;br /&gt;
    super(Dog, self).speak(&#039;Dog says: &#039; + msg)     # call super class method&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Subclass usage:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from dog import Dog&lt;br /&gt;
d = Dog(&#039;bad&#039;)&lt;br /&gt;
print(d.__doc__)    # Dog class&lt;br /&gt;
print(d)            # name = &#039;bad&#039;&lt;br /&gt;
d                   # Dog(name = &#039;bad&#039;)&lt;br /&gt;
print(d.name)       # bad&lt;br /&gt;
d.speak(&#039;hi&#039;)       # Dog says: hi&lt;br /&gt;
print(d._Dog__iam)  # dog - access to private variable (shouldn&#039;t do)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Super: [http://stackoverflow.com/questions/576169/understanding-python-super-with-init-methods]&lt;br /&gt;
 # python 3.0&lt;br /&gt;
 super().__init__()&lt;br /&gt;
&lt;br /&gt;
 # python 2.7&lt;br /&gt;
 super(self.__class__, self).__init__()&lt;br /&gt;
 super([CLASSNAME], self).__init__()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Rectangle(Polygon):&lt;br /&gt;
    def __init__(self, id, width, height):&lt;br /&gt;
        #  super(Rectangle, self).__init__(id)&lt;br /&gt;
        super(self.__class__, self).__init__(id)&lt;br /&gt;
        self.shape = (width, height)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Get class name:&lt;br /&gt;
 self.__class__.__name__&lt;br /&gt;
 obj.__class__.__name__&lt;br /&gt;
&lt;br /&gt;
Full name:&lt;br /&gt;
 obj.__module__ + &amp;quot;.&amp;quot; + obj.__class__.__name__&lt;br /&gt;
&lt;br /&gt;
Private variables: (uses name mangling)&lt;br /&gt;
  self.__age&lt;br /&gt;
  # direct access:  _classname__varname  (eg. p._Person__age = 44)&lt;br /&gt;
&lt;br /&gt;
Tests:&lt;br /&gt;
 isinstance(myobj, myclass)  # check if myobj is a class or subclass of myclass &lt;br /&gt;
 issubclass(A, B)  # check if A is subclass of B&lt;br /&gt;
 issubclass(Exception, BaseException)  # True&lt;br /&gt;
&lt;br /&gt;
Multiple Inheritance:  (methods searched in order)&lt;br /&gt;
 class DerviedClass(Base1, Base2, Base3):&lt;br /&gt;
   pass&lt;br /&gt;
&lt;br /&gt;
Standard startup script:&lt;br /&gt;
 class MyClass():&lt;br /&gt;
     ...&lt;br /&gt;
     @classmethod&lt;br /&gt;
     def main(cls, argv=None):&lt;br /&gt;
         ...&lt;br /&gt;
         # return cls() # creator&lt;br /&gt;
 if __name__ == &amp;quot;__main__&amp;quot;;&lt;br /&gt;
     sys.exit(MyClass.main(sys.argv))&lt;br /&gt;
&lt;br /&gt;
Raise an error if a method is not overridden (not implemented)&lt;br /&gt;
    def _get_dist(self):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Find linux disto. Implemented in subclasses.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        raise NotImplementedError&lt;br /&gt;
&lt;br /&gt;
==== Multiple Constructors ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Animal(object):&lt;br /&gt;
&lt;br /&gt;
  def __init__(self, name):&lt;br /&gt;
    self.name = name&lt;br /&gt;
&lt;br /&gt;
  @classmethod&lt;br /&gt;
  def create_fido(cls):&lt;br /&gt;
    return cls(&amp;quot;fido&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Descriptor Classes ====&lt;br /&gt;
&lt;br /&gt;
&amp;quot;In general, a descriptor is an object attribute with “binding behavior”, one whose attribute access has been overridden by methods in the descriptor protocol: __get__(), __set__(), and __delete__(). If any of those methods are defined for an object, it is said to be a descriptor.&amp;quot; [http://docs.python.org/2/reference/datamodel.html#implementing-descriptors]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
object.__get__(self, instance, owner)&lt;br /&gt;
&lt;br /&gt;
    Called to get the attribute of the owner class (class attribute access) or of an instance of that&lt;br /&gt;
    class (instance attribute access). owner is always the owner class, while instance is the instance&lt;br /&gt;
    that the attribute was accessed through, or None when the attribute is accessed through the owner.&lt;br /&gt;
    This method should return the (computed) attribute value or raise an AttributeError exception.&lt;br /&gt;
&lt;br /&gt;
object.__set__(self, instance, value)&lt;br /&gt;
&lt;br /&gt;
    Called to set the attribute on an instance instance of the owner class to a new value, value.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example: [http://stackoverflow.com/questions/3798835/understanding-get-and-set-and-python-descriptors]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Celsius(object):&lt;br /&gt;
    def __init__(self, value=0.0):&lt;br /&gt;
        self.value = float(value)&lt;br /&gt;
    def __get__(self, instance, owner):&lt;br /&gt;
        return self.value&lt;br /&gt;
    def __set__(self, instance, value):&lt;br /&gt;
        self.value = float(value)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
class Temperature(object):&lt;br /&gt;
    celsius = Celsius()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
t = Temperature()&lt;br /&gt;
t.celsius = 5    # calls Celsius.__set__&lt;br /&gt;
print t.celsius  # calls Celsius.__get__&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: Also appears in &#039;pydoc&#039; under &amp;quot;Data descriptors defined here&amp;quot; with object&#039;s docstring.  Trick: the __doc__ can be overridden in the __init__ method, which makes for dynamic docstrings!&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* Descriptor HowTo Guide — Python v2.7.5 documentation - http://docs.python.org/2/howto/descriptor.html&lt;br /&gt;
* 3.4.2.2. Implementing Descriptors¶ - 3. Data model — Python v2.7.5 documentation - http://docs.python.org/2/reference/datamodel.html#implementing-descriptors&lt;br /&gt;
&lt;br /&gt;
=== [http://docs.python.org/reference/simple_stmts.html#the-exec-statement exec code] ===&lt;br /&gt;
&lt;br /&gt;
DANGEROUS!&lt;br /&gt;
&lt;br /&gt;
Execute code in string:&lt;br /&gt;
 exec( &#039;print(&amp;quot;hi&amp;quot;)&#039; )&lt;br /&gt;
&lt;br /&gt;
Example of executing a startup script for IDLE:&lt;br /&gt;
 if os.path.isfile(&#039;.pythonrc.py&#039;): exec(open(&#039;.pythonrc.py&#039;).read())&lt;br /&gt;
&lt;br /&gt;
 import os&lt;br /&gt;
 filename = os.environ.get(&#039;PYTHONSTARTUP&#039;)&lt;br /&gt;
 if filename and os.path.isfile(filename):&lt;br /&gt;
   exec(open(filename).read())&lt;br /&gt;
&lt;br /&gt;
=== eval ===&lt;br /&gt;
&lt;br /&gt;
VERY DANGEROUS&lt;br /&gt;
&lt;br /&gt;
Will execute a string as though it were pure python code!&lt;br /&gt;
&lt;br /&gt;
 eval(&amp;quot;print &#039;hello&#039;&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
=== Common Header Format ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
__author__ = &amp;quot;software team&amp;quot;&lt;br /&gt;
__date__ =&amp;quot;$Feb 15, 2011 1:42:17 PM$&amp;quot;&lt;br /&gt;
__version__ = &amp;quot;1.1.0.441 bandelier@66d9fe1edf3e&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Next should be authorship information. This information should follow this format:&lt;br /&gt;
&lt;br /&gt;
__author__ = &amp;quot;Rob Knight, Gavin Huttley, and Peter Maxwell&amp;quot;&lt;br /&gt;
__copyright__ = &amp;quot;Copyright 2007, The Cogent Project&amp;quot;&lt;br /&gt;
__credits__ = [&amp;quot;Rob Knight&amp;quot;, &amp;quot;Peter Maxwell&amp;quot;, &amp;quot;Gavin Huttley&amp;quot;,&lt;br /&gt;
                    &amp;quot;Matthew Wakefield&amp;quot;]&lt;br /&gt;
__license__ = &amp;quot;GPL&amp;quot;&lt;br /&gt;
__version__ = &amp;quot;1.0.1&amp;quot;&lt;br /&gt;
__maintainer__ = &amp;quot;Rob Knight&amp;quot;&lt;br /&gt;
__email__ = &amp;quot;rob@spot.colorado.edu&amp;quot;&lt;br /&gt;
__status__ = &amp;quot;Production&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Source: Python Coding Guidelines - http://bayes.colorado.edu/PythonGuidelines.html&lt;br /&gt;
&lt;br /&gt;
These will show up in the help() like such:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Help on module test:&lt;br /&gt;
&lt;br /&gt;
NAME&lt;br /&gt;
    test&lt;br /&gt;
&lt;br /&gt;
FILE&lt;br /&gt;
    /home/kenneth/test.py&lt;br /&gt;
&lt;br /&gt;
FUNCTIONS&lt;br /&gt;
    test()&lt;br /&gt;
&lt;br /&gt;
DATA&lt;br /&gt;
    __author__ = &#039;test author&#039;&lt;br /&gt;
    __version__ = &#039;1.0&#039;&lt;br /&gt;
&lt;br /&gt;
VERSION&lt;br /&gt;
    1.0&lt;br /&gt;
&lt;br /&gt;
AUTHOR&lt;br /&gt;
    test author&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* Python: What is the common header format? - Stack Overflow - http://stackoverflow.com/questions/1523427/python-what-is-the-common-header-format&lt;br /&gt;
&lt;br /&gt;
=== Common Environment Variables ===&lt;br /&gt;
&lt;br /&gt;
 Command line and environment — Python v2.7.2 documentation - http://docs.python.org/using/cmdline.htm&lt;br /&gt;
&lt;br /&gt;
PYTHONUNBUFFERED&lt;br /&gt;
: If this is set to a non-empty string it is equivalent to specifying the -u option. [http://docs.python.org/using/cmdline.html#envvar-PYTHONUNBUFFERED]&lt;br /&gt;
: -u - Force stdin, stdout and stderr to be totally unbuffered. On systems where it matters, also put stdin, stdout and stderr in binary mode.&lt;br /&gt;
* See also stdout - Python output buffering - Stack Overflow - http://stackoverflow.com/questions/107705/python-output-buffering&lt;br /&gt;
 export PYTHONUNBUFFERED=1&lt;br /&gt;
 set PYTHONUNBUFFERED=1&lt;br /&gt;
&lt;br /&gt;
PYTHONVERBOSE&lt;br /&gt;
:If this is set to a non-empty string it is equivalent to specifying the -v option. If set to an integer, it is equivalent to specifying -v multiple times.&lt;br /&gt;
: -v - Print a message each time a module is initialized, showing the place (filename or built-in module) from which it is loaded.&lt;br /&gt;
 export PYTHONVERBOSE=1&lt;br /&gt;
 set PYTHONVERBOSE=1&lt;br /&gt;
&lt;br /&gt;
PYTHONPATH&lt;br /&gt;
: Augment the default search path for module files. The format is the same as the shell’s PATH: one or more directory pathnames separated by os.pathsep (e.g. colons on Unix or semicolons on Windows). Non-existent directories are silently ignored. [http://docs.python.org/using/cmdline.html#envvar-PYTHONPATH]&lt;br /&gt;
 export PYTHONPATH=/path1/:path2/&lt;br /&gt;
 set PYTHONPATH=C:\path1\;C:\path2\&lt;br /&gt;
&lt;br /&gt;
=== Queue ===&lt;br /&gt;
&lt;br /&gt;
Good for threading.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;The Queue module implements multi-producer, multi-consumer queues. It is especially useful in threaded programming when information must be exchanged safely between multiple threads. The Queue class in this module implements all the required locking semantics.&amp;quot; [http://docs.python.org/2/library/queue.html]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import Queue&lt;br /&gt;
&lt;br /&gt;
bucket = Queue.Queue()&lt;br /&gt;
bucket.put(&amp;quot;something&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
while True:&lt;br /&gt;
    try:&lt;br /&gt;
        item = bucket.get(block=False)&lt;br /&gt;
    except Queue.Empty:&lt;br /&gt;
        pass&lt;br /&gt;
    else:&lt;br /&gt;
        # do stuff with queue&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Important methods:&lt;br /&gt;
  Queue.qsize()&lt;br /&gt;
  Queue.empty()&lt;br /&gt;
  Queue.put(item[, block[, timeout]])&lt;br /&gt;
  Queue.get([block[, timeout]])&lt;br /&gt;
&lt;br /&gt;
-&lt;br /&gt;
&lt;br /&gt;
Example: http://docs.python.org/2/library/queue.html&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def worker():&lt;br /&gt;
    while True:&lt;br /&gt;
        item = q.get()&lt;br /&gt;
        do_work(item)&lt;br /&gt;
        q.task_done()&lt;br /&gt;
&lt;br /&gt;
q = Queue()&lt;br /&gt;
for i in range(num_worker_threads):&lt;br /&gt;
     t = Thread(target=worker)&lt;br /&gt;
     t.daemon = True&lt;br /&gt;
     t.start()&lt;br /&gt;
&lt;br /&gt;
for item in source():&lt;br /&gt;
    q.put(item)&lt;br /&gt;
&lt;br /&gt;
q.join()       # block until all tasks are done&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
-&lt;br /&gt;
&lt;br /&gt;
&amp;quot;The module implements three types of queue, which differ only in the order in which the entries are retrieved. In a FIFO queue, the first tasks added are the first retrieved. In a LIFO queue, the most recently added entry is the first retrieved (operating like a stack). With a priority queue, the entries are kept sorted (using the heapq module) and the lowest valued entry is retrieved first.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Queue Types:&lt;br /&gt;
  class Queue.Queue(maxsize=0)          # FIFO Queue&lt;br /&gt;
  class Queue.LifoQueue(maxsize=0)      # LIFO Queue&lt;br /&gt;
  class Queue.PriorityQueue(maxsize=0)  # Priority Queue&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* 8.10. Queue — A synchronized queue class — Python v2.7.5 documentation - http://docs.python.org/2/library/queue.html&lt;br /&gt;
&lt;br /&gt;
== Recipes ==&lt;br /&gt;
&lt;br /&gt;
=== Remove Numbers from String ===&lt;br /&gt;
&lt;br /&gt;
Using list comprehension: [http://stackoverflow.com/questions/12851791/removing-numbers-from-string]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
result = &#039;&#039;.join([i for i in s if not i.isdigit()])&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Using pattern matching:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; re.compile(r&#039;\D+&#039;).findall(&amp;quot;test 1234 test 1234&amp;quot;)&lt;br /&gt;
[&#039;test &#039;, &#039; test &#039;]&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; re.compile(r&amp;quot;\d&amp;quot;).sub(&amp;quot;&amp;quot;, &amp;quot;test 1234 test 1234&amp;quot;)&lt;br /&gt;
&#039;test  test &#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Retry Wrapper ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import functool&lt;br /&gt;
class SomethingRetry:&lt;br /&gt;
&lt;br /&gt;
    def retry_with_backoff(retries: int, base_delay: float, exceptions: tuple[type[Exception], ...] = (Exception,)) -&amp;gt; callable:&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Retries a function with exponential backoff, doubling on each attempt.&lt;br /&gt;
        Arguments:&lt;br /&gt;
            retries: Number of retry attempts.&lt;br /&gt;
            base_delay: Initial delay between retries in seconds.&lt;br /&gt;
            exceptions: Tuple of exceptions to catch and retry.&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
        def decorator(func):&lt;br /&gt;
            @functools.wraps(func)&lt;br /&gt;
            def wrapper(*args, **kwargs):&lt;br /&gt;
                for attempt in range(1, retries + 1):&lt;br /&gt;
                    try:&lt;br /&gt;
                        return func(*args, **kwargs)&lt;br /&gt;
                    except exceptions as e:&lt;br /&gt;
                        print(f&amp;quot;Warning: Attempt {attempt} failed with error: {e}&amp;quot;)&lt;br /&gt;
                        if attempt == retries:&lt;br /&gt;
                            print(&amp;quot;Error: All retry attempts failed.&amp;quot;)&lt;br /&gt;
                            raise&lt;br /&gt;
                        sleep_time = base_delay * (2 ** (attempt - 1))&lt;br /&gt;
                        print(f&amp;quot;Notice: Retrying in {sleep_time} seconds...&amp;quot;)&lt;br /&gt;
                        time.sleep(sleep_time)&lt;br /&gt;
            return wrapper&lt;br /&gt;
        return decorator&lt;br /&gt;
&lt;br /&gt;
    @retry_with_backoff(retries=6, base_delay=10, exceptions=(Exception,))&lt;br /&gt;
    def do_something(self, sample_param: str):&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Standard Libraries ==&lt;br /&gt;
&lt;br /&gt;
=== user input ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
line = raw_input()  # Python 2&lt;br /&gt;
# line = input()    # Python 2&lt;br /&gt;
line = input(&#039;What is your name: &#039;)&lt;br /&gt;
print(&amp;quot;: &amp;quot; + line.strip() + &amp;quot; :&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== sys - stdout stderr stdin ===&lt;br /&gt;
&lt;br /&gt;
STDOUT:&lt;br /&gt;
 import sys&lt;br /&gt;
 sys.stdout.write(&amp;quot;Hello &amp;quot;)  # does not write new line&lt;br /&gt;
 sys.stdout.write(&amp;quot;World\n&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
STDERR:&lt;br /&gt;
 import sys&lt;br /&gt;
 sys.stderr.write(&amp;quot;ERROR!\n&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
STDIN:&lt;br /&gt;
 import sys&lt;br /&gt;
 line = sys.stdin.readline()&lt;br /&gt;
&lt;br /&gt;
 line = input()   # use raw_input() in Python 2&lt;br /&gt;
 line = input(&#039;What is your name: &#039;)&lt;br /&gt;
 print(&amp;quot;: &amp;quot; + line.strip() + &amp;quot; :&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Read piped stdin line by line: [http://stackoverflow.com/questions/1450393/how-do-you-read-from-stdin-in-python]&lt;br /&gt;
 # cat /etc/passwd | ./readlines.py     # linux&lt;br /&gt;
 # type file.txt | python readlines.py  # windows&lt;br /&gt;
&lt;br /&gt;
 # fileinput.input() - returns fileinput object which is iterative&lt;br /&gt;
 import fileinput&lt;br /&gt;
 for line in fileinput.input():&lt;br /&gt;
     print(&amp;quot;: &amp;quot; + line + &amp;quot; :&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
 # sys.stdin.readlines() - returns list of strings&lt;br /&gt;
 import sys&lt;br /&gt;
 for line in sys.stdin.readlines():&lt;br /&gt;
     print(&amp;quot;: &amp;quot; + line + &amp;quot; :&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
 # sys.stdin - returns object which is iterative&lt;br /&gt;
 import sys&lt;br /&gt;
 for line in sys.stdin:&lt;br /&gt;
     print(&amp;quot;: &amp;quot; + line + &amp;quot; :&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
 # ugly while loop: [http://ubuntuforums.org/showthread.php?t=1092300]&lt;br /&gt;
 while True:&lt;br /&gt;
     try:&lt;br /&gt;
         s = raw_input(&amp;quot;Say something &amp;quot;)&lt;br /&gt;
     except EOFError:&lt;br /&gt;
         break&lt;br /&gt;
     print &amp;quot;: %s&amp;quot; % s&lt;br /&gt;
&lt;br /&gt;
Check if stdin has any waiting data: [http://stackoverflow.com/questions/3762881/how-do-i-check-if-stdin-has-some-data]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import sys&lt;br /&gt;
import select&lt;br /&gt;
&lt;br /&gt;
# if select.select([sys.stdin,],[],[],0.0)[0]:  # alternative old method&lt;br /&gt;
&lt;br /&gt;
if not sys.stdin.isatty():&lt;br /&gt;
    print &amp;quot;Have data!&amp;quot;&lt;br /&gt;
    print sys.stdin.readlines()&lt;br /&gt;
else:&lt;br /&gt;
    print &amp;quot;No data&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if len(sys.argv) &amp;gt; 1:&lt;br /&gt;
    message = &#039; &#039;.join(sys.argv[1:])&lt;br /&gt;
elif not sys.stdin.isatty():&lt;br /&gt;
    # read from pipe in&lt;br /&gt;
    message = sys.stdin.readline()&lt;br /&gt;
else:&lt;br /&gt;
    # read from user&lt;br /&gt;
    sys.stdout.write(&amp;quot;Message: &amp;quot;)&lt;br /&gt;
    message = raw_input().strip()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [http://docs.python.org/library/re.html Regular Expressions] ===&lt;br /&gt;
&lt;br /&gt;
Import:&lt;br /&gt;
 import re  # user regular expressions&lt;br /&gt;
&lt;br /&gt;
Match vs Search:&lt;br /&gt;
 re.match(&amp;quot;cde&amp;quot;, &amp;quot;abcdef&amp;quot;)  # no match (match searches beginning of string, first match)&lt;br /&gt;
 re.match(&amp;quot;abc&amp;quot;, &amp;quot;abcdef&amp;quot;)  # match (match searches beginning of string, first match)&lt;br /&gt;
 re.search(&amp;quot;cd&amp;quot;, &amp;quot;abcdef&amp;quot;)  # match (matches any location, first match)&lt;br /&gt;
&lt;br /&gt;
Both re.match() and re.search() return objects that are not intuitive to use.  You can check the object&#039;s group() method for what matched, but I prefer re.findall().&lt;br /&gt;
&lt;br /&gt;
Match:&lt;br /&gt;
 s = &#039;done&#039;&lt;br /&gt;
 if re.match(&#039;done|quit&#039;, s) != None  # True&lt;br /&gt;
&lt;br /&gt;
Search:&lt;br /&gt;
 s = &#039;done&#039;&lt;br /&gt;
 if re.search(&#039;do&#039;, s) != None  # True&lt;br /&gt;
&lt;br /&gt;
Replace:&lt;br /&gt;
 msg = &#039;jello world&#039;&lt;br /&gt;
 msg = re.sub(&#039;jello&#039;, &#039;hello&#039;, msg)&lt;br /&gt;
&lt;br /&gt;
For case intensive searches append 3rd parameter &amp;quot;re.I&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Find all:&lt;br /&gt;
 re.findall(&amp;quot;[a-z]+&amp;quot;, &amp;quot;aaa111bbb222&amp;quot;)       # [&#039;aaa&#039;, &#039;bbb&#039;]&lt;br /&gt;
 re.findall(&amp;quot;111([a-z]+)&amp;quot;, &amp;quot;aaa111bbb222&amp;quot;)  # [&#039;bbb&#039;]&lt;br /&gt;
 re.findall(&amp;quot;hello&amp;quot;, &amp;quot;HELLO&amp;quot;, re.I)         # [&#039;HELLO&#039;] - Case Insensitive&lt;br /&gt;
&lt;br /&gt;
Split:&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; re.split(&#039;[a-z]+&#039;,&#039;111aaa222bbb&#039;)&lt;br /&gt;
 [&#039;111&#039;, &#039;222&#039;, &#039;&#039;]&lt;br /&gt;
&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; re.split(&#039;([a-z]+)&#039;,&#039;111aaa222bbb&#039;)  # parenthesis cause return of all&lt;br /&gt;
 [&#039;111&#039;, &#039;aaa&#039;, &#039;222&#039;, &#039;bbb&#039;, &#039;&#039;]&lt;br /&gt;
&lt;br /&gt;
Replacement Substitution:&lt;br /&gt;
 # re.sub(pattern, repl, string[, count, flags])&lt;br /&gt;
 re.sub(r&#039;\\&#039;, r&#039;/&#039;, r&#039;\\data\files&#039;)&lt;br /&gt;
&lt;br /&gt;
Compiled regular express for repeated use: (performance)&lt;br /&gt;
 valid = re.compile(r&amp;quot;[0-9]+&amp;quot;)&lt;br /&gt;
 valid.match(&amp;quot;aaa111bbb&amp;quot;)               # not valid&lt;br /&gt;
 match = valid.search(&amp;quot;aaa111bbb222&amp;quot;)   # valid&lt;br /&gt;
 print(match.group())                   # what matched: &#039;111&#039;&lt;br /&gt;
&lt;br /&gt;
=== Date and Time ===&lt;br /&gt;
&lt;br /&gt;
Sleep in seconds:&lt;br /&gt;
 import time&lt;br /&gt;
 time.sleep(seconds)&lt;br /&gt;
&lt;br /&gt;
Use the following functions to convert between time representations:&lt;br /&gt;
&amp;lt;table border=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;From&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;To&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Use&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;seconds since the epoch&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;struct_time in UTC&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;gmtime()&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;seconds since the epoch&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;struct_time in local time&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;localtime()&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;struct_time in UTC&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;seconds since the epoch&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;calendar.timegm()&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;struct_time in local time&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;seconds since the epoch&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;mktime()&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Date formats:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; time.strftime(&amp;quot;%Y-%m-%d %H:%M:%S&amp;quot;, time.localtime())&lt;br /&gt;
&#039;2014-04-04 12:22:43&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; time.time()&lt;br /&gt;
1396635763.0581281&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; datetime.datetime.now()&lt;br /&gt;
datetime.datetime(2014, 4, 4, 12, 22, 43, 58456)&lt;br /&gt;
# datetime(year, month, day, hour, minute, second, microsecond)&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; time.localtime()&lt;br /&gt;
time.struct_time(tm_year=2014, tm_mon=4, tm_mday=4, tm_hour=12, tm_min=22, tm_sec=43, tm_wday=4, tm_yday=94, tm_isdst=1)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Current epoch time:&lt;br /&gt;
 int(time.time())&lt;br /&gt;
&lt;br /&gt;
Time zone offset:&lt;br /&gt;
 standard_tz_offset = - time.timezone / 3600  # 7&lt;br /&gt;
 daylight_tz_offset = - time.altzone / 3600  # 6&lt;br /&gt;
&lt;br /&gt;
Is daylight saving time: [http://stackoverflow.com/questions/2881025/python-daylight-savings-time]&lt;br /&gt;
 import time&lt;br /&gt;
 time.localtime()&lt;br /&gt;
 _.tm_isdst  # 0 or 1&lt;br /&gt;
&lt;br /&gt;
 mst_epoch_time = time.time()  # server in MST/MDT&lt;br /&gt;
 if time.localtime().tm_isdst:  # are we in daylight saving time?&lt;br /&gt;
   utc_epoch_time = mst_epoch_time + time.altzone&lt;br /&gt;
 else:&lt;br /&gt;
   utc_epoch_time = mst_epoch_time + time.timezone&lt;br /&gt;
&lt;br /&gt;
Format current time: [http://docs.python.org/2/library/time.html#time.strftime]&lt;br /&gt;
 time.strftime(&#039;%d%b%y&#039;)  # &#039;12May11&#039;&lt;br /&gt;
 time.strftime(&#039;%Y.%m.%d %H:%M:%S&#039;)  # &#039;2013.08.09 14:01:28&#039;&lt;br /&gt;
&lt;br /&gt;
Time conversions:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# epoch to str&lt;br /&gt;
epoch_time = time.time()    # 1375992088.7867229&lt;br /&gt;
dt = datetime.datetime.fromtimestamp( epoch_time )    # datetime.datetime(2013, 8, 8, 14, 1, 28, 786723)&lt;br /&gt;
date_str = dt.strftime(&amp;quot;%Y-%m-%d %H:%M:%S&amp;quot;)    # &#039;2013-08-08 14:01:28&#039;&lt;br /&gt;
tz_offset = - time.altzone / 3600&lt;br /&gt;
if tz_offset &amp;lt; 0:&lt;br /&gt;
  tz_offset_str = &amp;quot;-%02d00&amp;quot; % abs(tz_offset)&lt;br /&gt;
else:&lt;br /&gt;
  tz_offset_str = &amp;quot;+%02d00&amp;quot; % abs(tz_offset)&lt;br /&gt;
print date_str + &amp;quot; &amp;quot; + tz_offset_str  # &#039;2013-08-08 14:01:28 -0600&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# UTC epoch to str&lt;br /&gt;
gm_epoch_time = calendar.timegm(time.gmtime())    # 1375992114&lt;br /&gt;
dt = datetime.utcfromtimestamp( gm_epoch_time )    # datetime.datetime(2013, 8, 8, 20, 1, 54)&lt;br /&gt;
dt.strftime(&amp;quot;%Y-%m-%d %H:%M:%S +0000&amp;quot;)    # &#039;2013-08-08 20:01:54 +0000&#039;&lt;br /&gt;
dt.strftime(&amp;quot;%Y-%m-%dT%H:%M:%SZ&amp;quot;)    # &#039;2013-08-08 20:01:54 +0000&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Local time str to epoch&lt;br /&gt;
iso_string=&#039;2013-08-08T14:01:28&#039;&lt;br /&gt;
epoch_time = time.mktime( time.strptime( iso_string, &#039;%Y-%m-%dT%H:%M:%S&#039; ) )    # 1375992088.0&lt;br /&gt;
&lt;br /&gt;
iso_string=&#039;2013-08-08T14:01:28 MDT&#039;&lt;br /&gt;
epoch_time = time.mktime( time.strptime( iso_string, &#039;%Y-%m-%dT%H:%M:%S %Z&#039; ) )    # 1375992088.0&lt;br /&gt;
&lt;br /&gt;
# not sure how to specify numerical time zone and pull it in!&lt;br /&gt;
&lt;br /&gt;
# UTC (Zulu) str to epoch, and back again&lt;br /&gt;
iso_string = &#039;2013-08-08T20:01:54Z&#039;&lt;br /&gt;
epoch_time = calendar.timegm( time.strptime( iso_string.replace(&#039;Z&#039;, &#039;GMT&#039;), &#039;%Y-%m-%dT%H:%M:%S%Z&#039; ) )&lt;br /&gt;
print epoch_time    # 1375992114&lt;br /&gt;
print &amp;quot;%sZ&amp;quot; % datetime.utcfromtimestamp(timestamp).isoformat()  # 2013-08-08T20:01:54Z&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Convert epoch from Local to UTC&lt;br /&gt;
epoch_time = 1375992114&lt;br /&gt;
tz_offset = - time.altzone / 3600&lt;br /&gt;
gm_epoch_time = epoch_time - tz_offset * 3600    # 1376013714&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Convert epoch from UTC to Local&lt;br /&gt;
gm_epoch_time = 1376013714&lt;br /&gt;
tz_offset = - time.altzone / 3600&lt;br /&gt;
epoch_time = gm_epoch_time + tz_offset * 3600    # 1375992114&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
struct_time:&lt;br /&gt;
 time.localtime()  # local zime zone&lt;br /&gt;
 time.gmtime()     # UTC time&lt;br /&gt;
&lt;br /&gt;
 today = time.localtime()&lt;br /&gt;
 today_year = today.tm_year&lt;br /&gt;
 today_month = today.tm_mon&lt;br /&gt;
 today_day = today.tm_mday&lt;br /&gt;
&lt;br /&gt;
 time.strftime(&amp;quot;%a, %d %b %Y %H:%M:%S +0000&amp;quot;, time.gmtime())&lt;br /&gt;
&lt;br /&gt;
Zulu time to epoch time: [http://stackoverflow.com/questions/127803/how-to-parse-iso-formatted-date-in-python]&lt;br /&gt;
 s = &#039;2008-09-03T20:56:35.450686Z&#039;&lt;br /&gt;
 event_time_struct = time.strptime(s.split(&#039;.&#039;)[0]+ &amp;quot;UTC&amp;quot;, &amp;quot;%Y-%m-%dT%H:%M:%S%Z&amp;quot;)&lt;br /&gt;
 epoch_time = calendar.timegm(event_time_struct)&lt;br /&gt;
&lt;br /&gt;
Parse string to time.struct_time (like gmtime()): [http://docs.python.org/2/library/time.html#time.strptime]&lt;br /&gt;
 time.strptime(time.ctime())  # current time - default format is ctime format: &amp;quot;%a %b %d %H:%M:%S %Y&amp;quot;&lt;br /&gt;
 time.strptime(time.ctime(time.time()))  # default format is ctime format: &amp;quot;%a %b %d %H:%M:%S %Y&amp;quot;&lt;br /&gt;
 time.strptime(&amp;quot;30 Nov 00&amp;quot;, &amp;quot;%d %b %y&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Build from ticks: [http://www.tutorialspoint.com/python/python_date_time.htm]&lt;br /&gt;
 localtime = time.localtime( time.time() )  # build time.struct_time from ticks&lt;br /&gt;
 print time.asctime( localtime )  # Tue Jan 13 10:17:09 2009&lt;br /&gt;
&lt;br /&gt;
 dt = datetime.datetime.fromtimestamp( time.time() )  # build datetime.datetime struct from ticks&lt;br /&gt;
 dt.strftime(&amp;quot;%Y-%m-%d  %H:%M:%S&amp;quot;)  # &#039;2013-07-31  23:07:48&#039;&lt;br /&gt;
 time.strptime( time.time(), &amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from datetime import date&lt;br /&gt;
now = date.today()    # now = datetime.date(2003, 12,2)&lt;br /&gt;
now.strftime(&amp;quot;%m-%d-%y&amp;quot;)   # &#039;12-02-03&#039;&lt;br /&gt;
# dates support calendar arthimetic&lt;br /&gt;
birthday = date(1964, 7, 31)&lt;br /&gt;
age = now - birthday&lt;br /&gt;
age.days  # 14368&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 ts = (datetime.datetime.now().strftime(&amp;quot;%Y%m%d%H%M&amp;quot;))         # 201105191118&lt;br /&gt;
 tstxt = (datetime.datetime.now().strftime(&amp;quot;%m-%d-%Y %H:%M&amp;quot;))  # 05-19-2011 11:18&lt;br /&gt;
&lt;br /&gt;
Seconds since epoch:&lt;br /&gt;
 int(time.time())    # 1305842304&lt;br /&gt;
&lt;br /&gt;
Zulu and back again: ([http://aboutsimon.com/2013/06/05/datetime-hell-time-zone-aware-to-unix-timestamp/ Datetime hell])&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import time&lt;br /&gt;
from calendar import timegm&lt;br /&gt;
from datetime import datetime&lt;br /&gt;
 &lt;br /&gt;
if __name__ == &#039;__main__&#039;:&lt;br /&gt;
    iso_string = &#039;2013-06-05T15:19:10Z&#039;&lt;br /&gt;
 &lt;br /&gt;
    timestamp = timegm(&lt;br /&gt;
        time.strptime(&lt;br /&gt;
            iso_string.replace(&#039;Z&#039;, &#039;GMT&#039;),&lt;br /&gt;
            &#039;%Y-%m-%dT%H:%M:%S%Z&#039;&lt;br /&gt;
        )&lt;br /&gt;
    )&lt;br /&gt;
 &lt;br /&gt;
    print iso_string&lt;br /&gt;
    print timestamp&lt;br /&gt;
    print &#039;-&amp;gt; %sZ&#039; % datetime.utcfromtimestamp(timestamp).isoformat()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
http://wiki.python.org/moin/TimeTransitionsImage?action=AttachFile&amp;amp;do=get&amp;amp;target=v1.png  [http://wiki.python.org/moin/WorkingWithTime]&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* WorkingWithTime - PythonInfo Wiki - http://wiki.python.org/moin/WorkingWithTime&lt;br /&gt;
* Datetime hell. Time zone aware to UNIX timestamp. | About me and the things I do - http://aboutsimon.com/2013/06/05/datetime-hell-time-zone-aware-to-unix-timestamp/&lt;br /&gt;
* WorkingWithTime - Python Wiki - http://wiki.python.org/moin/WorkingWithTime&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
Something I cooked up...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def utc_time(self, years_offset=60):&lt;br /&gt;
        mst_epoch_time = time.time()  # server is in MST&lt;br /&gt;
        if time.localtime().tm_isdst: # are we daylight saving time?&lt;br /&gt;
            utc_epoch_time = mst_epoch_time + time.altzone&lt;br /&gt;
        else:&lt;br /&gt;
            utc_epoch_time = mst_epoch_time + time.timezone&lt;br /&gt;
        return utc_epoch_time&lt;br /&gt;
&lt;br /&gt;
    def tz_time(self, tz_offset, daylight_adjust=True):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot; return the future time based on timezone offset&lt;br /&gt;
            @tz_offset is timezone offset, eg -7 for MST&lt;br /&gt;
            @daylight_adjust is flag to auto adjust for daylight time&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        if daylight_adjust:&lt;br /&gt;
            if time.localtime().tm_isdst: # are we daylight saving time?&lt;br /&gt;
                _tz_offset = tz_offset - 1&lt;br /&gt;
            else:&lt;br /&gt;
                _tz_offset = tz_offset&lt;br /&gt;
            _utc_epoch_time = self.utc_time()&lt;br /&gt;
            _adj_time = _utc_epoch_time + _tz_offset * 60 * 60&lt;br /&gt;
            return _adj_time&lt;br /&gt;
&lt;br /&gt;
    def future_time(self, tz_offset=-7, daylight_adjust=True, years_offset=60):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot; Calculate some future year &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        _tz_time = self.tz_time(tz_offset)&lt;br /&gt;
        future_utc_epoch_time = _tz_time + years_offset * 365 * 24 * 60 * 60&lt;br /&gt;
        # account for leap years&lt;br /&gt;
        cur_year = datetime.datetime.now().year&lt;br /&gt;
        cur_year_leap = cur_year / 4&lt;br /&gt;
        future_year = cur_year + years_offset&lt;br /&gt;
        future_year_leap = future_year / 4&lt;br /&gt;
        leap_days = future_year_leap - cur_year_leap&lt;br /&gt;
        future_utc_epoch_time += leap_days * 24 * 60 * 60&lt;br /&gt;
        return future_utc_epoch_time&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Math ===&lt;br /&gt;
&lt;br /&gt;
Math Functions:&lt;br /&gt;
 import math&lt;br /&gt;
 math.ceil(x)&lt;br /&gt;
 math.floor(x)&lt;br /&gt;
 math.trunc(x)&lt;br /&gt;
 math.pow(x,y)&lt;br /&gt;
&lt;br /&gt;
 abs(x)  # built in&lt;br /&gt;
&lt;br /&gt;
=== Random ===&lt;br /&gt;
&lt;br /&gt;
 import random&lt;br /&gt;
 random.choice([&#039;a&#039;, &#039;b&#039;, &#039;c&#039;])&lt;br /&gt;
 random.sample(range(100), 10)&lt;br /&gt;
 random.random()  # random float 0 &amp;lt; x &amp;lt; 1&lt;br /&gt;
 random.randrange(3)     # integer in [0, 1, 2]&lt;br /&gt;
 random.randrange(1, 3)  # integer in [1, 2]&lt;br /&gt;
 random.randint(1, 3)    # integer in [1, 2, 3]&lt;br /&gt;
&lt;br /&gt;
=== Operating System Operations ===&lt;br /&gt;
&lt;br /&gt;
Import OS Library:&lt;br /&gt;
 import os&lt;br /&gt;
&lt;br /&gt;
Common Functions:&lt;br /&gt;
 # directory functions&lt;br /&gt;
 os.getcwd()       # get current directory&lt;br /&gt;
 os.listdir(p)     # get list of directory contents&lt;br /&gt;
 os.chdir(p)       # change directory&lt;br /&gt;
 os.mkdir(p)       # make directory&lt;br /&gt;
 os.makedirs(p)    # make directory and all intermediate&lt;br /&gt;
 os.rmdir(p)       # remove empty directory, see shutil.rmtree()&lt;br /&gt;
 os.removedirs(p)  # remove empty directories, see shutil.rmtree()&lt;br /&gt;
 os.path.exists(p) # does file/directory exist?&lt;br /&gt;
 os.path.isdir(p)  # does directory exist&lt;br /&gt;
 os.path.join(folder1, folder2, file, etc)  # portable path join&lt;br /&gt;
&lt;br /&gt;
 # file functions&lt;br /&gt;
 os.remove(p)      # remove file&lt;br /&gt;
 os.unlink(p)      # same as os.remove()&lt;br /&gt;
 os.path.exists(p) # does file/directory exist?&lt;br /&gt;
 os.path.isfile(p) # does file exist&lt;br /&gt;
 os.stat(fname)    # get file stats&lt;br /&gt;
 os.stat(fname).st_size  # file size&lt;br /&gt;
 os.link(src, dst) # create hard link&lt;br /&gt;
 os.readlink(p)    # read symbolic link&lt;br /&gt;
 os.rename(old, new) # rename/move file or directory&lt;br /&gt;
 os.tempnam(p)     # temporary unique name for target path&lt;br /&gt;
 os.tmpfile()      # create temporary file&lt;br /&gt;
 os.tmpnam()       # temporary file name&lt;br /&gt;
 os.path.getsize(filename)  # get file size&lt;br /&gt;
&lt;br /&gt;
 # system functions&lt;br /&gt;
 os.fork()         # fork process&lt;br /&gt;
 os.getpid()       # get process id&lt;br /&gt;
 os.getppid()      # get parent&#039;s process id&lt;br /&gt;
 os.kill(pid, sig) # kill a process&lt;br /&gt;
 os.getlogin()     # get user&#039;s login name&lt;br /&gt;
&lt;br /&gt;
 # execution&lt;br /&gt;
 os.system(cmd)    # output to stdout, return exit_status&lt;br /&gt;
 os.popen(cmd)     # returns a pipe to command&lt;br /&gt;
&lt;br /&gt;
Note: to get path to script:&lt;br /&gt;
 sys.path[0]&lt;br /&gt;
&lt;br /&gt;
Get directory and file names:&lt;br /&gt;
 os.path.dirname(path)  # &#039;/root/test.txt&#039; -&amp;gt; &#039;/root&#039;&lt;br /&gt;
 os.path.basename(path) # &#039;/root/test.txt&#039; -&amp;gt; &#039;test.txt&#039;&lt;br /&gt;
 os.path.splitext(path) # &#039;/root/test.test.txt&#039; -&amp;gt; (&#039;/root/test.test&#039;, &#039;.txt&#039;) - extract extention&lt;br /&gt;
 filename.split(&amp;quot;.&amp;quot;)[-1] # &#039;/root/test.test.txt&#039; -&amp;gt; &#039;txt&#039; - extract extention&lt;br /&gt;
&lt;br /&gt;
Normalize path, eliminating double slashes, etc.&lt;br /&gt;
 os.path.normpath(path)  # &#039;/root/..&#039; -&amp;gt; &#039;/&#039; or &#039;test/..&#039; -&amp;gt; &#039;.&#039;&lt;br /&gt;
 os.path.abspath(path)   # &#039;/root/..&#039; -&amp;gt; &#039;/&#039; or &#039;test/..&#039; -&amp;gt; &#039;/root/test&#039;&lt;br /&gt;
&lt;br /&gt;
List dir: (returns list)&lt;br /&gt;
 os.listdir( os.getcwd() )&lt;br /&gt;
&lt;br /&gt;
List of files:&lt;br /&gt;
 [p for p in os.listdir(os.getcwd())&lt;br /&gt;
    if os.path.isfile(p)]&lt;br /&gt;
&lt;br /&gt;
List of folders:&lt;br /&gt;
 [p for p in os.listdir(os.getcwd())&lt;br /&gt;
    if os.path.isdir(p)]&lt;br /&gt;
&lt;br /&gt;
Build path for local OS: (using appropriate slash)&lt;br /&gt;
 pathstr = os.path.join(&amp;quot;folder&amp;quot;, &amp;quot;folder&amp;quot;, &amp;quot;file_or_folder&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
File and directory management with shutil&lt;br /&gt;
 import shutil&lt;br /&gt;
 shutil.copyfile(&#039;file1&#039;, &#039;file2&#039;)&lt;br /&gt;
 shutil.move(&#039;file1&#039;, &#039;folder2/file1&#039;)&lt;br /&gt;
&lt;br /&gt;
File Wildcards:&lt;br /&gt;
 import glob&lt;br /&gt;
 glob.glob(&#039;*.py&#039;)  # return list of files&lt;br /&gt;
&lt;br /&gt;
Walk directory tree: [http://stackoverflow.com/questions/120656/directory-listing-in-python]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import os&lt;br /&gt;
for dirname, dirnames, filenames in os.walk(&#039;.&#039;):&lt;br /&gt;
    for subdirname in dirnames:&lt;br /&gt;
        print os.path.join(dirname, subdirname)&lt;br /&gt;
    for filename in filenames:&lt;br /&gt;
        print os.path.join(dirname, filename)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ugly &#039;deltree&#039; (by kenneth)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import os&lt;br /&gt;
def deltree(path):&lt;br /&gt;
    files = os.listdir(path)&lt;br /&gt;
    for file in files:&lt;br /&gt;
        file_path = os.path.join(path, file)&lt;br /&gt;
        if os.path.isdir(file_path):&lt;br /&gt;
            deltree(file_path)&lt;br /&gt;
            os.rmdir(file_path)&lt;br /&gt;
        else:&lt;br /&gt;
            os.remove(file_path)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cleaner &#039;deltree&#039; (by Kep)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import shutil&lt;br /&gt;
# Blow away (if needed), and reclone to proper version&lt;br /&gt;
if os.path.isdir(&amp;quot;xxx&amp;quot;):&lt;br /&gt;
    shutil.rmtree(&amp;quot;xxx&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== System Platform ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import platform&lt;br /&gt;
&lt;br /&gt;
if platform.system() == &amp;quot;Linux&amp;quot;:&lt;br /&gt;
 # ...&lt;br /&gt;
if platform.system() == &amp;quot;Windows&amp;quot;:&lt;br /&gt;
 # ...&lt;br /&gt;
else:&lt;br /&gt;
 # ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Temp Files ===&lt;br /&gt;
&lt;br /&gt;
 import tempfile&lt;br /&gt;
 filename = tempfile.mktemp()&lt;br /&gt;
 f = open(filename, &#039;w&#039;)&lt;br /&gt;
 ...&lt;br /&gt;
 f.close()&lt;br /&gt;
 &lt;br /&gt;
 import os&lt;br /&gt;
 os.remove(filename)  # delete temp file&lt;br /&gt;
&lt;br /&gt;
=== Pickling ===&lt;br /&gt;
&lt;br /&gt;
Pickling (serializing, making objects persistent):&lt;br /&gt;
 import pickle&lt;br /&gt;
 grades = {&#039;bob&#039; : [4, 5, 6],&lt;br /&gt;
           &#039;sue&#039; : [3, None, 7, 7]}&lt;br /&gt;
 outfile = open(fname, &#039;wb&#039;)&lt;br /&gt;
 pickle.dump(grades, outfile)&lt;br /&gt;
&lt;br /&gt;
 infile = open(fname, &#039;rb&#039;)&lt;br /&gt;
 grades = pickle.load(infile)&lt;br /&gt;
&lt;br /&gt;
=== [http://docs.python.org/library/logging.html Logging] ===&lt;br /&gt;
&lt;br /&gt;
* logging — Logging facility for Python — Python 3 documentation - https://docs.python.org/3/library/logging.html&lt;br /&gt;
* Logging HOWTO — Python Dev Version documentation - http://docs.python.org/dev/howto/logging.html&lt;br /&gt;
* Logging Cookbook — Python Dev Version documentation - http://docs.python.org/dev/howto/logging-cookbook.html&lt;br /&gt;
&lt;br /&gt;
Setup logger:&lt;br /&gt;
 import logging&lt;br /&gt;
 logging.basicConfig(level=logging.DEBUG,format=&#039;[%(asctime)s.%(msecs)03d] %(levelname)s %(filename)s(line:%(lineno)d): %(message)s&#039;)&lt;br /&gt;
&lt;br /&gt;
Log Levels:&lt;br /&gt;
 import logging&lt;br /&gt;
 msg = &amp;quot;i broke&amp;quot;&lt;br /&gt;
 logging.debug(msg)&lt;br /&gt;
 logging.info(msg)&lt;br /&gt;
 logging.warning(msg)   # WARNING:root:i broke&lt;br /&gt;
 logging.error(msg)     # ERROR:root:i broke&lt;br /&gt;
 logging.critical(msg)  # CRITICAL:root:i broke&lt;br /&gt;
&lt;br /&gt;
 log.setLevel(level)  # debug, info, warn/warning, error, critical&lt;br /&gt;
 log.setLevel(logging.DEBUG)&lt;br /&gt;
&lt;br /&gt;
A good convention to use when naming loggers is to use a module-level logger, in each module which uses logging, named as follows: [http://docs.python.org/dev/howto/logging.html]&lt;br /&gt;
 logger = logging.getLogger(__name__)&lt;br /&gt;
&lt;br /&gt;
Simple example: [http://stackoverflow.com/questions/345991/python-no-handlers-could-be-found-for-logger-opengl-error]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
log_format=&#039;%(asctime)s | %(levelname)s | %(message)s&#039;&lt;br /&gt;
log_date_format=&#039;%Y-%m-%d %H:%M:%S&#039;&lt;br /&gt;
logging.basicConfig(format=log_format, datefmt=log_date_format)&lt;br /&gt;
log = logging.getLogger(__name__)&lt;br /&gt;
log.setLevel(logging.INFO)&lt;br /&gt;
&lt;br /&gt;
log.info(&#039;hi&#039;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Formatter function:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def makeFormatter(format_str=&amp;quot;&amp;quot;, date_format=&amp;quot;%Y-%m-%d %H:%M:%S&amp;quot;):&lt;br /&gt;
    if not format_str:&lt;br /&gt;
        format_str = &amp;quot;%(asctime)s | %(levelname)s | %(filename)s:%(lineno)d:%(funcName)s | %(message)s&amp;quot;&lt;br /&gt;
    return logging.Formatter(fmt=format_str, datefmt=date_format)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Medium example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Create logger&lt;br /&gt;
log_format=&#039;%(asctime)s | %(levelname)s | %(message)s&#039;&lt;br /&gt;
log_date_format=&#039;%Y-%m-%d %H:%M:%S&#039;&lt;br /&gt;
log_formatter = logging.Formatter(fmt=log_format, datefmt=log_date_format)&lt;br /&gt;
log = logging.getLogger(__name__)&lt;br /&gt;
log.setLevel(logging.DEBUG)&lt;br /&gt;
&lt;br /&gt;
# Log to console&lt;br /&gt;
ch = logging.StreamHandler()&lt;br /&gt;
ch.setLevel(logging.INFO)&lt;br /&gt;
ch.setFormatter(log_formatter)&lt;br /&gt;
log.addHandler(ch)&lt;br /&gt;
&lt;br /&gt;
# Log to file&lt;br /&gt;
fh = logging.FileHandler(&#039;my_logger.log&#039;)&lt;br /&gt;
fh.setLevel(logging.DEBUG)&lt;br /&gt;
fh.setFormatter(log_formatter)&lt;br /&gt;
log.addHandler(fh)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Log all loggers to file - attach to root logger&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import logging&lt;br /&gt;
&lt;br /&gt;
logger = logging.getLogger(__name__)&lt;br /&gt;
&lt;br /&gt;
# Configure Logger&lt;br /&gt;
log_format=&#039;%(asctime)s | %(name)s | %(levelname)s | %(message)s&#039;&lt;br /&gt;
log_date_format=&#039;%Y-%m-%d %H:%M:%S&#039;&lt;br /&gt;
log_formatter = logging.Formatter(fmt=log_format, datefmt=log_date_format)&lt;br /&gt;
logging.basicConfig(level=logging.DEBUG, format=log_format, datefmt=log_date_format)&lt;br /&gt;
&lt;br /&gt;
# Setup Log to File handler, and attach to root logger&lt;br /&gt;
root_logger = logging.getLogger()  # Calling getLogger() without a name returns the root logger&lt;br /&gt;
fh = logging.FileHandler(&#039;logger.txt&#039;)&lt;br /&gt;
fh.setLevel(logging.DEBUG)&lt;br /&gt;
fh.setFormatter(log_formatter)&lt;br /&gt;
root_logger.addHandler(fh)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Application Setup (not basic log configuration carries across imported modules):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import logging&lt;br /&gt;
def main():&lt;br /&gt;
    logging.basicConfig(filename=&#039;myapp.log&#039;, level=logging.INFO)&lt;br /&gt;
    logging.info(&#039;Started&#039;)&lt;br /&gt;
    ...&lt;br /&gt;
    logging.info(&#039;Finished&#039;)&lt;br /&gt;
&lt;br /&gt;
if __name__ == &#039;__main__&#039;:&lt;br /&gt;
    main()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Log multiple lines:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
for line in output.splitlines():&lt;br /&gt;
    log.debug(line)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Set log level:  (warning is default)&lt;br /&gt;
 logging.basicConfig(level=logging.DEBUG)&lt;br /&gt;
&lt;br /&gt;
Set log level from string value: [http://docs.python.org/dev/howto/logging.html]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# assuming loglevel is bound to the string value obtained from the&lt;br /&gt;
# command line argument. Convert to upper case to allow the user to&lt;br /&gt;
# specify --log=DEBUG or --log=debug&lt;br /&gt;
numeric_level = getattr(logging, loglevel.upper(), None)&lt;br /&gt;
if not isinstance(numeric_level, int):&lt;br /&gt;
    raise ValueError(&#039;Invalid log level: %s&#039; % loglevel)&lt;br /&gt;
logging.basicConfig(level=numeric_level, ...)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Log to file:&lt;br /&gt;
 logging.basicConfig(filename=&#039;example.log&#039;,level=logging.DEBUG)&lt;br /&gt;
 logging.basicConfig(filename=&#039;example.log&#039;, filemode=&#039;w&#039;, level=logging.DEBUG)  # do not append&lt;br /&gt;
&lt;br /&gt;
Format output: (once set, can&#039;t be changed?)&lt;br /&gt;
 # WARNING:MESSAGE&lt;br /&gt;
 logging.basicConfig(format=&#039;%(levelname)s:%(message)s&#039;, level=logging.DEBUG)&lt;br /&gt;
&lt;br /&gt;
 # 05/23/2011 12:50:02 PM MESSAGE&lt;br /&gt;
 logging.basicConfig(format=&#039;%(asctime)s %(message)s&#039;, datefmt=&#039;%m/%d/%Y %I:%M:%S %p&#039;)&lt;br /&gt;
&lt;br /&gt;
 # 05/23/2011 12:55:28 PM : WARNING : MESSAGE&lt;br /&gt;
 logging.basicConfig(format=&#039;%(asctime)s : %(levelname)s : %(message)s&#039;, datefmt=&#039;%m/%d/%Y %I:%M:%S %p&#039;)&lt;br /&gt;
&lt;br /&gt;
 # 2011-05-23 13:05:30 : WARNING : MESSAGE&lt;br /&gt;
 logging.basicConfig(format=&#039;%(asctime)s : %(levelname)s : %(message)s&#039;, datefmt=&#039;%Y-%m-%d %H:%M:%S&#039;)&lt;br /&gt;
&lt;br /&gt;
 # 2011-05-23 13:05:30 | WARNING | FILE:FUNC | MESSAGE&lt;br /&gt;
 logging.basicConfig(format=&#039;%(asctime)s | %(levelname)s | %(filename)s:%(funcName)s | %(message)s&#039;, datefmt=&#039;%Y-%m-%d %H:%M:%S&#039;)&lt;br /&gt;
&lt;br /&gt;
Log record attributes - http://docs.python.org/library/logging.html#logrecord-attributes&lt;br /&gt;
&lt;br /&gt;
Format Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FORMAT = &#039;%(asctime)-15s %(clientip)s %(user)-8s %(message)s&#039;  # doesn&#039;t work!&lt;br /&gt;
logging.basicConfig(format=FORMAT)&lt;br /&gt;
d = { &#039;clientip&#039; : &#039;192.168.0.1&#039;, &#039;user&#039; : &#039;fbloggs&#039; }&lt;br /&gt;
logger = logging.getLogger(&#039;tcpserver&#039;)&lt;br /&gt;
logger.warning(&#039;Protocol problem: %s&#039;, &#039;connection reset&#039;, extra=d)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import logging&lt;br /&gt;
&lt;br /&gt;
# create logger with &#039;spam_application&#039;&lt;br /&gt;
logger = logging.getLogger(&#039;spam_application&#039;)&lt;br /&gt;
logger.setLevel(logging.DEBUG)&lt;br /&gt;
&lt;br /&gt;
# create file handler which logs even debug messages&lt;br /&gt;
fh = logging.FileHandler(&#039;spam.log&#039;)&lt;br /&gt;
fh.setLevel(logging.DEBUG)&lt;br /&gt;
&lt;br /&gt;
# create console handler with a higher log level&lt;br /&gt;
ch = logging.StreamHandler()&lt;br /&gt;
ch.setLevel(logging.ERROR)&lt;br /&gt;
&lt;br /&gt;
# create formatter and add it to the handlers&lt;br /&gt;
formatter = logging.Formatter(&#039;%(asctime)s - %(name)s - %(levelname)s - %(message)s&#039;)&lt;br /&gt;
fh.setFormatter(formatter)&lt;br /&gt;
ch.setFormatter(formatter)&lt;br /&gt;
&lt;br /&gt;
# add the handlers to the logger&lt;br /&gt;
logger.addHandler(fh)&lt;br /&gt;
logger.addHandler(ch)&lt;br /&gt;
&lt;br /&gt;
logger.info(&#039;Message to loggers and handlers&#039;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Templating ===&lt;br /&gt;
&lt;br /&gt;
 from string import Template&lt;br /&gt;
 t = Template(&#039;${name}&#039;s fav dish is $food&#039;)&lt;br /&gt;
 t.substitute(name = &#039;ken&#039;, food = &#039;beans&#039;) # throws exception if missing one, but can have more&lt;br /&gt;
 t.safe_substitute(name = &#039;ken&#039;)  # will fill in what it can&lt;br /&gt;
&lt;br /&gt;
Change delimiter:&lt;br /&gt;
 class MYT(Template):&lt;br /&gt;
   delimiter = &#039;%&#039;&lt;br /&gt;
 minput = input(&amp;quot;File name format (%d - date, %s - size): &amp;quot;)&lt;br /&gt;
 myt = MYT(minput)&lt;br /&gt;
 myt.substitute(%d=date, %s=size)&lt;br /&gt;
&lt;br /&gt;
=== [http://docs.python.org/library/threading.html Threading] ===&lt;br /&gt;
&lt;br /&gt;
Basic thread: [http://softwareramblings.com/2008/06/running-functions-as-threads-in-python.html]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import thread&lt;br /&gt;
 &lt;br /&gt;
def someFunc():&lt;br /&gt;
    print &amp;quot;someFunc was called&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
thread.start_new_thread(someFunc, ())&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
More complete basic thread:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import thread&lt;br /&gt;
import threading&lt;br /&gt;
import time&lt;br /&gt;
&lt;br /&gt;
def run_thread (threadname, sleeptime):&lt;br /&gt;
 print &amp;quot;Thread start: &amp;quot; + threadname&lt;br /&gt;
 time.sleep(sleeptime)&lt;br /&gt;
 print &amp;quot;Thread end: &amp;quot; + threadname&lt;br /&gt;
 thread.interrupt_main()   # throw keyboard interrupt to kill main program&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
 thread.start_new_thread(run_thread, (&amp;quot;Thread1&amp;quot;, 3))&lt;br /&gt;
 try:&lt;br /&gt;
     while 1:&lt;br /&gt;
         pass&lt;br /&gt;
 except:&lt;br /&gt;
     print &amp;quot;Thread1 exited....&amp;quot; &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Can use a global counter instead of exception to track number of threads:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import thread&lt;br /&gt;
import threading&lt;br /&gt;
import time&lt;br /&gt;
&lt;br /&gt;
threadcount = 3&lt;br /&gt;
&lt;br /&gt;
def run_thread (threadname, sleeptime):&lt;br /&gt;
  global threadcount&lt;br /&gt;
  print &amp;quot;Thread start: &amp;quot; + threadname&lt;br /&gt;
  time.sleep(sleeptime)&lt;br /&gt;
  print &amp;quot;Thread end: &amp;quot; + threadname&lt;br /&gt;
  threadcount -= 1&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
  thread.start_new_thread(run_thread, (&amp;quot;Thread1&amp;quot;, 3))&lt;br /&gt;
  thread.start_new_thread(run_thread, (&amp;quot;Thread2&amp;quot;, 4))&lt;br /&gt;
  thread.start_new_thread(run_thread, (&amp;quot;Thread3&amp;quot;, 2))&lt;br /&gt;
  while 1:&lt;br /&gt;
    if threadcount == 0:&lt;br /&gt;
      break&lt;br /&gt;
    else:&lt;br /&gt;
      pass&lt;br /&gt;
  print &amp;quot;completed&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
Thread object: [http://softwareramblings.com/2008/06/running-functions-as-threads-in-python.html]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import threading&lt;br /&gt;
 &lt;br /&gt;
t1 = threading.Thread(target=someFunc)&lt;br /&gt;
#  with parameters: Thread(target=myfunction, args=(&#039;MyStringHere&#039;,1)).start()&lt;br /&gt;
t1.start()&lt;br /&gt;
t1.join()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Basic threading with parameters:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import threading&lt;br /&gt;
t = threading.Thread(None, someFunc, None, (param1, param2))&lt;br /&gt;
t.start()&lt;br /&gt;
t.join()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
t = threading.Thread(target=client_recv, args=(s, name))&lt;br /&gt;
while True:&lt;br /&gt;
  t.join(timeout=2)&lt;br /&gt;
  if t.isAlive():&lt;br /&gt;
    print &amp;quot;Thread is dead...&amp;quot;&lt;br /&gt;
    break&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Threading as a class: [http://softwareramblings.com/2008/06/running-functions-as-threads-in-python.html]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import threading&lt;br /&gt;
 &lt;br /&gt;
class FuncThread(threading.Thread):&lt;br /&gt;
    def __init__(self, target, *args):&lt;br /&gt;
        self._target = target&lt;br /&gt;
        self._args = args&lt;br /&gt;
        threading.Thread.__init__(self)&lt;br /&gt;
 &lt;br /&gt;
    def run(self):&lt;br /&gt;
        self._target(*self._args)&lt;br /&gt;
 &lt;br /&gt;
# Example usage&lt;br /&gt;
def someOtherFunc(data, key):&lt;br /&gt;
    print &amp;quot;someOtherFunc was called : data=%s; key=%s&amp;quot; % (str(data), str(key))&lt;br /&gt;
 &lt;br /&gt;
t1 = FuncThread(someOtherFunc, [1,2], 6)&lt;br /&gt;
t1.start()&lt;br /&gt;
t1.join()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Threading as a class #2:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import threading&lt;br /&gt;
import time&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
class MyT(threading.Thread):&lt;br /&gt;
  def __init__(self, name, time):&lt;br /&gt;
    threading.Thread.__init__(self)&lt;br /&gt;
    self.name = name&lt;br /&gt;
    self.time = time&lt;br /&gt;
  def run(self):&lt;br /&gt;
    print(&amp;quot;Thread Start: &amp;quot; + self.name)&lt;br /&gt;
    for i in range(self.time):&lt;br /&gt;
      print(&amp;quot;[&amp;quot; + self.name + &amp;quot;]&amp;quot;, end=&#039;&#039;)&lt;br /&gt;
      sys.stdout.flush()&lt;br /&gt;
      time.sleep(1)&lt;br /&gt;
    print(&amp;quot;Thread Stop: &amp;quot; + self.name)&lt;br /&gt;
&lt;br /&gt;
myt1 = MyT(&#039;1&#039;, 10)&lt;br /&gt;
myt1.start()&lt;br /&gt;
&lt;br /&gt;
myt2 = MyT(&#039;2&#039;, 15)&lt;br /&gt;
myt2.start()&lt;br /&gt;
&lt;br /&gt;
myt3 = MyT(&#039;3&#039;, 5)&lt;br /&gt;
myt3.start()&lt;br /&gt;
&lt;br /&gt;
myt4 = MyT(&#039;4&#039;, 10)&lt;br /&gt;
myt4.start()&lt;br /&gt;
&lt;br /&gt;
myt1.join()&lt;br /&gt;
myt2.join()&lt;br /&gt;
myt3.join()&lt;br /&gt;
myt4.join()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Locking:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
lock=thread.allocate_lock()&lt;br /&gt;
&lt;br /&gt;
# pass lock to thread, and use in thread as such:&lt;br /&gt;
lock.acquire()&lt;br /&gt;
#some operation&lt;br /&gt;
lock.release()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Returning data from a thread (using a [http://docs.python.org/library/queue.html queue]): [http://stackoverflow.com/questions/1886090/return-value-from-thread] [http://stackoverflow.com/questions/2829329/catch-a-threads-exception-in-the-caller-thread-in-python]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Pass exception back to parent&lt;br /&gt;
import sys&lt;br /&gt;
import threading&lt;br /&gt;
import Queue&lt;br /&gt;
&lt;br /&gt;
class ExcThread(threading.Thread):&lt;br /&gt;
    def __init__(self, bucket):&lt;br /&gt;
        threading.Thread.__init__(self)&lt;br /&gt;
        self.bucket = bucket&lt;br /&gt;
    def run(self):&lt;br /&gt;
        try:&lt;br /&gt;
            raise Exception(&#039;An error occured here.&#039;)&lt;br /&gt;
        except Exception:&lt;br /&gt;
            self.bucket.put(sys.exc_info())&lt;br /&gt;
&lt;br /&gt;
def main():&lt;br /&gt;
    bucket = Queue.Queue()&lt;br /&gt;
    thread_obj = ExcThread(bucket)&lt;br /&gt;
    thread_obj.start()&lt;br /&gt;
    while True:&lt;br /&gt;
        try:&lt;br /&gt;
            exc = bucket.get(block=False)&lt;br /&gt;
        except Queue.Empty:&lt;br /&gt;
            pass&lt;br /&gt;
        else:&lt;br /&gt;
            exc_type, exc_obj, exc_trace = exc&lt;br /&gt;
            # deal with the exception&lt;br /&gt;
            print &amp;quot;Exception Caught:&amp;quot;, exc_type, exc_obj&lt;br /&gt;
            print &amp;quot;Exception Trace:&amp;quot;, exc_trace&lt;br /&gt;
        thread_obj.join(0.1)&lt;br /&gt;
        if thread_obj.isAlive():&lt;br /&gt;
            continue&lt;br /&gt;
        else:&lt;br /&gt;
            break&lt;br /&gt;
&lt;br /&gt;
if __name__ == &#039;__main__&#039;:&lt;br /&gt;
    main()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Exception Caught: &amp;lt;type &#039;exceptions.Exception&#039;&amp;gt; An error occured here.&lt;br /&gt;
Exception Trace: &amp;lt;traceback object at 0x2b2230a285f0&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Another Exception catching queue example: (kenneth&#039;s example)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# thread function&lt;br /&gt;
def run_thread(queue, item):&lt;br /&gt;
  ...&lt;br /&gt;
  queue.put( Exception(&amp;quot;Failure on item:&amp;quot; + item) )&lt;br /&gt;
&lt;br /&gt;
threads = []&lt;br /&gt;
queue = Queue.Queue()&lt;br /&gt;
&lt;br /&gt;
# start threads&lt;br /&gt;
for item in items:&lt;br /&gt;
  t = Thread(None, run_thread, None, (queue, item))&lt;br /&gt;
  t.start()&lt;br /&gt;
  threads.append(t)&lt;br /&gt;
&lt;br /&gt;
# wait for threads&lt;br /&gt;
for t in threads:&lt;br /&gt;
  t.join()&lt;br /&gt;
&lt;br /&gt;
# catch and reraise exceptions&lt;br /&gt;
while not queue.empty():&lt;br /&gt;
  raise(queue.get())&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Returning data from a thread (using a callback function): [http://stackoverflow.com/questions/1886090/return-value-from-thread]&lt;br /&gt;
:&amp;quot;Another approach is to pass a callback function to the thread. This gives a simple, safe and flexible way to return a value to the parent, anytime from the new thread.&amp;quot;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import threading&lt;br /&gt;
import time&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
class MyThread(threading.Thread):&lt;br /&gt;
    def __init__(self, cb):&lt;br /&gt;
        threading.Thread.__init__(self)&lt;br /&gt;
        self.callback = cb&lt;br /&gt;
    def run(self):&lt;br /&gt;
        for i in range(10):&lt;br /&gt;
            self.callback(i)&lt;br /&gt;
            time.sleep(1)&lt;br /&gt;
&lt;br /&gt;
def count(x):&lt;br /&gt;
    print x&lt;br /&gt;
    sys.stdout.flush()&lt;br /&gt;
&lt;br /&gt;
t = MyThread(count)&lt;br /&gt;
t.start()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* 16.2. threading — Higher-level threading interface — Python v2.7.1 documentation - http://docs.python.org/library/threading.html&lt;br /&gt;
* An Introduction to Thread Programming - http://www.prasannatech.net/2008/08/introduction-to-thread-programming.html&lt;br /&gt;
* Python - Multithreaded Programming - http://www.tutorialspoint.com/python/python_multithreading.htm&lt;br /&gt;
* Running Functions as Threads in Python « Software Ramblings - http://softwareramblings.com/2008/06/running-functions-as-threads-in-python.html&lt;br /&gt;
* Understanding Threading in Python LG #107 - http://linuxgazette.net/107/pai.html&lt;br /&gt;
* multithreading - Simple threading in Python 2.6 using thread.start_new_thread() - Stack Overflow - http://stackoverflow.com/questions/849674/simple-threading-in-python-2-6-using-thread-start-new-thread&lt;br /&gt;
* python - Return value from thread - Stack Overflow - http://stackoverflow.com/questions/1886090/return-value-from-thread&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
Interrupt main thread:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# source: http://stackoverflow.com/questions/4591917/python-how-to-quit-cli-when-stuck-in-blocking-raw-input&lt;br /&gt;
&lt;br /&gt;
import thread&lt;br /&gt;
import time&lt;br /&gt;
&lt;br /&gt;
def main():&lt;br /&gt;
    try:&lt;br /&gt;
        m = thread.start_new_thread(killable_input, tuple())&lt;br /&gt;
        while 1:&lt;br /&gt;
            time.sleep(0.1) &lt;br /&gt;
    except KeyboardInterrupt:&lt;br /&gt;
        print &amp;quot;exception&amp;quot; &lt;br /&gt;
&lt;br /&gt;
def killable_input():&lt;br /&gt;
    w = thread.start_new_thread(normal_input, tuple())&lt;br /&gt;
    i = thread.start_new_thread(wait_sometime, tuple())&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def normal_input():&lt;br /&gt;
    s = raw_input(&amp;quot;input:&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def wait_sometime():&lt;br /&gt;
    time.sleep(4) # or any other condition to kill the thread&lt;br /&gt;
    print &amp;quot;too slow, killing imput&amp;quot;&lt;br /&gt;
    thread.interrupt_main()&lt;br /&gt;
&lt;br /&gt;
if __name__ == &#039;__main__&#039;:&lt;br /&gt;
    main()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== urllib ===&lt;br /&gt;
&lt;br /&gt;
See [[Python/urllib]]&lt;br /&gt;
&lt;br /&gt;
=== Command line arguments ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import sys&lt;br /&gt;
for x in sys.argv:&lt;br /&gt;
    print x&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Execute other python script ===&lt;br /&gt;
&lt;br /&gt;
 import sys&lt;br /&gt;
 sys.argv = [&#039;&#039;, &#039;my&#039;, &#039;args&#039;, &#039;here&#039;]&lt;br /&gt;
 execfile(&#039;myscript.py&#039;)  # does not support arguments directly&lt;br /&gt;
&lt;br /&gt;
=== Exit Code ===&lt;br /&gt;
&lt;br /&gt;
sys.exit(n) http://docs.python.org/library/sys.html:&lt;br /&gt;
 import sys&lt;br /&gt;
 sys.exit(1)  # exit code of 1 (default is 0)&lt;br /&gt;
 sys.exit(&amp;quot;some error&amp;quot;)  # exit code of 1, and message displayed&lt;br /&gt;
&lt;br /&gt;
=== [http://docs.python.org/library/syslog.html syslog] ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import syslog&lt;br /&gt;
syslog.openlog(&#039;[WATER]&#039;)&lt;br /&gt;
syslog.syslog(&#039;Processing started&#039;)&lt;br /&gt;
if error:&lt;br /&gt;
    syslog.syslog(syslog.LOG_ERR, &#039;Processing started&#039;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import syslog&lt;br /&gt;
syslog.openlog(&#039;[WATER]&#039;)&lt;br /&gt;
def log(msg):&lt;br /&gt;
    syslog.syslog(str(msg))&lt;br /&gt;
log(&amp;quot;Starting...&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Subprocess ===&lt;br /&gt;
&lt;br /&gt;
Subprocess - http://docs.python.org/library/subprocess.html&lt;br /&gt;
&lt;br /&gt;
Methods of subprocess (or external command execution):&lt;br /&gt;
* subprocess (only method to rule/replace all others)&lt;br /&gt;
* os.system&lt;br /&gt;
* os.spawn*&lt;br /&gt;
* os.popen*&lt;br /&gt;
* popen2.*&lt;br /&gt;
* commands.*&lt;br /&gt;
&lt;br /&gt;
My New Favorite:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import subprocess&lt;br /&gt;
class Run(object):&lt;br /&gt;
    class RC(int):&lt;br /&gt;
        pass&lt;br /&gt;
    def __new__(cls, cmd, *args, **kwargs):&lt;br /&gt;
        p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)&lt;br /&gt;
        rc = cls.RC(p.wait())&lt;br /&gt;
        rc.output = &amp;quot;\n&amp;quot;.join(p.stdout.readlines())&lt;br /&gt;
        rc.error = &amp;quot;\n&amp;quot;.join(p.stderr.readlines())&lt;br /&gt;
        return rc&lt;br /&gt;
&lt;br /&gt;
if Run(&amp;quot;some command&amp;quot;): print &amp;quot;do something&amp;quot;  # on rc of not 0 (negative or positive)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
My Favorite:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def exe(cmd):&lt;br /&gt;
    p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)&lt;br /&gt;
    #output = &amp;quot; | &amp;quot;.join(p.stdout.readlines())&lt;br /&gt;
    output = &amp;quot;\n&amp;quot;.join(p.stdout.readlines())&lt;br /&gt;
    rc = p.wait()&lt;br /&gt;
    return (rc, output)&lt;br /&gt;
&lt;br /&gt;
def exe_checked(cmd, checked=True):&lt;br /&gt;
    p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)&lt;br /&gt;
    #output = &amp;quot; | &amp;quot;.join(p.stdout.readlines())&lt;br /&gt;
    output = &amp;quot;\n&amp;quot;.join(p.stdout.readlines())&lt;br /&gt;
    rc = p.wait()&lt;br /&gt;
    if rc and checked:&lt;br /&gt;
        raise Exception(&amp;quot;Command returned non zero [{0}]: {1}&amp;quot;.format(rc, cmd)&lt;br /&gt;
    return (rc, output)&lt;br /&gt;
&lt;br /&gt;
def exe_with_stderr(cmd):&lt;br /&gt;
    p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subproc&lt;br /&gt;
ess.PIPE)&lt;br /&gt;
    output = &amp;quot; | &amp;quot;.join(p.stdout.readlines())&lt;br /&gt;
    outputerr = &amp;quot; | &amp;quot;.join(p.stderr.readlines())&lt;br /&gt;
    rc = p.wait()&lt;br /&gt;
    return (rc, output, outputerr)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def exec_program(cmd):&lt;br /&gt;
    s = subprocess.Popen(cmd.split(), stdout=subprocess.PIPE, stderr=subprocess.PIPE)&lt;br /&gt;
    stdout, stderr = s.communicate()&lt;br /&gt;
    result = s.wait()&lt;br /&gt;
    return stdout, stderr, result&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pass along output and return true error code:&lt;br /&gt;
 import subprocess&lt;br /&gt;
 retcode = subprocess.call([&amp;quot;ls&amp;quot;, &amp;quot;-l&amp;quot;])  # true return code, output sent to STDOUT&lt;br /&gt;
&lt;br /&gt;
 retcode = subprocess.call([&amp;quot;foo.sh&amp;quot;,&amp;quot;args&amp;quot;],shell=True)  # Execute in shell, with shell processing&lt;br /&gt;
 retcode = subprocess.call([&#039;C:\\Temp\\a b c\\Notepad.exe&#039;])&lt;br /&gt;
 retcode = subprocess.call([&amp;quot;D:/Python24/Python.exe&amp;quot;, &amp;quot;Skripta.py&amp;quot;, &amp;quot;arg1&amp;quot;, &amp;quot;arg2&amp;quot;])&lt;br /&gt;
&lt;br /&gt;
Note: shell=True is equivalent to: subprocess.Popen([&#039;/bin/sh&#039;, &#039;-c&#039;, args[0], args[1], ...])&lt;br /&gt;
&lt;br /&gt;
Process STDOUT and STDERR and get return code:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
import subprocess&lt;br /&gt;
import string&lt;br /&gt;
&lt;br /&gt;
cmd = &amp;quot;cat /etc/passwd | grep ken&amp;quot;&lt;br /&gt;
p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) # stderr=subprocess.STDOUT to combine&lt;br /&gt;
&lt;br /&gt;
out = string.join(p.stdout.readlines())&lt;br /&gt;
outerr = string.join(p.stderr.readlines())&lt;br /&gt;
retcode = str(p.wait())&lt;br /&gt;
&lt;br /&gt;
print(&amp;quot;STDOUT: &amp;quot; + out)&lt;br /&gt;
print(&amp;quot;STDERR: &amp;quot; + outerr)&lt;br /&gt;
print(&amp;quot;RETCODE: &amp;quot; + retcode)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Above with stderr redirected to stdout (combined):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import subprocess&lt;br /&gt;
p = subprocess.Popen(&#039;ls&#039;, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)&lt;br /&gt;
for line in p.stdout.readlines():&lt;br /&gt;
    print line,&lt;br /&gt;
retval = p.wait()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Replacing shell backtick: [http://docs.python.org/library/subprocess.html]&lt;br /&gt;
 # shell code:&lt;br /&gt;
 # OUTPUT=`mycmd myarg`&lt;br /&gt;
 from subprocess import Popen&lt;br /&gt;
 output = Popen([&amp;quot;mycmd&amp;quot;, &amp;quot;myarg&amp;quot;], stdout=PIPE).communicate()[0]&lt;br /&gt;
&lt;br /&gt;
Replacing shell pipeline  [http://docs.python.org/library/subprocess.html]&lt;br /&gt;
 # shell code:&lt;br /&gt;
 # OUTPUT=`dmesg | grep hda`&lt;br /&gt;
 from subprocess import Popen&lt;br /&gt;
 p1 = Popen([&amp;quot;dmesg&amp;quot;], stdout=PIPE)&lt;br /&gt;
 p2 = Popen([&amp;quot;grep&amp;quot;, &amp;quot;hda&amp;quot;], stdin=p1.stdout, stdout=PIPE)&lt;br /&gt;
 p1.stdout.close()  # Allow p1 to receive a SIGPIPE if p2 exits.&lt;br /&gt;
 output = p2.communicate()[0]&lt;br /&gt;
&lt;br /&gt;
Replacing os.system(): [http://docs.python.org/library/subprocess.html]&lt;br /&gt;
 # old:&lt;br /&gt;
 sts = os.system(&amp;quot;mycmd&amp;quot; + &amp;quot; myarg&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
 # new:&lt;br /&gt;
 p = Popen(&amp;quot;mycmd&amp;quot; + &amp;quot; myarg&amp;quot;, shell=True)&lt;br /&gt;
 sts = os.waitpid(p.pid, 0)[1]&lt;br /&gt;
&lt;br /&gt;
Control an executed process:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cmd = &amp;quot;/usr/bin/java -Xms256M -Xmx1024M -jar minecraft_server.jar nogui&amp;quot;&lt;br /&gt;
&lt;br /&gt;
p = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE,&lt;br /&gt;
        stdout=subprocess.PIPE, stderr=subprocess.STDOUT)&lt;br /&gt;
&lt;br /&gt;
# cycle while process continues alive&lt;br /&gt;
while p.poll() == None:&lt;br /&gt;
&lt;br /&gt;
  # check if input&lt;br /&gt;
  if select.select([p.stdout.fileno()], [], [], 1)[0]:&lt;br /&gt;
    while select.select([p.stdout.fileno()], [], [], .1)[0]:&lt;br /&gt;
        line = p.stdout.readline()&lt;br /&gt;
        # ... process&lt;br /&gt;
&lt;br /&gt;
  # write something to process&lt;br /&gt;
  p.stdin.write(&amp;quot;tp %s %s\n&amp;quot; % (user1, user2))&lt;br /&gt;
&lt;br /&gt;
  ...&lt;br /&gt;
&lt;br /&gt;
  # time to force a quit: (choose which you need)&lt;br /&gt;
  p.kill()  # SIGKILL&lt;br /&gt;
  p.terminate()  # SIGTERM&lt;br /&gt;
  os.kill(p.pid, signal.SIGTERM)  # same as first, but not as clean&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Other Command Execution ====&lt;br /&gt;
&lt;br /&gt;
Old method with os.system(): [http://docs.python.org/library/os.html]&lt;br /&gt;
 import os&lt;br /&gt;
 encoded_wait_code = os.system(&amp;quot;some command&amp;quot;)  # output sent to STDOUT&lt;br /&gt;
 # Note: returns code of 0 if command returns 0, but wait() encoded value for all other values&lt;br /&gt;
&lt;br /&gt;
Quick and dirty old method (prints stderr, captures stdout)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import os&lt;br /&gt;
out = string.join( os.popen(cmd).readlines() )&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Quick and dirty old method (prints stderr, captures stdout, captures ugly wait() encoded return code)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import os&lt;br /&gt;
p = os.popen(cmd)&lt;br /&gt;
stdout = &amp;quot;&amp;quot;.join( p.readlines() )&lt;br /&gt;
encoded_wait_code = p.close()  # None if 0&lt;br /&gt;
rcode = os.WEXITSTATUS(ugly_rcode) # fix ugly wait() encoded rcode&lt;br /&gt;
print(stdout)&lt;br /&gt;
print(rcode)&lt;br /&gt;
&lt;br /&gt;
if os.popen(cmd).close():&lt;br /&gt;
  print &amp;quot;error with cmd: %s&amp;quot; % cmd&lt;br /&gt;
  sys.exit(1)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
???:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
os.spawnvp(os.P_WAIT,&amp;quot;/usr/bin/mplayer&amp;quot;,[&amp;quot;&amp;quot;,&amp;quot;-ao&amp;quot;,&amp;quot;pcm&amp;quot;,file])&lt;br /&gt;
# or &lt;br /&gt;
os.spawnvp(os.P_NOWAIT,&amp;quot;/usr/bin/mplayer&amp;quot;,[&amp;quot;&amp;quot;,&amp;quot;-ao&amp;quot;,&amp;quot;pcm&amp;quot;,file])&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Replacing os.system(): [http://docs.python.org/library/subprocess.html]&lt;br /&gt;
 # old:&lt;br /&gt;
 sts = os.system(&amp;quot;mycmd&amp;quot; + &amp;quot; myarg&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
 # new:&lt;br /&gt;
 p = Popen(&amp;quot;mycmd&amp;quot; + &amp;quot; myarg&amp;quot;, shell=True)&lt;br /&gt;
 sts = os.waitpid(p.pid, 0)[1]&lt;br /&gt;
&lt;br /&gt;
More realistic example replacing os.system(): [http://docs.python.org/library/subprocess.html]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
try:&lt;br /&gt;
    retcode = call(&amp;quot;mycmd&amp;quot; + &amp;quot; myarg&amp;quot;, shell=True)&lt;br /&gt;
    if retcode &amp;lt; 0:&lt;br /&gt;
        print &amp;gt;&amp;gt;sys.stderr, &amp;quot;Child was terminated by signal&amp;quot;, -retcode&lt;br /&gt;
    else:&lt;br /&gt;
        print &amp;gt;&amp;gt;sys.stderr, &amp;quot;Child returned&amp;quot;, retcode&lt;br /&gt;
except OSError, e:&lt;br /&gt;
    print &amp;gt;&amp;gt;sys.stderr, &amp;quot;Execution failed:&amp;quot;, e&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== select ====&lt;br /&gt;
&lt;br /&gt;
Select:&lt;br /&gt;
&lt;br /&gt;
select.select(rlist, wlist, xlist[, timeout])&lt;br /&gt;
: This is a straightforward interface to the Unix select() system call. The first three arguments are sequences of ‘waitable objects’: either integers representing file descriptors or objects with a parameterless method named fileno() returning such an integer&lt;br /&gt;
: The optional timeout argument specifies a time-out as a floating point number in seconds. When the timeout argument is omitted the function blocks until at least one file descriptor is ready. A time-out value of zero specifies a poll and never blocks.&lt;br /&gt;
&lt;br /&gt;
 if select.select([sys.stdin.fileno()], [], [], .1)[0]:&lt;br /&gt;
     line = p.stdout.readline()&lt;br /&gt;
&lt;br /&gt;
==== full wrapped execution ====&lt;br /&gt;
&lt;br /&gt;
Process timeout (by Kenneth):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import subprocess&lt;br /&gt;
import time&lt;br /&gt;
import os&lt;br /&gt;
import signal&lt;br /&gt;
&lt;br /&gt;
def cmd(cmd, timeout=300, retry=0):&lt;br /&gt;
    # Execute command, time progress, and kill on timeout&lt;br /&gt;
&lt;br /&gt;
    # (status, output) = commands.getstatusoutput(cmd)&lt;br /&gt;
    start_time = None&lt;br /&gt;
    status = None&lt;br /&gt;
    output = None&lt;br /&gt;
    for retry_count in range(retry+1):&lt;br /&gt;
        if retry_count &amp;gt; 0:&lt;br /&gt;
            print(&amp;quot;RETRY: &amp;quot; + str(retry_count) + &amp;quot; &amp;quot; + cmd)&lt;br /&gt;
        start_time = time.time()&lt;br /&gt;
        p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE,&lt;br /&gt;
                stderr=subprocess.STDOUT)&lt;br /&gt;
        timeout_fail = False&lt;br /&gt;
        while p.poll() == None:&lt;br /&gt;
            if time.time() - start_time &amp;gt; timeout:&lt;br /&gt;
                # kill process&lt;br /&gt;
                print(&amp;quot;TIMEOUT: &amp;quot; + str(timeout) + &amp;quot;sec - killing (&amp;quot; + str(p.pid) + &amp;quot;) - &amp;quot; + cmd)&lt;br /&gt;
                try:&lt;br /&gt;
                    os.kill(p.pid, signal.SIGTERM)&lt;br /&gt;
                except OSError as e:&lt;br /&gt;
                    print(&amp;quot;Kill exception: &amp;quot; + str(e))&lt;br /&gt;
                timeout_fail = True&lt;br /&gt;
                break&lt;br /&gt;
            #print(&amp;quot;.&amp;quot;)&lt;br /&gt;
            time.sleep(1)&lt;br /&gt;
        status = p.poll()&lt;br /&gt;
        output = p.stdout.read()&lt;br /&gt;
        if timeout_fail == False:&lt;br /&gt;
            break&lt;br /&gt;
    seconds = int(time.time() - start_time)&lt;br /&gt;
    return (status, output, seconds)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
Process input and output wrapper (from minecraft):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import subprocess&lt;br /&gt;
import select&lt;br /&gt;
import re&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
cmd = &amp;quot;/usr/bin/java -Xms256M -Xmx1024M -jar minecraft_server.jar nogui&amp;quot;&lt;br /&gt;
&lt;br /&gt;
p = subprocess.Popen(cmd, shell=True,&lt;br /&gt;
        stdin=subprocess.PIPE,&lt;br /&gt;
        stdout=subprocess.PIPE,&lt;br /&gt;
        stderr=subprocess.STDOUT)&lt;br /&gt;
&lt;br /&gt;
# cycle while process continues alive&lt;br /&gt;
while p.poll() == None:&lt;br /&gt;
&lt;br /&gt;
    if select.select([p.stdout.fileno()], [], [], 1)[0]:&lt;br /&gt;
        while select.select([p.stdout.fileno()], [], [], .1)[0]:&lt;br /&gt;
            line = p.stdout.readline()&lt;br /&gt;
            # &amp;lt;kiloforce&amp;gt; -tp joe&lt;br /&gt;
            match = re.findall(&amp;quot;&amp;lt;(.*)&amp;gt; -tp (.*)&amp;quot;, line)&lt;br /&gt;
            if match:&lt;br /&gt;
                user1 = match[0][0]&lt;br /&gt;
                user2 = match[0][1]&lt;br /&gt;
                print &amp;quot;&amp;gt;&amp;gt; ACTION: Teleporting %s to %s&amp;quot; % (user1, user2)&lt;br /&gt;
                p.stdin.write(&amp;quot;tp %s %s\n&amp;quot; % (user1, user2))&lt;br /&gt;
            if line:&lt;br /&gt;
                print &amp;quot;&amp;gt;&amp;gt; SERVER: %s&amp;quot; % line.strip()&lt;br /&gt;
            else:&lt;br /&gt;
                print &amp;quot;The server died!&amp;quot;&lt;br /&gt;
                sys.exit(1)&lt;br /&gt;
&lt;br /&gt;
    if select.select([sys.stdin.fileno()], [], [], .1)[0]:&lt;br /&gt;
        line = sys.stdin.readline()&lt;br /&gt;
        print &amp;quot;&amp;gt;&amp;gt; CONSOLE: %s&amp;quot; % line.strip()&lt;br /&gt;
        p.stdin.write(&amp;quot;%s&amp;quot; % line)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Command With Timeout ====&lt;br /&gt;
&lt;br /&gt;
python - Using module &#039;subprocess&#039; with timeout - Stack Overflow - http://stackoverflow.com/questions/1191374/using-module-subprocess-with-timeout&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import subprocess, threading&lt;br /&gt;
&lt;br /&gt;
class Command(object):&lt;br /&gt;
    def __init__(self, cmd):&lt;br /&gt;
        self.cmd = cmd&lt;br /&gt;
        self.process = None&lt;br /&gt;
&lt;br /&gt;
    def run(self, timeout):&lt;br /&gt;
        def target():&lt;br /&gt;
            print &#039;Thread started&#039;&lt;br /&gt;
            self.process = subprocess.Popen(self.cmd, shell=True)&lt;br /&gt;
            self.process.communicate()&lt;br /&gt;
            print &#039;Thread finished&#039;&lt;br /&gt;
&lt;br /&gt;
        thread = threading.Thread(target=target)&lt;br /&gt;
        thread.start()&lt;br /&gt;
&lt;br /&gt;
        thread.join(timeout)&lt;br /&gt;
        if thread.is_alive():&lt;br /&gt;
            print &#039;Terminating process&#039;&lt;br /&gt;
            self.process.terminate()&lt;br /&gt;
            thread.join()&lt;br /&gt;
        print self.process.returncode&lt;br /&gt;
&lt;br /&gt;
command = Command(&amp;quot;echo &#039;Process started&#039;; sleep 2; echo &#039;Process finished&#039;&amp;quot;)&lt;br /&gt;
command.run(timeout=3)&lt;br /&gt;
command.run(timeout=1)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
My version:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import subprocess&lt;br /&gt;
import threading&lt;br /&gt;
&lt;br /&gt;
class Command(object):&lt;br /&gt;
    def __init__(self, cmd, capture=False, shell=True):&lt;br /&gt;
        self.cmd = cmd&lt;br /&gt;
        self.process = None&lt;br /&gt;
        self.thread = None&lt;br /&gt;
        self.shell = shell&lt;br /&gt;
        if type(cmd) == list:&lt;br /&gt;
            self.shell = False&lt;br /&gt;
        self.rc = None&lt;br /&gt;
        self.pid = None&lt;br /&gt;
        self.stdout = None&lt;br /&gt;
        self.stderr = None&lt;br /&gt;
        self.capture = capture  # capture stdout?&lt;br /&gt;
&lt;br /&gt;
    def run(self, timeout=None, wait=True):&lt;br /&gt;
        def target():&lt;br /&gt;
            print &#039;&amp;gt;&amp;gt; Thread started (%s)&#039; % self.cmd&lt;br /&gt;
            if self.capture:&lt;br /&gt;
                self.process = subprocess.Popen(self.cmd, shell=self.shell, stdout=subprocess.PIPE, stderr=subprocess.PIPE)&lt;br /&gt;
            else:&lt;br /&gt;
                self.process = subprocess.Popen(self.cmd, shell=self.shell)&lt;br /&gt;
            print &#039;&amp;gt;&amp;gt; Thread PID: %d&#039; % self.process.pid&lt;br /&gt;
            self.pid = self.process.pid&lt;br /&gt;
            self.stdout, self.stderr = self.process.communicate()&lt;br /&gt;
            self.rc = self.process.returncode&lt;br /&gt;
            print &#039;&amp;gt;&amp;gt; Thread finished: %d&#039; % self.rc&lt;br /&gt;
&lt;br /&gt;
        self.thread = threading.Thread(target=target)&lt;br /&gt;
        self.thread.start()&lt;br /&gt;
&lt;br /&gt;
        if wait:&lt;br /&gt;
            self.wait(timeout)&lt;br /&gt;
        return self  # so you can do: c = Command().run()&lt;br /&gt;
&lt;br /&gt;
    def wait(self, timeout=None):&lt;br /&gt;
        print &#039;&amp;gt;&amp;gt; Waiting for thread...&#039;&lt;br /&gt;
        if timeout:&lt;br /&gt;
            self.thread.join(timeout)&lt;br /&gt;
        else:&lt;br /&gt;
            self.thread.join()&lt;br /&gt;
        if self.thread.is_alive():&lt;br /&gt;
            print &#039;&amp;gt;&amp;gt; Terminating process&#039;&lt;br /&gt;
            self.process.terminate()&lt;br /&gt;
            self.rc = self.process.returncode&lt;br /&gt;
            self.thread.join()&lt;br /&gt;
            if self.thread.is_alive():&lt;br /&gt;
                print &#039;&amp;gt;&amp;gt; Failed to terminate&#039;&lt;br /&gt;
        else:&lt;br /&gt;
            print &#039;&amp;gt;&amp;gt; Thread completed&#039;&lt;br /&gt;
        #print self.process.returncode&lt;br /&gt;
&lt;br /&gt;
    def is_alive(self ):&lt;br /&gt;
        return self.thread.is_alive()&lt;br /&gt;
&lt;br /&gt;
command = Command(&#039;do something&#039;).run()&lt;br /&gt;
&lt;br /&gt;
command2 = Command([&#039;do&#039;, &#039;something&#039;, &#039;long&#039;]).run(wait=False)&lt;br /&gt;
command2.wait(timeout=10)&lt;br /&gt;
&lt;br /&gt;
command3 = Command(&#039;want output&#039;, capture=True).run()&lt;br /&gt;
print command3.stdout&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== System call ===&lt;br /&gt;
&lt;br /&gt;
 os.system(&amp;quot;some_command with args&amp;quot;)&lt;br /&gt;
 os.system(&amp;quot;some_command &amp;lt; input_file | another_command &amp;gt; output_file&amp;quot;)&lt;br /&gt;
 stream = os.popen(&amp;quot;some_command with args&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Here&#039;s a summary of the ways to call external programs and the advantages and disadvantages of each:&lt;br /&gt;
&lt;br /&gt;
1.&lt;br /&gt;
: os.system(&amp;quot;some_command with args&amp;quot;) passes the command and arguments to your system&#039;s shell. This is nice because you can actually run multiple commands at once in this manner and set up pipes and input/output redirection. For example,&lt;br /&gt;
: os.system(&amp;quot;some_command &amp;lt; input_file | another_command &amp;gt; output_file&amp;quot;)&lt;br /&gt;
: However, while this is convenient, you have to manually handle the escaping of shell characters such as spaces, etc. On the other hand, this also lets you run commands which are simply shell commands and not actually external programs.&lt;br /&gt;
: http://docs.python.org/lib/os-process.html&lt;br /&gt;
&lt;br /&gt;
2.&lt;br /&gt;
: stream = os.popen(&amp;quot;some_command with args&amp;quot;) will do the same thing as os.system except that it gives you a file-like object that you can use to access standard input/output for that process. There are 3 other variants of popen that all handle the i/o slightly differently. If you pass everything as a string, then your command is passed to the shell; if you pass them as a list then you don&#039;t need to worry about escaping anything.&lt;br /&gt;
: http://docs.python.org/lib/os-newstreams.html&lt;br /&gt;
&lt;br /&gt;
3.&lt;br /&gt;
: The Popen class of the subprocess module. This is intended as a replacement for os.popen but has the downside of being slightly more complicated by virtue of being so comprehensive. For example, you&#039;d say&lt;br /&gt;
: print Popen(&amp;quot;echo Hello World&amp;quot;, stdout=PIPE, shell=True).stdout.read()&lt;br /&gt;
: instead of&lt;br /&gt;
: print os.popen(&amp;quot;echo Hello World&amp;quot;).read()&lt;br /&gt;
: but it is nice to have all of the options there in one unified class instead of 4 different popen functions.&lt;br /&gt;
: http://docs.python.org/lib/node528.html&lt;br /&gt;
&lt;br /&gt;
4.&lt;br /&gt;
: The call function from the subprocess module. This is basically just like the Popen class and takes all of the same arguments, but it simply wait until the command completes and gives you the return code. For example:&lt;br /&gt;
: return_code = call(&amp;quot;echo Hello World&amp;quot;, shell=True)&lt;br /&gt;
: http://docs.python.org/lib/node529.html&lt;br /&gt;
&lt;br /&gt;
5.&lt;br /&gt;
: The os module also has all of the fork/exec/spawn functions that you&#039;d have in a C program, but I don&#039;t recommend using them directly.&lt;br /&gt;
&lt;br /&gt;
: The subprocess module should probably be what you use.&lt;br /&gt;
&lt;br /&gt;
Source: [http://stackoverflow.com/questions/89228/how-to-call-external-command-in-python]&lt;br /&gt;
&lt;br /&gt;
== Advanced Code ==&lt;br /&gt;
&lt;br /&gt;
=== Executing Code from Command Line ===&lt;br /&gt;
&lt;br /&gt;
 python -c [cmd]&lt;br /&gt;
 # -c cmd : program passed in as string (terminates option list)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python -c &amp;quot;import sys;exec(sys.stdin.read())&amp;quot; &amp;lt;&amp;lt; &amp;quot;EOF&amp;quot;&lt;br /&gt;
def test1():&lt;br /&gt;
  print &amp;quot;test1&amp;quot;&lt;br /&gt;
test1()&lt;br /&gt;
print &amp;quot;test&amp;quot;&lt;br /&gt;
EOF&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Integer Return Code Class ===&lt;br /&gt;
&lt;br /&gt;
Python3 version:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class RC(int):&lt;br /&gt;
  def __new__(cls, rc, stdout=&#039;&#039;, stderr=&#039;&#039;):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;We can&#039;t use use __init__ because int is immutable.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    return super(RC, cls).__new__(cls, rc)&lt;br /&gt;
  def __init__(self, rc, stdout=&#039;&#039;, stderr=&#039;&#039;):&lt;br /&gt;
    super().__init__()&lt;br /&gt;
    self.rc = rc  # redundant&lt;br /&gt;
    self.stdout = stdout&lt;br /&gt;
    self.stderr = stderr&lt;br /&gt;
  def __repr__(self):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;Optional string output&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    return &amp;quot;(%s, &#039;%s&#039;, &#039;%s&#039;)&amp;quot; % (self.rc, self.stdout, self.stderr)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Python2 version:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class RC(int):&lt;br /&gt;
  def __new__(cls, rc, stdout=&#039;&#039;, stderr=&#039;&#039;):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;We can&#039;t use use __init__ because int is immutable.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    return super(RC, cls).__new__(cls, rc)&lt;br /&gt;
  def __init__(self, rc, stdout=&#039;&#039;, stderr=&#039;&#039;):&lt;br /&gt;
    super(self.__class__, self).__init__(rc)&lt;br /&gt;
    self.rc = rc  # redundant&lt;br /&gt;
    self.stdout = stdout&lt;br /&gt;
    self.stderr = stderr&lt;br /&gt;
  def __repr__(self):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;Optional string output&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    return &amp;quot;(%s, &#039;%s&#039;, &#039;%s&#039;)&amp;quot; % (self, self.stdout, self.stderr)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
sample:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; rc1 = RC(5)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; rc2 = RC(0, &#039;out&#039;, &#039;err&#039;)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; rc1&lt;br /&gt;
(5, &#039;&#039;, &#039;&#039;)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; rc2&lt;br /&gt;
(5, &#039;out&#039;, &#039;err&#039;)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; rc2.stdout&lt;br /&gt;
&#039;out&#039;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; int(rc1)&lt;br /&gt;
5&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; 0 + rc1&lt;br /&gt;
5&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; if rc1 &amp;lt;= 5:  print &amp;quot;yes&amp;quot;&lt;br /&gt;
...&lt;br /&gt;
yes&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; if rc2:  print &amp;quot;non-zero&amp;quot;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Smart Execute ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class RC(int):&lt;br /&gt;
    def __new__(cls, rc, output=&#039;&#039;):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;We can&#039;t use use __init__ because int is immutable.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        return super(RC, cls).__new__(cls, rc)&lt;br /&gt;
    def __init__(self, rc, output=&#039;&#039;):&lt;br /&gt;
        super().__init__()&lt;br /&gt;
        self.rc = rc  # redundant&lt;br /&gt;
        self.output = output&lt;br /&gt;
    def __repr__(self):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Optional string output&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        return &amp;quot;(%s, &#039;%s&#039;)&amp;quot; % (self.rc, self.output)&lt;br /&gt;
&lt;br /&gt;
def smart_execute(cmd, display=True, checked=False):&lt;br /&gt;
    output = &amp;quot;&amp;quot;&lt;br /&gt;
    process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, bufsize=1, shell=True, encoding=&#039;utf-8&#039;)&lt;br /&gt;
    for c in iter(lambda: process.stdout.read(1), &amp;quot;&amp;quot;):&lt;br /&gt;
        if display:&lt;br /&gt;
            sys.stdout.buffer.write(c.encode(&#039;utf-8&#039;))&lt;br /&gt;
        output += c&lt;br /&gt;
    process.stdout.close()&lt;br /&gt;
    rc = process.wait()&lt;br /&gt;
    if checked and rc:&lt;br /&gt;
        raise subprocess.CalledProcessError(ret, cmd)&lt;br /&gt;
    return RC(rc, output.strip())&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Not smart version:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def execute(cmd, return_output=False):&lt;br /&gt;
    out = &amp;quot;&amp;quot;&lt;br /&gt;
    process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, bufsize=1, shell=True, encoding=&#039;utf-8&#039;)&lt;br /&gt;
    for c in iter(lambda: process.stdout.read(1), &amp;quot;&amp;quot;):&lt;br /&gt;
        sys.stdout.buffer.write(c.encode(&#039;utf-8&#039;))&lt;br /&gt;
        if return_output:&lt;br /&gt;
            out += c&lt;br /&gt;
    process.stdout.close()&lt;br /&gt;
    ret = process.wait()&lt;br /&gt;
    if ret:&lt;br /&gt;
        raise subprocess.CalledProcessError(ret, cmd)&lt;br /&gt;
    if return_output:&lt;br /&gt;
        return out.strip()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== select ===&lt;br /&gt;
&lt;br /&gt;
usage: select.select(rlist, wlist, xlist[, timeout]) [http://docs.python.org/2/library/select.html]&lt;br /&gt;
* rlist: wait until ready for reading&lt;br /&gt;
* wlist: wait until ready for writing&lt;br /&gt;
* xlist: wait for an “exceptional condition” (see the manual page for what your system considers such a condition)&lt;br /&gt;
* The optional timeout argument specifies a time-out as a floating point number in seconds.&lt;br /&gt;
&lt;br /&gt;
 if select.select([p.stdout.fileno()], [], [], 1)[0]:&lt;br /&gt;
&lt;br /&gt;
=== ANSI Color ===&lt;br /&gt;
&lt;br /&gt;
* ANSI escape code - http://en.wikipedia.org/wiki/ANSI_escape_code&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
unicode - Print in terminal with colors using Python? - Stack Overflow - https://stackoverflow.com/questions/287871/print-in-terminal-with-colors-using-python&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class bcolors:&lt;br /&gt;
    HEADER = &#039;\033[95m&#039;&lt;br /&gt;
    OKBLUE = &#039;\033[94m&#039;&lt;br /&gt;
    OKGREEN = &#039;\033[92m&#039;&lt;br /&gt;
    WARNING = &#039;\033[93m&#039;&lt;br /&gt;
    FAIL = &#039;\033[91m&#039;&lt;br /&gt;
    ENDC = &#039;\033[0m&#039;&lt;br /&gt;
    BOLD = &#039;\033[1m&#039;&lt;br /&gt;
    UNDERLINE = &#039;\033[4m&#039;&lt;br /&gt;
&lt;br /&gt;
print bcolors.WARNING + &amp;quot;Warning: No active frommets remain. Continue?&amp;quot; + bcolors.ENDC&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class colors:&lt;br /&gt;
  black = 0&lt;br /&gt;
  red = 1&lt;br /&gt;
  green = 2&lt;br /&gt;
  yellow = 3&lt;br /&gt;
  blue = 4&lt;br /&gt;
  magenta = 5&lt;br /&gt;
  cyan = 6&lt;br /&gt;
  white = 7&lt;br /&gt;
  fg = 30  # foreground add&lt;br /&gt;
  bg = 40  # background add&lt;br /&gt;
  bfg = 90  # bold foreground add&lt;br /&gt;
  bbg = 100  # bold background add&lt;br /&gt;
&lt;br /&gt;
print &#039;\033[%dm red foreground \033[0m&#039; % (colors.red + colors.fg)&lt;br /&gt;
print &#039;\033[%dm bold red foreground \033[0m&#039; % (colors.red + colors.bfg)&lt;br /&gt;
print &#039;\033[%dm blue background \033[0m&#039; % (colors.blue + colors.bg)&lt;br /&gt;
print &#039;\033[%dm bold blue background \033[0m&#039; % (colors.blue + colors.bbg)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
Before you start spouting escape sequences, you should check that stdout is a tty. You can do this with sys.stdout.isatty()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sys.stdout.isatty()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def hilite(string, status, bold):&lt;br /&gt;
    attr = []&lt;br /&gt;
    if status:&lt;br /&gt;
        # green&lt;br /&gt;
        attr.append(&#039;32&#039;)&lt;br /&gt;
    else:&lt;br /&gt;
        # red&lt;br /&gt;
        attr.append(&#039;31&#039;)&lt;br /&gt;
    if bold:&lt;br /&gt;
        attr.append(&#039;1&#039;)&lt;br /&gt;
    return &#039;\x1b[%sm%s\x1b[0m&#039; % (&#039;;&#039;.join(attr), string)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Python | change text color in shell - Stack Overflow - https://stackoverflow.com/questions/2330245/python-change-text-color-in-shell&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
For reference, a small bash script which prints a table of escape sequences: colortable16.sh: ([http://www.frexx.de/xterm-256-notes/ The 256 color mode of xterm], [http://plug.org/pipermail/plug/2008-March/016821.html The 90s called; they want their 256 colors back])&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
&lt;br /&gt;
# prints a color table of 8bg * 8fg * 2 states (regular/bold)&lt;br /&gt;
echo&lt;br /&gt;
echo Table for 16-color terminal escape sequences.&lt;br /&gt;
echo Replace ESC with \\033 in bash.&lt;br /&gt;
echo&lt;br /&gt;
echo &amp;quot;Background | Foreground colors&amp;quot;&lt;br /&gt;
echo &amp;quot;---------------------------------------------------------------------&amp;quot;&lt;br /&gt;
for((bg=40;bg&amp;lt;=47;bg++)); do&lt;br /&gt;
	for((bold=0;bold&amp;lt;=1;bold++)) do&lt;br /&gt;
		echo -en &amp;quot;\033[0m&amp;quot;&amp;quot; ESC[${bg}m   | &amp;quot;&lt;br /&gt;
		for((fg=30;fg&amp;lt;=37;fg++)); do&lt;br /&gt;
			if [ $bold == &amp;quot;0&amp;quot; ]; then&lt;br /&gt;
				echo -en &amp;quot;\033[${bg}m\033[${fg}m [${fg}m  &amp;quot;&lt;br /&gt;
			else&lt;br /&gt;
				echo -en &amp;quot;\033[${bg}m\033[1;${fg}m [1;${fg}m&amp;quot;&lt;br /&gt;
			fi&lt;br /&gt;
		done&lt;br /&gt;
		echo -e &amp;quot;\033[0m&amp;quot;&lt;br /&gt;
	done&lt;br /&gt;
	echo &amp;quot;--------------------------------------------------------------------- &amp;quot;&lt;br /&gt;
done&lt;br /&gt;
&lt;br /&gt;
echo&lt;br /&gt;
echo&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Python version: (modified by me)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
# prints a color table of 8bg * 8fg * 2 states (regular/bold)&lt;br /&gt;
print&lt;br /&gt;
print &amp;quot;Table for 16-color terminal escape sequences.&amp;quot;&lt;br /&gt;
print &amp;quot;Replace ESC with \\033 in bash.&amp;quot;&lt;br /&gt;
print&lt;br /&gt;
print &amp;quot;Background | Foreground colors&amp;quot;&lt;br /&gt;
print &amp;quot;---------------------------------------------------------------------&amp;quot;&lt;br /&gt;
for bg in range(40, 47+1):&lt;br /&gt;
  for bold in range(0, 1+1):&lt;br /&gt;
                sys.stdout.write(&amp;quot;\033[0m&amp;quot;&amp;quot; ESC[{bg}m   | &amp;quot;.format(bg=bg))&lt;br /&gt;
                for fg in range(30, 37+1):&lt;br /&gt;
                        if bold == 0:&lt;br /&gt;
                                sys.stdout.write(&amp;quot;\033[{bg}m\033[{fg}m [{fg}m  &amp;quot;.format(bg=bg, fg=fg))&lt;br /&gt;
                        else:&lt;br /&gt;
                                sys.stdout.write(&amp;quot;\033[{bg}m\033[1;{fg}m [1;{fg}m&amp;quot;.format(bg=bg, fg=fg))&lt;br /&gt;
                sys.stdout.write(&amp;quot;\033[0m\n&amp;quot;)&lt;br /&gt;
  print &amp;quot;--------------------------------------------------------------------- &amp;quot;&lt;br /&gt;
&lt;br /&gt;
print&lt;br /&gt;
print&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Execute External Application ===&lt;br /&gt;
&lt;br /&gt;
Execute program: (and send output to STDOUT)&lt;br /&gt;
 encoded_wait_code = os.system(&#039;mkdir mydir&#039;)  # output sent to STDOUT&lt;br /&gt;
&lt;br /&gt;
Get output and ugly return code: (STDERR goes to STDOUT)&lt;br /&gt;
 p = os.popen(cmd)&lt;br /&gt;
 print p.readlines()&lt;br /&gt;
 encoded_wait_code = p.close()&lt;br /&gt;
&lt;br /&gt;
Execute other python script&lt;br /&gt;
 import sys&lt;br /&gt;
 sys.argv = [, &#039;my&#039;, &#039;args&#039;, &#039;here&#039;]&lt;br /&gt;
 execfile(&#039;myscript.py&#039;)  # does not support arguments directly&lt;br /&gt;
&lt;br /&gt;
Subprocess:&lt;br /&gt;
* See [[#Subprocess]]&lt;br /&gt;
&lt;br /&gt;
=== Program Layout ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
PackageName/&lt;br /&gt;
    README&lt;br /&gt;
    setup.py&lt;br /&gt;
    bin/&lt;br /&gt;
        script&lt;br /&gt;
    docs/&lt;br /&gt;
    test/  # some include in package_name&lt;br /&gt;
    pacakgename/&lt;br /&gt;
        __init__.py&lt;br /&gt;
        code1.py&lt;br /&gt;
        subpackage/&lt;br /&gt;
            __init__.py&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== __init__.py ===&lt;br /&gt;
&lt;br /&gt;
Purpose: Makes the folder into a package library&lt;br /&gt;
&lt;br /&gt;
NOTE: This file is most commonly blank&lt;br /&gt;
&lt;br /&gt;
Good place to put your package functions.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# ken/__init__.py&lt;br /&gt;
def load():&lt;br /&gt;
  ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import ken&lt;br /&gt;
ken.load()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Can import other modules to then use as package modules:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# ken/__init__.py&lt;br /&gt;
from ken.client import Server&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import ken&lt;br /&gt;
ken.Server()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Good place to put your Exceptions.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class MyException(Exception):&lt;br /&gt;
  &amp;quot;&amp;quot;&amp;quot; My Error Exception &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use the __all__ to specify what gets imported on &#039;from package import *&#039;&lt;br /&gt;
  __all__ = [&#039;func1&#039;, &#039;func2&#039;]&lt;br /&gt;
&lt;br /&gt;
=== Metadata ===&lt;br /&gt;
&lt;br /&gt;
 VERSION = (0, 2, 1)&lt;br /&gt;
or&lt;br /&gt;
 __version__ = &#039;0.2.1&#039;&lt;br /&gt;
&lt;br /&gt;
Also See [[#pydoc]]&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
 __version__ = &#039;1.10&#039;&lt;br /&gt;
 __author__ = &#039;Joshua Roesslein&#039;&lt;br /&gt;
 __license__ = &#039;MIT&#039;&lt;br /&gt;
&lt;br /&gt;
=== setup.py ===&lt;br /&gt;
&lt;br /&gt;
See [[#Distributing Python Modules with Distutils]]&lt;br /&gt;
&lt;br /&gt;
=== Distributing Python Modules with Distutils ===&lt;br /&gt;
&lt;br /&gt;
Distributing Python Modules — http://docs.python.org/distutils/index.html&lt;br /&gt;
&lt;br /&gt;
Uses setup.py for package installation.&lt;br /&gt;
 python setup.py install&lt;br /&gt;
&lt;br /&gt;
==== Simple example ====&lt;br /&gt;
&lt;br /&gt;
To install foo.py:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from distutils.core import setup&lt;br /&gt;
setup(name=&#039;foo&#039;,&lt;br /&gt;
      version=&#039;1.0&#039;,&lt;br /&gt;
      py_modules=[&#039;foo&#039;],&lt;br /&gt;
      )&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Source: http://docs.python.org/distutils/introduction.html&lt;br /&gt;
&lt;br /&gt;
==== klib example ====&lt;br /&gt;
&lt;br /&gt;
klib setup.py:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from distutils.core import setup&lt;br /&gt;
&lt;br /&gt;
setup(name = &amp;quot;klib&amp;quot;,&lt;br /&gt;
    version = &amp;quot;101&amp;quot;,&lt;br /&gt;
    description = &amp;quot;klib library&amp;quot;,&lt;br /&gt;
    url = &amp;quot;http://www.oeey.com/klib&amp;quot;,&lt;br /&gt;
    author = &amp;quot;Kenneth&amp;quot;,&lt;br /&gt;
    author_email = &amp;quot;kenneth@oeey.com&amp;quot;,&lt;br /&gt;
    license = &amp;quot;Kenneth License&amp;quot;,&lt;br /&gt;
    long_description = &amp;quot;&amp;quot;&amp;quot;Really long text here.&amp;quot;&amp;quot;&amp;quot;,&lt;br /&gt;
    platforms = &amp;quot;Any Platform&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
    packages = [&#039;klib&#039;,&#039;klib.messenger&#039;],&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Installed to:&lt;br /&gt;
 /opt/python26/lib/python2.6/site-packages/klib/&lt;br /&gt;
 /opt/python26/lib/python2.6/site-packages/klib-100-py2.6.egg-info&lt;br /&gt;
&lt;br /&gt;
Metadata: (/opt/python26/lib/python2.6/site-packages/klib-101-py2.6.egg-info)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Metadata-Version: 1.0&lt;br /&gt;
Name: klib&lt;br /&gt;
Version: 101&lt;br /&gt;
Summary: klib library&lt;br /&gt;
Home-page: http://www.oeey.com/klib&lt;br /&gt;
Author: Kenneth&lt;br /&gt;
Author-email: kenneth@oeey.com&lt;br /&gt;
License: Kenneth License&lt;br /&gt;
Description: Really long text here.&lt;br /&gt;
Platform: Any platform&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Any fields not included will be marked:&lt;br /&gt;
 Platform: UNKNOWN&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* 2. Writing the Setup Script — Python v2.7.2 documentation - http://docs.python.org/distutils/setupscript.html&lt;br /&gt;
* http://wiki.python.org/moin/Distutils/Tutorial&lt;br /&gt;
&lt;br /&gt;
==== Uninstall Package ====&lt;br /&gt;
&lt;br /&gt;
Collect files during install:&lt;br /&gt;
 python setup.py install --record install-record.txt&lt;br /&gt;
 sudo rm $(cat install-record.txt)&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* installation - python setup.py uninstall - Stack Overflow - http://stackoverflow.com/questions/1550226/python-setup-py-uninstall&lt;br /&gt;
&lt;br /&gt;
=== Distributing Python Modules with Setuptools ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
import setuptools&lt;br /&gt;
&lt;br /&gt;
setuptools.setup(name=&amp;quot;tweepy&amp;quot;,&lt;br /&gt;
      version=&amp;quot;1.10&amp;quot;,&lt;br /&gt;
      description=&amp;quot;Twitter library for python&amp;quot;,&lt;br /&gt;
      license=&amp;quot;MIT&amp;quot;,&lt;br /&gt;
      author=&amp;quot;Joshua Roesslein&amp;quot;,&lt;br /&gt;
      author_email=&amp;quot;tweepy@googlegroups.com&amp;quot;,&lt;br /&gt;
      url=&amp;quot;http://github.com/tweepy/tweepy&amp;quot;,&lt;br /&gt;
      packages = setuptools.find_packages(),&lt;br /&gt;
      keywords= &amp;quot;twitter library&amp;quot;,&lt;br /&gt;
      zip_safe = True)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Decorators ===&lt;br /&gt;
&lt;br /&gt;
Decorators wrap functions&lt;br /&gt;
&lt;br /&gt;
Function Counter: [http://stackoverflow.com/questions/739654/understanding-python-decorators]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def fcount(func):&lt;br /&gt;
    def wrapper(*args, **kw):&lt;br /&gt;
        wrapper.count = wrapper.count + 1&lt;br /&gt;
        return func(*args, **kw)&lt;br /&gt;
    wrapper.count = 0&lt;br /&gt;
    return wrapper&lt;br /&gt;
&lt;br /&gt;
@fcount&lt;br /&gt;
def f(n):&lt;br /&gt;
    return n*n&lt;br /&gt;
&lt;br /&gt;
print &amp;quot;f.count = &amp;quot;, f.count&lt;br /&gt;
print &amp;quot;f(10) = &amp;quot;, f(10)&lt;br /&gt;
print &amp;quot;f.count = &amp;quot;, f.count&lt;br /&gt;
print &amp;quot;f(3) = &amp;quot;, f(3)&lt;br /&gt;
print &amp;quot;f.count = &amp;quot;, f.count&lt;br /&gt;
print &amp;quot;f(12) = &amp;quot;, f(12)&lt;br /&gt;
print &amp;quot;f.count = &amp;quot;, f.count&lt;br /&gt;
print &amp;quot;f(15) = &amp;quot;, f(15)&lt;br /&gt;
print &amp;quot;f.count = &amp;quot;, f.count&lt;br /&gt;
&lt;br /&gt;
# Output:&lt;br /&gt;
# f.count =  0&lt;br /&gt;
# f(10) =  100&lt;br /&gt;
# f.count =  1&lt;br /&gt;
# f(3) =  9&lt;br /&gt;
# f.count =  2&lt;br /&gt;
# f(12) =  144&lt;br /&gt;
# f.count =  3&lt;br /&gt;
# f(15) =  225&lt;br /&gt;
# f.count =  4&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Great reference: Understanding Python decorators - Stack Overflow - http://stackoverflow.com/questions/739654/understanding-python-decorators&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Example 1:&lt;br /&gt;
 @dec1&lt;br /&gt;
 def func(arg1, arg2, ...): pass&lt;br /&gt;
&lt;br /&gt;
 # equivalent to:&lt;br /&gt;
 def func(arg1, arg2, ...): pass&lt;br /&gt;
 func = dec1(func)&lt;br /&gt;
&lt;br /&gt;
Example 2:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
@dec2&lt;br /&gt;
@dec1&lt;br /&gt;
def func(arg1, arg2, ...):&lt;br /&gt;
    pass&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# equivalent to:&lt;br /&gt;
def func(arg1, arg2, ...):&lt;br /&gt;
    pass&lt;br /&gt;
func = dec2(dec1(func))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example 3:&lt;br /&gt;
 @decomaker(argA, argB, ...)&lt;br /&gt;
 def func(arg1, arg2, ...):&lt;br /&gt;
     pass&lt;br /&gt;
&lt;br /&gt;
 # equivalent to:&lt;br /&gt;
 func = decomaker(argA, argB, ...)(func)&lt;br /&gt;
&lt;br /&gt;
 # example:&lt;br /&gt;
 @accepts(int,int)&lt;br /&gt;
 @returns(float)&lt;br /&gt;
 def bar(low,high):&lt;br /&gt;
     pass&lt;br /&gt;
&lt;br /&gt;
Example 4: (overrides and ignores passed in function - bad, unless desired)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def spamrun(fn):&lt;br /&gt;
    def sayspam(*args):&lt;br /&gt;
        print &amp;quot;spam, spam, spam&amp;quot;&lt;br /&gt;
    return sayspam&lt;br /&gt;
&lt;br /&gt;
@spamrun&lt;br /&gt;
def useful(a, b):&lt;br /&gt;
    print a**2 + b**2&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example 5: (Decorator that modifies behavior of undecorated func)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def addspam(fn):&lt;br /&gt;
    def new(*args):&lt;br /&gt;
        print &amp;quot;spam, spam, spam&amp;quot;&lt;br /&gt;
        return fn(*args)&lt;br /&gt;
    return new&lt;br /&gt;
&lt;br /&gt;
@addspam&lt;br /&gt;
def useful(a, b):&lt;br /&gt;
    print a**2 + b**2&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
My Example 1: (print args and continue to function)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def showargs(fn):&lt;br /&gt;
    def doshowargs(*args, **kw):&lt;br /&gt;
        print &amp;quot;Args for:&amp;quot;, fn.__name__, args, kw&lt;br /&gt;
        return fn(*args, **kw)&lt;br /&gt;
    return doshowargs&lt;br /&gt;
&lt;br /&gt;
@showargs&lt;br /&gt;
def useful(a, b):&lt;br /&gt;
    print a**2 + b**2&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Another Example: [http://stackoverflow.com/questions/739654/understanding-python-decorators]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def makebold(fn):&lt;br /&gt;
    def wrapped(*args, **kw):&lt;br /&gt;
        return &amp;quot;&amp;lt;b&amp;gt;&amp;quot; + fn(*args, **kw) + &amp;quot;&amp;lt;/b&amp;gt;&amp;quot;&lt;br /&gt;
    return wrapped&lt;br /&gt;
&lt;br /&gt;
def makeitalic(fn):&lt;br /&gt;
    def wrapped(*args, **kw):&lt;br /&gt;
        return &amp;quot;&amp;lt;i&amp;gt;&amp;quot; + fn(*args, **kw) + &amp;quot;&amp;lt;/i&amp;gt;&amp;quot;&lt;br /&gt;
    return wrapped&lt;br /&gt;
&lt;br /&gt;
@makebold&lt;br /&gt;
@makeitalic&lt;br /&gt;
def hello(msg):&lt;br /&gt;
    return msg&lt;br /&gt;
&lt;br /&gt;
print hello(&amp;quot;hello world&amp;quot;)&lt;br /&gt;
# output: &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;hello world&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* PEP 318 -- Decorators for Functions and Methods - http://www.python.org/dev/peps/pep-0318/&lt;br /&gt;
* Charming Python: Decorators make magic easy - http://www.ibm.com/developerworks/linux/library/l-cpdecor/index.html&lt;br /&gt;
* What are some common uses for Python decorators? - Stack Overflow - http://stackoverflow.com/questions/489720/what-are-some-common-uses-for-python-decorators&lt;br /&gt;
* Understanding Python decorators - Stack Overflow - http://stackoverflow.com/questions/739654/understanding-python-decorators&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
Utah Python July 2013 Meeting - Decorator Examples: [https://www.youtube.com/watch?v=uh9uhzitdvw]&lt;br /&gt;
&lt;br /&gt;
Example of uses:&lt;br /&gt;
* Count function calls&lt;br /&gt;
* Add additional output (debugging)&lt;br /&gt;
* Timing code&lt;br /&gt;
* Thread synchronization (locks)&lt;br /&gt;
* Type checking&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
## Simple wrapping call&lt;br /&gt;
def shout(f):&lt;br /&gt;
    def wrapper(*args):&lt;br /&gt;
        print(&#039;This is before {name}&#039;.format(name=f.__name__))&lt;br /&gt;
        ret = f(*args)&lt;br /&gt;
        print(&#039;This is after {name}&#039;.format(name=f.__name__))&lt;br /&gt;
        return ret&lt;br /&gt;
    wrapper.__name__ = f.__name__&lt;br /&gt;
    return wrapper&lt;br /&gt;
&lt;br /&gt;
@shout&lt;br /&gt;
def echo(text):&lt;br /&gt;
    print(text)&lt;br /&gt;
&lt;br /&gt;
echo(&#039;this is a test&#039;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
## Counting function calls&lt;br /&gt;
def count(f):&lt;br /&gt;
    def wrapper(*args):&lt;br /&gt;
        wrapper.counter += 1&lt;br /&gt;
        print(&amp;quot;Function called {count} times&amp;quot;.format(count=wrapper.counter))&lt;br /&gt;
        return f(*args)&lt;br /&gt;
    wrapper.counter = 0&lt;br /&gt;
    # change wrapper name, or it will just be &#039;wrapper&#039; (for inspection)&lt;br /&gt;
    wrapper.__name__ = f.__name__&lt;br /&gt;
    return wrapper&lt;br /&gt;
&lt;br /&gt;
@count&lt;br /&gt;
def donothing():&lt;br /&gt;
    pass&lt;br /&gt;
&lt;br /&gt;
donothing()&lt;br /&gt;
donothing()&lt;br /&gt;
print(&amp;quot;Function called a total of {count} times&amp;quot;.format(count=donothing.counter))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
## Timing your code&lt;br /&gt;
import time&lt;br /&gt;
&lt;br /&gt;
def timer(f):&lt;br /&gt;
    def wrapper(*arg):&lt;br /&gt;
        t = time.time()&lt;br /&gt;
        ret = f(*arg)&lt;br /&gt;
        print(&amp;quot;Took {elapsedtime} seconds&amp;quot;.format(elapsedtime=time.time()-t))&lt;br /&gt;
        return ret&lt;br /&gt;
    return wrapper&lt;br /&gt;
&lt;br /&gt;
@timer&lt;br /&gt;
def fact(n):&lt;br /&gt;
    prod = 1&lt;br /&gt;
    while n &amp;gt; 0:&lt;br /&gt;
        prod *= n&lt;br /&gt;
        n -= 1&lt;br /&gt;
    return prod&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
total = fact(10000)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
## Synchronization&lt;br /&gt;
import threading&lt;br /&gt;
&lt;br /&gt;
def synchronized(lock):&lt;br /&gt;
    def wrap(f):&lt;br /&gt;
        def wrapper(*args, **kwargs):&lt;br /&gt;
            lock.acquire()&lt;br /&gt;
            try:&lt;br /&gt;
                return f(*args, **kwargs)&lt;br /&gt;
            finally:&lt;br /&gt;
                lock.release()&lt;br /&gt;
        return wrapper&lt;br /&gt;
    return wrap&lt;br /&gt;
&lt;br /&gt;
mylock = threading.Lock()&lt;br /&gt;
&lt;br /&gt;
@synchronized(mylock)&lt;br /&gt;
def myfunc():&lt;br /&gt;
    pass&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
## Type checking&lt;br /&gt;
def myMethod(ID, name):&lt;br /&gt;
    &#039;&#039;&#039; Old way &#039;&#039;&#039;&lt;br /&gt;
    if not (isinstance(ID, &#039;uint&#039;) and isinstance(name, &#039;utf8string&#039;)):&lt;br /&gt;
        raise Exception()&lt;br /&gt;
&lt;br /&gt;
def accepts(*typeargs):&lt;br /&gt;
    &#039;&#039;&#039; Decorator way &#039;&#039;&#039;&lt;br /&gt;
    def wrap(f):&lt;br /&gt;
        def wrapper(*args):&lt;br /&gt;
            for a, t in zip(args, typeargs):&lt;br /&gt;
                if not isinstance(a, t):&lt;br /&gt;
                    raise Exception(&#039;{a} not of type {t}&#039;.format(a=a, t=t))&lt;br /&gt;
            return f(*args)&lt;br /&gt;
        return wrapper&lt;br /&gt;
    return wrap&lt;br /&gt;
&lt;br /&gt;
@accepts(int)&lt;br /&gt;
def add1(n):&lt;br /&gt;
    return n + 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
## Memoize&lt;br /&gt;
def memoize(f):&lt;br /&gt;
    def wrapper(*args):&lt;br /&gt;
        if not wrapper.ret:&lt;br /&gt;
            wrapper.ret = f(*args)&lt;br /&gt;
        return wrapper.ret&lt;br /&gt;
    wrapper.ret = False&lt;br /&gt;
    wrapper.__name__ = f.__name__&lt;br /&gt;
    return wrapper&lt;br /&gt;
&lt;br /&gt;
import time&lt;br /&gt;
&lt;br /&gt;
@memoize&lt;br /&gt;
def sumto10():&lt;br /&gt;
    count = 0&lt;br /&gt;
    sum = 0&lt;br /&gt;
    while count &amp;lt; 10:&lt;br /&gt;
        sum += count&lt;br /&gt;
        time.sleep(1)&lt;br /&gt;
        count += 1&lt;br /&gt;
    return sum&lt;br /&gt;
&lt;br /&gt;
# first time will count slow&lt;br /&gt;
print sumto10()&lt;br /&gt;
# second time will return cached value instantly&lt;br /&gt;
print sumto10()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Memoize: &amp;quot;Caches a function&#039;s return value each time it is called. If called later with the same arguments, the cached value is returned (not reevaluated)&amp;quot; [http://wiki.python.org/moin/PythonDecoratorLibrary#Memoize]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
## Nested decorators&lt;br /&gt;
import time&lt;br /&gt;
@shout&lt;br /&gt;
@memoize&lt;br /&gt;
def test1():&lt;br /&gt;
  print &amp;quot;calculating&amp;quot;&lt;br /&gt;
  time.sleep(3)&lt;br /&gt;
  return 100&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Order is important!  For tested decorators the execution order is from the top to the bottom.  If you reverse @shout and @memoize, the @shout will not run because of the way @memoize was written.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
## registry&lt;br /&gt;
registry = []&lt;br /&gt;
# can also decorate decorators:&lt;br /&gt;
@shout&lt;br /&gt;
def registry(f):&lt;br /&gt;
    registry.append(f)&lt;br /&gt;
    return f&lt;br /&gt;
&lt;br /&gt;
@register&lt;br /&gt;
def test2():&lt;br /&gt;
    pass&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Decorator is just a function that returns a function.&lt;br /&gt;
&lt;br /&gt;
Can use functools to automatically update decorator wrappers with __name__, etc [http://docs.python.org/2/library/functools.html]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
## Auto syntax sygar the wrapper for you&lt;br /&gt;
import functools&lt;br /&gt;
def my_decorator(f):&lt;br /&gt;
    @functools.wraps(f)&lt;br /&gt;
    def wrapper(*args, **kwds):&lt;br /&gt;
        print &#039;Calling decorated function&#039;&lt;br /&gt;
        return f(*args, **kwds)&lt;br /&gt;
    return wrapper&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Class Method Decorators ===&lt;br /&gt;
&lt;br /&gt;
Static methods: [http://docs.python.org/library/functions.html#staticmethod]&lt;br /&gt;
: Similar to C++ and Java static methods&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class C:&lt;br /&gt;
  @staticmethod&lt;br /&gt;
  def say(msg):&lt;br /&gt;
    print(msg)&lt;br /&gt;
&lt;br /&gt;
C.say(&#039;hi&#039;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Class method: [http://docs.python.org/library/functions.html#classmethod]&lt;br /&gt;
: A class method receives the class as implicit first argument, just like an instance method receives the instance.&lt;br /&gt;
: Class methods are different than C++ or Java static methods. If you want those, see staticmethod() in this section.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    @classmethod&lt;br /&gt;
    def setup_parser(cls, parser):&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See also [[#Class Properties]]&lt;br /&gt;
&lt;br /&gt;
=== Class Properties ===&lt;br /&gt;
&lt;br /&gt;
Properties: (not using decorators)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class C(object):&lt;br /&gt;
    def __init__(self):&lt;br /&gt;
        self._x = None&lt;br /&gt;
    def getx(self):&lt;br /&gt;
        print(&amp;quot;get x&amp;quot;)&lt;br /&gt;
        return self._x&lt;br /&gt;
    def setx(self, value):&lt;br /&gt;
        print(&amp;quot;set x&amp;quot;)&lt;br /&gt;
        self._x = value&lt;br /&gt;
    def delx(self):&lt;br /&gt;
        print(&amp;quot;del x&amp;quot;)&lt;br /&gt;
        del self._x&lt;br /&gt;
    x = property(getx, setx, delx, &amp;quot;I&#039;m the &#039;x&#039; property.&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#usage&lt;br /&gt;
c = C()&lt;br /&gt;
c.x = 5&lt;br /&gt;
print(c.x)&lt;br /&gt;
del(c.x)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Getter and Setter Property Decorators: [http://docs.python.org/library/functions.html#property]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class C(object):    # make sure to inherit from object for these properties to work!&lt;br /&gt;
    def __init__(self):&lt;br /&gt;
        self._x = None&lt;br /&gt;
    &lt;br /&gt;
    @property&lt;br /&gt;
    def x(self):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;I&#039;m the &#039;x&#039; property.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        print(&amp;quot;get x&amp;quot;)&lt;br /&gt;
        return self._x&lt;br /&gt;
    &lt;br /&gt;
    @x.setter   # python &amp;gt;= 2.6&lt;br /&gt;
    def x(self, value):&lt;br /&gt;
        print(&amp;quot;set x&amp;quot;)&lt;br /&gt;
        self._x = value&lt;br /&gt;
    &lt;br /&gt;
    @x.deleter  # python &amp;gt;= 2.6&lt;br /&gt;
    def x(self):&lt;br /&gt;
        print(&amp;quot;del x&amp;quot;)&lt;br /&gt;
        del self._x&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#usage&lt;br /&gt;
c = C()&lt;br /&gt;
c.x = 5&lt;br /&gt;
print(c.x)&lt;br /&gt;
del(c.x)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: If you don&#039;t add the @x.setter, the property will be read only, and will throw a &amp;quot;AttributeError: can&#039;t set attribute&amp;quot; if attempted to be set.&lt;br /&gt;
&lt;br /&gt;
Using x.getter example: [http://wiki.python.org/moin/AlternativeDescriptionOfProperty]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Cls(object):&lt;br /&gt;
    def __init__(self):&lt;br /&gt;
        self._x = 100&lt;br /&gt;
&lt;br /&gt;
    x = property()&lt;br /&gt;
&lt;br /&gt;
    @x.getter&lt;br /&gt;
    def x(self):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;I&#039;m the &#039;x&#039; property.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        return self._x&lt;br /&gt;
&lt;br /&gt;
    @x.setter&lt;br /&gt;
    def x(self, value):&lt;br /&gt;
        self._x = value&lt;br /&gt;
&lt;br /&gt;
    @x.deleter&lt;br /&gt;
    def x(self):&lt;br /&gt;
        del self._x&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Custom Decorators ===&lt;br /&gt;
&lt;br /&gt;
decorator&lt;br /&gt;
 @dec1&lt;br /&gt;
 def func(arg1, arg2, ...): pass&lt;br /&gt;
&lt;br /&gt;
equivalent to:&lt;br /&gt;
 def func(arg1, arg2, ...): pass&lt;br /&gt;
 func = dec1(func)&lt;br /&gt;
&lt;br /&gt;
Basic layout (names are arbitrary):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def my_decorator(function_name):&lt;br /&gt;
  # update wrapper.__doc__ and .func_name&lt;br /&gt;
  # or @functools.wraps(my_wrapper)&lt;br /&gt;
  def mywrapper(*args, **kw):&lt;br /&gt;
    # do something before&lt;br /&gt;
    result = function_name(*args, **kw)&lt;br /&gt;
    # do something after&lt;br /&gt;
    return result&lt;br /&gt;
  return my_wrapper&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def limit(length):&lt;br /&gt;
  def decorator(function):&lt;br /&gt;
    def wrapper(*args, **kw):&lt;br /&gt;
      result = function(*args, **kw)&lt;br /&gt;
      result = result[:length]&lt;br /&gt;
      return result&lt;br /&gt;
    return wrapper&lt;br /&gt;
  return decorator&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
@limit(3)&lt;br /&gt;
def echo(foo):  return foo&lt;br /&gt;
&lt;br /&gt;
echo(&#039;123456&#039;)  # &#039;123&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== assert ===&lt;br /&gt;
&lt;br /&gt;
 assert True&lt;br /&gt;
 assert False  # exception&lt;br /&gt;
 assert 1 == 1&lt;br /&gt;
 assert 1 == 2, &amp;quot;some message&amp;quot;  # AssertionError: some message&lt;br /&gt;
&lt;br /&gt;
=== Snake Case ===&lt;br /&gt;
&lt;br /&gt;
Convert Camel Case to Snake Case: [http://stackoverflow.com/questions/1175208/elegant-python-function-to-convert-camelcase-to-snake-case]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def snake_case(name):&lt;br /&gt;
    s1 = re.sub(&#039;(.)([A-Z][a-z]+)&#039;, r&#039;\1_\2&#039;, name)&lt;br /&gt;
    return re.sub(&#039;([a-z0-9])([A-Z])&#039;, r&#039;\1_\2&#039;, s1).lower()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; convert(&#039;CamelCase&#039;)&lt;br /&gt;
&#039;camel_case&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Camel Case ===&lt;br /&gt;
&lt;br /&gt;
Camel Case: [http://stackoverflow.com/questions/8347048/camelcase-every-string-any-standard-library]&lt;br /&gt;
&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; &#039;&#039;.join(x for x in &#039;make IT camel CaSe&#039;.title() if not x.isspace())&lt;br /&gt;
 &#039;MakeItCamelCase&#039;&lt;br /&gt;
&lt;br /&gt;
To titleize a sentence:&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; &amp;quot;this is a test&amp;quot;.title()&lt;br /&gt;
 &amp;quot;This Is A Test&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Lambda ===&lt;br /&gt;
&lt;br /&gt;
Simple functions&lt;br /&gt;
 mul = lambda a, b: a * b&lt;br /&gt;
&lt;br /&gt;
 # equivalent to:&lt;br /&gt;
 def mul(a, b):&lt;br /&gt;
   return a * b&lt;br /&gt;
&lt;br /&gt;
Sort usage:&lt;br /&gt;
 data = [dict(number=x) for x in &#039;036149&#039;]&lt;br /&gt;
 data.sort(key=lambda x: float(x[&#039;number&#039;]))&lt;br /&gt;
&lt;br /&gt;
Compare usage:&lt;br /&gt;
 data = [dict(number=x) for x in &#039;036149&#039;]&lt;br /&gt;
 data.sort(cmp=lambda x,y: cmp(x[&#039;number&#039;], y[&#039;number&#039;]))&lt;br /&gt;
&lt;br /&gt;
Boolean:&lt;br /&gt;
 lambda x: x % 3 == 0&lt;br /&gt;
&lt;br /&gt;
Multiple parameter:&lt;br /&gt;
 lambda x, y: x + y&lt;br /&gt;
&lt;br /&gt;
Call another function:&lt;br /&gt;
 lambda word: len(word)&lt;br /&gt;
&lt;br /&gt;
Strings:&lt;br /&gt;
 lambda line: line.split()[2]&lt;br /&gt;
&lt;br /&gt;
Embedded:&lt;br /&gt;
 def transform(n):&lt;br /&gt;
    return lambda x: x + n&lt;br /&gt;
&lt;br /&gt;
No parameters:&lt;br /&gt;
 lambda: 1&lt;br /&gt;
&lt;br /&gt;
Default parameters:&lt;br /&gt;
 lambda x=1: x+1&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* Python: Lambda Functions - http://www.secnetix.de/olli/Python/lambda_functions.hawk&lt;br /&gt;
&lt;br /&gt;
=== Map ===&lt;br /&gt;
&lt;br /&gt;
Apply a function to items of a sequence:&lt;br /&gt;
 map(str, range(3))   # [&#039;0&#039;, &#039;1&#039;, &#039;2&#039;]&lt;br /&gt;
&lt;br /&gt;
Note: list comprehensions can replace map and filter&lt;br /&gt;
&lt;br /&gt;
=== Reduce ===&lt;br /&gt;
&lt;br /&gt;
Apply a function to pairs of the sequence:&lt;br /&gt;
 import operator&lt;br /&gt;
 reduce(operator.mul, [1,2,3,4])   # 24   - ((1*2)*3)*4)&lt;br /&gt;
&lt;br /&gt;
Note: sum or for loop can replace reduce&lt;br /&gt;
&lt;br /&gt;
=== Filter ===&lt;br /&gt;
&lt;br /&gt;
Return a sequence of items for which function(item) is True&lt;br /&gt;
 filter(lambda x: x &amp;gt;= 0, [0, -1, 3])  # [0, 3]&lt;br /&gt;
&lt;br /&gt;
Note: list comprehensions can replace map and filter&lt;br /&gt;
&lt;br /&gt;
Find matching items in two lists:&lt;br /&gt;
 a = [&#039;a&#039;,&#039;b&#039;,&#039;c&#039;]&lt;br /&gt;
 b = [&#039;c&#039;,&#039;d&#039;]&lt;br /&gt;
 filter(lambda x: x in a, b)  # returns only &#039;c&#039; as it is in both lists&lt;br /&gt;
&lt;br /&gt;
=== List comprehension ===&lt;br /&gt;
&lt;br /&gt;
Nothing more than Syntactic Sugar&lt;br /&gt;
&lt;br /&gt;
5. Data Structures — Python v2.7.5 documentation - http://docs.python.org/2/tutorial/datastructures.html#list-comprehensions&lt;br /&gt;
: &amp;quot;List comprehensions provide a concise way to create lists.&amp;quot;&lt;br /&gt;
: &amp;quot;A list comprehension consists of &#039;&#039;&#039;brackets&#039;&#039;&#039; containing an &#039;&#039;&#039;expression&#039;&#039;&#039; followed by a &#039;&#039;&#039;for clause&#039;&#039;&#039;, then &#039;&#039;&#039;zero or more for or if clauses&#039;&#039;&#039;. &amp;quot;&lt;br /&gt;
&lt;br /&gt;
Remove newlines from each item in a list:&lt;br /&gt;
 mylist = [x.strip() for x in mylist]&lt;br /&gt;
&lt;br /&gt;
Simple:&lt;br /&gt;
 doubled = [x*2 for x in mylist]&lt;br /&gt;
 squares = [x**2 for x in range(10)]&lt;br /&gt;
&lt;br /&gt;
If:&lt;br /&gt;
 [ 2*x for x in range(1,10) if x &amp;gt;= 5 ]&lt;br /&gt;
&lt;br /&gt;
Complex:&lt;br /&gt;
 [(x, y) for x in [1,2,3] for y in [3,1,4] if x != y]&lt;br /&gt;
&lt;br /&gt;
Expanding PI:&lt;br /&gt;
 [str(round(pi, i)) for i in range(1, 6)]&lt;br /&gt;
&lt;br /&gt;
Return list of words&lt;br /&gt;
 my_list = [current_word.lower() for current_word in words]&lt;br /&gt;
&lt;br /&gt;
Utah Python July 2013 Meeting: (http://basepi.net)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Iterative&lt;br /&gt;
squares = []&lt;br /&gt;
for x in range(10):&lt;br /&gt;
    squares.append(x**2)&lt;br /&gt;
# [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]&lt;br /&gt;
&lt;br /&gt;
## Functional&lt;br /&gt;
squares = map(lambda x: x**2, range(10))&lt;br /&gt;
&lt;br /&gt;
## List comprehension&lt;br /&gt;
squares = [x**2 for x in range(10)]&lt;br /&gt;
even_squares = [x**2 for x in range(10) if x%2 == 0]&lt;br /&gt;
&lt;br /&gt;
# get hash of strings in list:&lt;br /&gt;
import sha&lt;br /&gt;
strings = [&#039;Python is cool!&#039;, &#039;I love python&#039;]&lt;br /&gt;
hashes = [sha.sha(x).digest() for x in strings]&lt;br /&gt;
&lt;br /&gt;
# flatten matrix:&lt;br /&gt;
matrix = [[1, 2, 3], [4, 5, 6]]&lt;br /&gt;
[x for row in matrix for x in row]&lt;br /&gt;
# [1, 2, 3, 4, 5, 6]&lt;br /&gt;
&lt;br /&gt;
# build matrix:&lt;br /&gt;
[(x,y) for x in range(10) for y in range(10)]&lt;br /&gt;
# matrix of not both odd and not both even&lt;br /&gt;
[(x,y) for x in range(10) for y in range(10) if x%2 != y%2]&lt;br /&gt;
&lt;br /&gt;
# suck lines of files into list, ignoring commented lines&lt;br /&gt;
[line.strip().split(&amp;quot;\t&amp;quot;) for line in open(&amp;quot;my_file.tab&amp;quot;)&lt;br /&gt;
    if not line.startswith(&#039;#&#039;)]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* 5.1.4. List Comprehensions - Data Structures — Python v2.7.2 documentation - http://docs.python.org/tutorial/datastructures.html#list-comprehensions&lt;br /&gt;
* Utah Python July 2013 Meeting - YouTube - https://www.youtube.com/watch?v=uh9uhzitdvw [http://basepi.net]&lt;br /&gt;
&lt;br /&gt;
=== [http://docs.python.org/reference/expressions#calls Mass Parameter Passing] ===&lt;br /&gt;
&lt;br /&gt;
Using: *args and **kw&lt;br /&gt;
* *args a tuple of remaining unnamed parameters&lt;br /&gt;
* **kw a dictionary of remaining named parameters&lt;br /&gt;
&lt;br /&gt;
 def param_func(a, b=&#039;b&#039;, *args, **kw):&lt;br /&gt;
   print( [a, b, args, kw] )&lt;br /&gt;
&lt;br /&gt;
WARNING: If not careful, this can result in this error: &amp;quot;TypeError: param_func() got multiple values for keyword argument &#039;myvar&#039;&amp;quot;.  Might be better to just use:&lt;br /&gt;
&lt;br /&gt;
 def param_func(*args, **kw):&lt;br /&gt;
   print( [args, kw] )&lt;br /&gt;
&lt;br /&gt;
 param_func(1, 2, 3, 4, 5)  # [1, 2, (3, 4, 5), {}]&lt;br /&gt;
 param_func(1, 2, 3, 4, 5, joe=&#039;test&#039;)  # [1, 2, (3, 4, 5), {&#039;joe&#039;: &#039;test&#039;}]&lt;br /&gt;
 mylist = (&amp;quot;a&amp;quot;, &amp;quot;c&amp;quot;, &amp;quot;g&amp;quot;, &amp;quot;h&amp;quot;, 5)&lt;br /&gt;
 param_func(mylist)  # [(&#039;a&#039;, &#039;c&#039;, &#039;g&#039;, &#039;h&#039;, 5), &#039;b&#039;, (), {}]&lt;br /&gt;
 param_func(*mylist)  # [&#039;a&#039;, &#039;c&#039;, (&#039;g&#039;, &#039;h&#039;, 5), {}]  *tricky*&lt;br /&gt;
 Note: *mydict will strip out just keys and treat like list&lt;br /&gt;
 Note: **mydict will treat like named parameters&lt;br /&gt;
&lt;br /&gt;
 def mywrapper(*args, **kw):&lt;br /&gt;
   # do something before&lt;br /&gt;
   result = function_name(*args, **kw)&lt;br /&gt;
&lt;br /&gt;
Passing arbitrary parameters:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def fun2(**kw):&lt;br /&gt;
  print kw  # {&#039;a&#039;: &#039;1&#039;, &#039;b&#039;: &#039;2&#039;, &#039;c&#039;: &#039;3&#039;}&lt;br /&gt;
&lt;br /&gt;
def fun1(c=&#039;3&#039;, **kw):&lt;br /&gt;
 print kw  # {&#039;a&#039;: &#039;1&#039;, &#039;b&#039;: &#039;2&#039;}&lt;br /&gt;
 fun2(c=&#039;3&#039;, **kw)&lt;br /&gt;
&lt;br /&gt;
fun1(a=&#039;1&#039;, b=&#039;2&#039;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [http://www.python.org/dev/peps/pep-0234/ Iteration Protocol] ===&lt;br /&gt;
&lt;br /&gt;
[http://www.python.org/dev/peps/pep-0234/ PEP 234 -- Iterators]&lt;br /&gt;
&lt;br /&gt;
Making a class iterable:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class mycount(object):&lt;br /&gt;
  def __init__(self, max):&lt;br /&gt;
    self.x = 0&lt;br /&gt;
    self.max = max&lt;br /&gt;
  def __iter__(self):  # return object that implements __next__() or next()&lt;br /&gt;
    return self&lt;br /&gt;
  def next(self):&lt;br /&gt;
    if self.x &amp;lt; self.max:&lt;br /&gt;
      self.x += 1&lt;br /&gt;
      return self.x&lt;br /&gt;
    else:&lt;br /&gt;
      self.x = 0&lt;br /&gt;
      raise StopIteration()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 for i in mycount(10): print i     # 1 ... 10&lt;br /&gt;
 print [x for x in mycount(10) ]   # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]&lt;br /&gt;
&lt;br /&gt;
 c = mycount(10)&lt;br /&gt;
 for i in c: print i    # 1 ... 10&lt;br /&gt;
 [ x for x in c ]       # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]&lt;br /&gt;
&lt;br /&gt;
=== Generators ===&lt;br /&gt;
&lt;br /&gt;
Generators are functions that return to their previous state (using &#039;yield&#039;) when iterated over, which can be used in for loops.&lt;br /&gt;
&lt;br /&gt;
==== Yield ====&lt;br /&gt;
&lt;br /&gt;
Improve on Iterators:&lt;br /&gt;
* Infinite data (infinite iterators)&lt;br /&gt;
* Memory-intensive iteration&lt;br /&gt;
* Cooperative Multi-threading&lt;br /&gt;
&lt;br /&gt;
Generators are functions that return to their previous state when iterated over, which can be used in for loops.&lt;br /&gt;
&lt;br /&gt;
Note: Generators throw StopIteration when completed&lt;br /&gt;
&lt;br /&gt;
Note: the &#039;yield&#039; keyword will stash away the state of the function and return the value. (Continuations)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def gen_range(end):&lt;br /&gt;
  cur = 0&lt;br /&gt;
  while cur &amp;lt; end:&lt;br /&gt;
    yield cur&lt;br /&gt;
    # return here next time&lt;br /&gt;
    cur += 1&lt;br /&gt;
&lt;br /&gt;
# for loop iteration&lt;br /&gt;
for i in gen_range(10):  print i&lt;br /&gt;
&lt;br /&gt;
# manual iteration&lt;br /&gt;
my_gen = gen_range(10)&lt;br /&gt;
try:&lt;br /&gt;
  while True:&lt;br /&gt;
    print my_gen.next()&lt;br /&gt;
except StopIteration:&lt;br /&gt;
  pass&lt;br /&gt;
&lt;br /&gt;
# list comprehension&lt;br /&gt;
numbers = [x for x in gen_range(10)]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: one can place an empty &#039;return&#039; in a generator if needed.  A &#039;return&#039; with argument is invalid.&lt;br /&gt;
&lt;br /&gt;
Making a class generate:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class mycount(object):&lt;br /&gt;
  def __init__(self, max):&lt;br /&gt;
    self.max = max&lt;br /&gt;
  def __iter__(self):&lt;br /&gt;
    return self.next()      # change here&lt;br /&gt;
  def next(self):           # change here&lt;br /&gt;
    x = 0&lt;br /&gt;
    while x &amp;lt; self.max:&lt;br /&gt;
      x += 1&lt;br /&gt;
      yield x&lt;br /&gt;
&lt;br /&gt;
for i in mycount(10): print i     # 1 ... 10&lt;br /&gt;
print [x for x in mycount(10) ]   # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]&lt;br /&gt;
&lt;br /&gt;
c = mycount(10)&lt;br /&gt;
for i in c: print i    # 1 ... 10&lt;br /&gt;
[ x for x in c ]       # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]&lt;br /&gt;
&lt;br /&gt;
itr = mycount(10).next()&lt;br /&gt;
itr.next()  # 1&lt;br /&gt;
itr.next()  # 2  - eventually throws StopIteration exception&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Utah Python July 2013 Meeting: [https://www.youtube.com/watch?v=uh9uhzitdvw] [http://basepi.net]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
* Iterators are used to traverse a list&lt;br /&gt;
* Generators are more powerful Iterators&lt;br /&gt;
&lt;br /&gt;
# simple &#039;n&#039; number in functional form&lt;br /&gt;
def firstn(n):&lt;br /&gt;
    num = 0&lt;br /&gt;
    nums = []&lt;br /&gt;
    while num &amp;lt; n:&lt;br /&gt;
        nums.append(num)&lt;br /&gt;
        num += 1&lt;br /&gt;
    return nums&lt;br /&gt;
&lt;br /&gt;
# simple &#039;n&#039; number in generator form&lt;br /&gt;
def firstn(n):&lt;br /&gt;
    num = 0&lt;br /&gt;
    while num &amp;lt; n:&lt;br /&gt;
        yield num&lt;br /&gt;
        num += 1&lt;br /&gt;
&lt;br /&gt;
-&lt;br /&gt;
&lt;br /&gt;
# Infinite list generator&lt;br /&gt;
def counter():&lt;br /&gt;
    num = 0&lt;br /&gt;
    while True:&lt;br /&gt;
        yield num&lt;br /&gt;
        num += 1&lt;br /&gt;
&lt;br /&gt;
# Fibbonacci generator&lt;br /&gt;
def fib():&lt;br /&gt;
    num1 = 0&lt;br /&gt;
    num2 = 1&lt;br /&gt;
    yield num1&lt;br /&gt;
    while True:&lt;br /&gt;
        num1, num2 = num2, num1 + num2&lt;br /&gt;
        yield num1&lt;br /&gt;
&lt;br /&gt;
# Fibbonacci generator 2&lt;br /&gt;
def fib(n):&lt;br /&gt;
    num1 = 0&lt;br /&gt;
    num2 = 1&lt;br /&gt;
    count = 0&lt;br /&gt;
    yield num1&lt;br /&gt;
    while count &amp;lt; n:&lt;br /&gt;
        count += 1&lt;br /&gt;
        num1, num2 = num2, num1 + num2&lt;br /&gt;
        yield num1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Utah Python July 2013 Meeting: [https://www.youtube.com/watch?v=uh9uhzitdvw] [http://basepi.net]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
## Cooperative Multi-Threading:&lt;br /&gt;
# Cooperative multithreading relies on the threads themselves to relinquish control once they are at a stopping point.&lt;br /&gt;
&lt;br /&gt;
def mythread(name):&lt;br /&gt;
    print(&#039;Starting Thread: {name}...&#039;.format(name=name))&lt;br /&gt;
    counter = 10&lt;br /&gt;
    while counter &amp;gt; 0:&lt;br /&gt;
        print(&#039;Thread: {name} doing some work!&#039;.format(name=name))&lt;br /&gt;
        counter -= 1&lt;br /&gt;
        yield&lt;br /&gt;
&lt;br /&gt;
thread1 = mythread(&#039;Alice&#039;)&lt;br /&gt;
thread2 = mythread(&#039;Bob&#039;)&lt;br /&gt;
thread3 = mythread(&#039;Trudy&#039;)&lt;br /&gt;
&lt;br /&gt;
try:&lt;br /&gt;
    while True:&lt;br /&gt;
        thread1.next()&lt;br /&gt;
        thread2.next()&lt;br /&gt;
        thread3.next()&lt;br /&gt;
except StopIteration:&lt;br /&gt;
    pass&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* Utah Python July 2013 Meeting: [https://www.youtube.com/watch?v=uh9uhzitdvw] [http://basepi.net]&lt;br /&gt;
** http://files.basepi.net/talks/pyarmory.zip&lt;br /&gt;
&lt;br /&gt;
=== dunder methods ===&lt;br /&gt;
&lt;br /&gt;
Some dunder (double under) methods determine what will happen when + (__add__) or other similar numerical symbols used.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class str_add(object):&lt;br /&gt;
    def __init__(self, name):&lt;br /&gt;
        self.name = name&lt;br /&gt;
    def __add__(self, other):&lt;br /&gt;
        self.name += other.name&lt;br /&gt;
        return self&lt;br /&gt;
        # note: only need to return self if you want to go beyond &#039;a + b&#039;&lt;br /&gt;
&lt;br /&gt;
a = str_add(&#039;a_&#039;)&lt;br /&gt;
b = str_add(&#039;b_&#039;)&lt;br /&gt;
c = str_add(&#039;c_&#039;)&lt;br /&gt;
d = a + b + c&lt;br /&gt;
print(a.name)  # a_b_c_&lt;br /&gt;
print(b.name)  # b_&lt;br /&gt;
print(c.name)  # c_&lt;br /&gt;
print(d.name)  # a_b_c_&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Other common methods to override:&lt;br /&gt;
* __add__ for +&lt;br /&gt;
* __sub__ for -&lt;br /&gt;
* __mul__ for *&lt;br /&gt;
* __div__ for /&lt;br /&gt;
* __mod__ for %&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* Emulating numeric types - http://docs.python.org/2/reference/datamodel.html#emulating-numeric-types&lt;br /&gt;
&lt;br /&gt;
=== [http://docs.python.org/library/doctest.html doctest] ===&lt;br /&gt;
&lt;br /&gt;
test.py:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
This is the &amp;quot;example&amp;quot; module.&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; double(5)&lt;br /&gt;
10&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
def double(n):&lt;br /&gt;
  &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  This is double function&lt;br /&gt;
&lt;br /&gt;
  &amp;gt;&amp;gt;&amp;gt; double(3)&lt;br /&gt;
  6&lt;br /&gt;
  &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  return n * 2&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
    import doctest&lt;br /&gt;
    doctest.testmod()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== unittest ===&lt;br /&gt;
&lt;br /&gt;
 unittest.TestCase&lt;br /&gt;
&lt;br /&gt;
Here is a short script to test three functions from the random module:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import random&lt;br /&gt;
import unittest&lt;br /&gt;
&lt;br /&gt;
class TestSequenceFunctions(unittest.TestCase):&lt;br /&gt;
&lt;br /&gt;
    def setUp(self):&lt;br /&gt;
        self.seq = range(10)&lt;br /&gt;
&lt;br /&gt;
    def test_shuffle(self):&lt;br /&gt;
        # make sure the shuffled sequence does not lose any elements&lt;br /&gt;
        random.shuffle(self.seq)&lt;br /&gt;
        self.seq.sort()&lt;br /&gt;
        self.assertEqual(self.seq, range(10))&lt;br /&gt;
&lt;br /&gt;
        # should raise an exception for an immutable sequence&lt;br /&gt;
        self.assertRaises(TypeError, random.shuffle, (1,2,3))&lt;br /&gt;
&lt;br /&gt;
    def test_choice(self):&lt;br /&gt;
        element = random.choice(self.seq)&lt;br /&gt;
        self.assertTrue(element in self.seq)&lt;br /&gt;
&lt;br /&gt;
    def test_sample(self):&lt;br /&gt;
        with self.assertRaises(ValueError):&lt;br /&gt;
            random.sample(self.seq, 20)&lt;br /&gt;
        for element in random.sample(self.seq, 5):&lt;br /&gt;
            self.assertTrue(element in self.seq)&lt;br /&gt;
&lt;br /&gt;
if __name__ == &#039;__main__&#039;:&lt;br /&gt;
    unittest.main()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The unittest module can be used from the command line to run tests from modules, classes or even individual test methods:&lt;br /&gt;
 python -m unittest test_module1 test_module2&lt;br /&gt;
 python -m unittest test_module.TestClass&lt;br /&gt;
 python -m unittest test_module.TestClass.test_method&lt;br /&gt;
 python -m unittest -v test_module  # verbose&lt;br /&gt;
 python -m unittest -h   # help&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* 25.3. unittest — Unit testing framework — Python v2.7.4 documentation - http://docs.python.org/2/library/unittest.html&lt;br /&gt;
* Python Debugging Tips - Google Drive - https://docs.google.com/presentation/d/130Wl--IzbDh9ymF6KHMu0WrsIwz6k32pav1gFbsw7NI/edit?usp=sharing&lt;br /&gt;
&lt;br /&gt;
=== Internet Access ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Python 3&lt;br /&gt;
from urllib.request import urlopen&lt;br /&gt;
for line in urlopen(&#039;http://tycho.usno.navy.mil/cgi-bin/timer.pl&#039;):&lt;br /&gt;
  line = line.decode(&#039;utf-8&#039;)&lt;br /&gt;
  if &#039;EST&#039; in line or &#039;EDT&#039; in line:  # look for eastern time&lt;br /&gt;
    print(line)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Simple SMTP ===&lt;br /&gt;
&lt;br /&gt;
Requires local STMP server.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import smtplib&lt;br /&gt;
server = smtplib.SMTP(&amp;quot;localhost&amp;quot;)&lt;br /&gt;
server.sendmail(&#039;mrken@demo.oeey.com&#039;, &#039;kenneth@demo.oeey.com&#039;,&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;To: kenneth@demo.oeey.com&lt;br /&gt;
From: mrken@demo.oeey.com&lt;br /&gt;
Subject: This is fun&lt;br /&gt;
&lt;br /&gt;
Beware of the dog.&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;)&lt;br /&gt;
server.quit()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
s = smtplib.SMTP(smtp_server)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
with TLS:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
s = smtplib.SMTP(&amp;quot;smtp.gmail.com&amp;quot;,587)&lt;br /&gt;
s.ehlo()&lt;br /&gt;
s.starttls()&lt;br /&gt;
s.ehlo()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
SSL:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
s = smtplib.SMTP_SSL(&#039;smtp.mail.yahoo.com&#039;, 465)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Data Compress ===&lt;br /&gt;
&lt;br /&gt;
zlib, gzip, bz2, zipfile, tarfile&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import zlib&lt;br /&gt;
s = b&#039;hello world&#039;  # only in python &amp;gt;3&lt;br /&gt;
len(s)&lt;br /&gt;
t = zlib.compress(s)&lt;br /&gt;
zlib.decompress(t)&lt;br /&gt;
zlib.crc32(s)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== gzip ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import gzip&lt;br /&gt;
content = &amp;quot;Lots of content here&amp;quot;&lt;br /&gt;
f = gzip.open(&#039;file.txt.gz&#039;, &#039;wb&#039;)&lt;br /&gt;
f.write(content)&lt;br /&gt;
f.close()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import gzip&lt;br /&gt;
f_in = open(&#039;file.txt&#039;, &#039;rb&#039;)&lt;br /&gt;
f_out = gzip.open(&#039;file.txt.gz&#039;, &#039;wb&#039;)&lt;br /&gt;
f_out.writelines(f_in)&lt;br /&gt;
f_out.close()&lt;br /&gt;
f_in.close()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Performance Timer ===&lt;br /&gt;
&lt;br /&gt;
Time a task repeated 10 times:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from timeit import Timer&lt;br /&gt;
Timer(&#039;t=a; a=b; b=t&#039;, &#039;a=1; b=2&#039;).timeit()&lt;br /&gt;
Timer(&#039;print(&amp;quot;hi&amp;quot;)&#039;).timeit(10)  # repeat 10 times and time&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Simple method:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
start_time = int(time.time())&lt;br /&gt;
... task ...&lt;br /&gt;
compute_time = int(time.time()) - start_time&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Python Version Check ===&lt;br /&gt;
&lt;br /&gt;
Solution:&lt;br /&gt;
&lt;br /&gt;
__init__.py:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Check Python Version:&lt;br /&gt;
import sys&lt;br /&gt;
assert sys.version_info &amp;gt;= (2, 6, 0), &#039;requires Python 2.6 or higher&#039;&lt;br /&gt;
del sys&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
resulting error if not &amp;gt; 2.6:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import nucleon&lt;br /&gt;
Traceback (most recent call last):&lt;br /&gt;
  File &amp;quot;&amp;lt;stdin&amp;gt;&amp;quot;, line 1, in ?&lt;br /&gt;
  File &amp;quot;nucleon/__init__.py&amp;quot;, line 9, in ?&lt;br /&gt;
    assert sys.version_info &amp;gt;= (2, 6, 0), &#039;nucleon requires Python 2.6 or higher&#039;&lt;br /&gt;
AssertionError: nucleon requires Python 2.6 or higher&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Other solutions:&lt;br /&gt;
&lt;br /&gt;
Note: this will throw syntax error on 2.4 due to ternary&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import sys&lt;br /&gt;
if sys.version_info &amp;lt; (2, 4):&lt;br /&gt;
    raise &amp;quot;must use python 2.5 or greater&amp;quot;&lt;br /&gt;
else:&lt;br /&gt;
    # syntax error in 2.4, ok in 2.5&lt;br /&gt;
    x = 1 if True else 2&lt;br /&gt;
    print x&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
maybe solution:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
try:&lt;br /&gt;
  eval(&amp;quot;1 if True else 2&amp;quot;)&lt;br /&gt;
except SyntaxError:&lt;br /&gt;
  # doesn&#039;t have ternary&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; try:&lt;br /&gt;
...     from my_module import twoPointSixCode&lt;br /&gt;
... except Exception: &lt;br /&gt;
...     print &amp;quot;can&#039;t import, probably because your python is too old!&amp;quot;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/env/python&lt;br /&gt;
import sys&lt;br /&gt;
if sys.version_info&amp;lt;(2,6,0):&lt;br /&gt;
  sys.stderr.write(&amp;quot;You need python 2.6 or later to run this script\n&amp;quot;)&lt;br /&gt;
  exit(1)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import sys&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; sys.hexversion  # hex printed as integer&lt;br /&gt;
33817584&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; &#039;%x&#039; % sys.hexversion  # output as hex, not zero fill  2.4.3&lt;br /&gt;
&#039;20403f0&#039;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; sys.hexversion &amp;lt; 0x02060000  # test if version less than 2.6&lt;br /&gt;
True&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; print &amp;quot;0x%08x&amp;quot; % sys.hexversion  # print as hex and zero fill and prepend &#039;0x&#039;&lt;br /&gt;
0x020403f0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import sys&lt;br /&gt;
if sys.hexversion &amp;lt; 0x02060500:&lt;br /&gt;
    print &amp;gt;&amp;gt; sys.stderr, &amp;quot;This script requires python 2.6.5 or higher.&amp;quot;&lt;br /&gt;
    exit(1)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import sys&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; sys.version_info&lt;br /&gt;
(2, 6, 4, &#039;final&#039;, 0)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; if not sys.version_info[:2] == (2, 6):&lt;br /&gt;
...    print &amp;quot;Error, I need python 2.6&amp;quot;&lt;br /&gt;
... else:&lt;br /&gt;
...    from my_module import twoPointSixCode&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* http://stackoverflow.com/questions/446052/python-best-way-to-check-for-python-version-in-program-that-uses-new-language-fe&lt;br /&gt;
* http://stackoverflow.com/questions/1093322/how-do-i-check-what-version-of-python-is-running-my-script&lt;br /&gt;
&lt;br /&gt;
=== [http://docs.python.org/library/struct.html Struct - Binary Data Record Layout] ===&lt;br /&gt;
&lt;br /&gt;
Format Characters:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Format	C Type		Python type 	Standard size&lt;br /&gt;
x	pad byte	no value	  	 &lt;br /&gt;
c	char		str of len 1	1	 &lt;br /&gt;
b	signed char	integer		1&lt;br /&gt;
B	unsigned char	integer 	1&lt;br /&gt;
?	_Bool		bool 		1&lt;br /&gt;
h	short		integer 	2&lt;br /&gt;
H	unsigned short 	integer 	2&lt;br /&gt;
i	int		integer 	4&lt;br /&gt;
I	unsigned int 	integer 	4&lt;br /&gt;
l	long		integer 	4&lt;br /&gt;
L	unsigned long	integer		4&lt;br /&gt;
q	long long	integer		8&lt;br /&gt;
Q	unsigned long long    integer	8&lt;br /&gt;
f	float		float		4&lt;br /&gt;
d	double		float		8&lt;br /&gt;
s	char[]		string&lt;br /&gt;
p	char[]		string&lt;br /&gt;
P	void *		integer&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 H  # two byte unassigned number&lt;br /&gt;
 I  # four byte unassigned number&lt;br /&gt;
 &amp;lt;  # standard size and in little-endian byte order&lt;br /&gt;
&lt;br /&gt;
 import struct&lt;br /&gt;
 data = struct.pack(&#039;&amp;lt;IIIHH&#039;, 1, 2, 3, 4, 5)&lt;br /&gt;
 # data = &#039;\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x04\x00\x05\x00&#039;&lt;br /&gt;
 &lt;br /&gt;
 fields = struct.unpack(&#039;&amp;lt;IIIHH&#039;, data)&lt;br /&gt;
 # fields = (1L, 2L, 3L, 4, 5)&lt;br /&gt;
 # using splice: fields = struct.unpack(&#039;&amp;lt;IIIHH&#039;, data[start:start+16])&lt;br /&gt;
 &lt;br /&gt;
 f1, f2, f3, f4, f5 = fields&lt;br /&gt;
 &lt;br /&gt;
 hex(f1)  # hex a field:&lt;br /&gt;
 #  &#039;0x1L&#039;&lt;br /&gt;
&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; struct.pack(&amp;quot;&amp;lt;5sh&amp;quot;, &amp;quot;helloo&amp;quot;, 11)&lt;br /&gt;
 &#039;hello\x0b\x00&#039;&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; struct.unpack(&amp;quot;&amp;lt;5sh&amp;quot;, &#039;hello\x0b\x00&#039;)&lt;br /&gt;
 (&#039;hello&#039;, 11)&lt;br /&gt;
&lt;br /&gt;
=== pdb interactive debugger ===&lt;br /&gt;
&lt;br /&gt;
 # uncomment the following to use the interactive debugger:&lt;br /&gt;
 # import pdb; pdb.set_trace()&lt;br /&gt;
&lt;br /&gt;
=== [http://docs.python.org/library/telnetlib.html Telnet] ===&lt;br /&gt;
&lt;br /&gt;
create:&lt;br /&gt;
 class telnetlib.Telnet([host[, port[, timeout]]])&lt;br /&gt;
&lt;br /&gt;
Note: The instance is initially not connected by default; the open() method must be used to establish a connection. Alternatively, the host name and optional port number can be passed to the constructor, to, in which case the connection to the server will be established before the constructor returns.&lt;br /&gt;
&lt;br /&gt;
open if not initially done so:&lt;br /&gt;
 Telnet.open(host[, port[, timeout]])&lt;br /&gt;
&lt;br /&gt;
Functions:&lt;br /&gt;
 Telnet.read_until(expected[, timeout])   # Read until a given string, expected, is encountered or until timeout seconds have passed.&lt;br /&gt;
                                          # on timeout return whatever is in queue, possibly empty string&lt;br /&gt;
 Telnet.close()         # close connection&lt;br /&gt;
 Telnet.read_all()      # Read all data until EOF; block until connection closed.&lt;br /&gt;
 Telnet.write(buffer)   # Write a string to the socket, doubling any IAC characters. This can block if the connection is blocked.&lt;br /&gt;
 Telnet.expect(list[, timeout])  # Read until one from a list of a regular expressions matches.&lt;br /&gt;
                        # Return a tuple of three items: the index in the list of matches; the match object; and the text read to match.&lt;br /&gt;
&lt;br /&gt;
Read until end of line:&lt;br /&gt;
 line = tn.read_until(&amp;quot;\n&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import getpass&lt;br /&gt;
import sys&lt;br /&gt;
import telnetlib&lt;br /&gt;
&lt;br /&gt;
HOST = &amp;quot;localhost&amp;quot;&lt;br /&gt;
user = raw_input(&amp;quot;Enter your remote account: &amp;quot;)&lt;br /&gt;
password = getpass.getpass()&lt;br /&gt;
&lt;br /&gt;
tn = telnetlib.Telnet(HOST)&lt;br /&gt;
&lt;br /&gt;
tn.read_until(&amp;quot;login: &amp;quot;)&lt;br /&gt;
tn.write(user + &amp;quot;\n&amp;quot;)&lt;br /&gt;
if password:&lt;br /&gt;
    tn.read_until(&amp;quot;Password: &amp;quot;)&lt;br /&gt;
    tn.write(password + &amp;quot;\n&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
tn.write(&amp;quot;ls\n&amp;quot;)&lt;br /&gt;
tn.write(&amp;quot;exit\n&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
print tn.read_all()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
&lt;br /&gt;
import sys&lt;br /&gt;
import telnetlib&lt;br /&gt;
&lt;br /&gt;
HOST = &amp;quot;216.119.193.252&amp;quot;&lt;br /&gt;
USER = &amp;quot;admin&amp;quot;&lt;br /&gt;
PASS = &amp;quot;@lt12345&amp;quot;&lt;br /&gt;
&lt;br /&gt;
tn = telnetlib.Telnet(HOST)&lt;br /&gt;
&lt;br /&gt;
tn.read_until(&amp;quot;login: &amp;quot;)&lt;br /&gt;
tn.write(USER + &amp;quot;\n&amp;quot;)&lt;br /&gt;
tn.read_until(&amp;quot;Password: &amp;quot;)&lt;br /&gt;
tn.write(PASS + &amp;quot;\n&amp;quot;)&lt;br /&gt;
tn.read_until(&amp;quot;# &amp;quot;)&lt;br /&gt;
&lt;br /&gt;
tn.write(&amp;quot;terminal length 0\n&amp;quot;)&lt;br /&gt;
tn.read_until(&amp;quot;# &amp;quot;)&lt;br /&gt;
&lt;br /&gt;
tn.write(&amp;quot;show running-config\n&amp;quot;)&lt;br /&gt;
configlines = tn.read_until(&amp;quot;# &amp;quot;)&lt;br /&gt;
&lt;br /&gt;
tn.write(&amp;quot;exit\n&amp;quot;)&lt;br /&gt;
tn.read_all()&lt;br /&gt;
&lt;br /&gt;
print(configlines)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== SSH ===&lt;br /&gt;
&lt;br /&gt;
Cheap method:&lt;br /&gt;
 os.system(&#039;ssh user@server command&#039;)&lt;br /&gt;
&lt;br /&gt;
SecureShell - PythonInfo Wiki - http://wiki.python.org/moin/SecureShell&lt;br /&gt;
: There are several ways to use Secure Shell (SSH) in Python&lt;br /&gt;
* pyssh - http://pyssh.sourceforge.net/&lt;br /&gt;
* paramiko - Paramiko is a native Python implementation of SSH. - http://www.lag.net/paramiko/&lt;br /&gt;
* conch - conch is another native implementation of SSH and part of the Twisted Matrix project - http://twistedmatrix.com/projects/conch &lt;br /&gt;
* SSH wrapper - Some tools just wrap around existing ssh/sftp implementations&lt;br /&gt;
** keyphrene - http://www.keyphrene.com/products/org.keyphrene/&lt;br /&gt;
** keyphrene SSH wrapper - http://membres.lycos.fr/fredp/python/pyscp.html&lt;br /&gt;
* Fabric - http://docs.fabfile.org/en/1.4.0/index.html&lt;br /&gt;
* pexpect - Noah.org - http://www.noah.org/wiki/Pexpect&lt;br /&gt;
&lt;br /&gt;
SFTP:&lt;br /&gt;
* SFTP in Python: Really Simple SSH | The best of Zeth - http://zeth.net/post/332/&lt;br /&gt;
&lt;br /&gt;
pexpect:&lt;br /&gt;
 wget http://pexpect.sourceforge.net/pexpect-2.3.tar.gz&lt;br /&gt;
 tar xzf pexpect-2.3.tar.gz&lt;br /&gt;
 cd pexpect-2.3&lt;br /&gt;
 sudo python ./setup.py install&lt;br /&gt;
&lt;br /&gt;
=== SFTP ===&lt;br /&gt;
&lt;br /&gt;
SFTP in Python? (platform independent) - Stack Overflow - http://stackoverflow.com/questions/432385/sftp-in-python-platform-independent&lt;br /&gt;
&lt;br /&gt;
paramiko: ssh2 protocol for python - http://www.lag.net/paramiko/&lt;br /&gt;
&lt;br /&gt;
 pip install paramiko&lt;br /&gt;
&lt;br /&gt;
 mkdir -p ~/.src ; cd ~/.src&lt;br /&gt;
 wget http://www.lag.net/paramiko/download/paramiko-1.7.7.1.zip&lt;br /&gt;
 unzip paramiko-1.7.7.1.zip&lt;br /&gt;
 cd paramiko-1.7.7.1&lt;br /&gt;
 python setup.py install&lt;br /&gt;
&lt;br /&gt;
SFTP Methods:&lt;br /&gt;
* chdir&lt;br /&gt;
* chmod&lt;br /&gt;
* chown&lt;br /&gt;
* close&lt;br /&gt;
* file&lt;br /&gt;
* from_transport&lt;br /&gt;
* get&lt;br /&gt;
* get_channel&lt;br /&gt;
* getcwd&lt;br /&gt;
* listdir&lt;br /&gt;
* listdir_attr&lt;br /&gt;
* logger&lt;br /&gt;
* lstat&lt;br /&gt;
* mkdir&lt;br /&gt;
* normalize&lt;br /&gt;
* open&lt;br /&gt;
* put&lt;br /&gt;
* readlink&lt;br /&gt;
* remove&lt;br /&gt;
* rename&lt;br /&gt;
* request_number&lt;br /&gt;
* rmdir&lt;br /&gt;
* sock&lt;br /&gt;
* stat&lt;br /&gt;
* symlink&lt;br /&gt;
* truncate&lt;br /&gt;
* ultra_debug&lt;br /&gt;
* unlink&lt;br /&gt;
* utime&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import paramiko&lt;br /&gt;
&lt;br /&gt;
host = &amp;quot;THEHOST.com&amp;quot;                    #hard-coded&lt;br /&gt;
port = 22&lt;br /&gt;
transport = paramiko.Transport((host, port))&lt;br /&gt;
&lt;br /&gt;
password = &amp;quot;THEPASSWORD&amp;quot;                #hard-coded&lt;br /&gt;
username = &amp;quot;THEUSERNAME&amp;quot;                #hard-coded&lt;br /&gt;
transport.connect(username = username, password = password)&lt;br /&gt;
&lt;br /&gt;
sftp = paramiko.SFTPClient.from_transport(transport)&lt;br /&gt;
&lt;br /&gt;
import sys&lt;br /&gt;
path = &#039;./THETARGETDIRECTORY/&#039; + sys.argv[1]    #hard-coded&lt;br /&gt;
localpath = sys.argv[1]&lt;br /&gt;
sftp.put(localpath, path)&lt;br /&gt;
&lt;br /&gt;
sftp.close()&lt;br /&gt;
transport.close()&lt;br /&gt;
print &#039;Upload done.&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
VMware Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
&lt;br /&gt;
import paramiko&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
host = &amp;quot;sftp2.engx.vmware.com&amp;quot;&lt;br /&gt;
port = 443&lt;br /&gt;
transport = paramiko.Transport((host, port))&lt;br /&gt;
&lt;br /&gt;
username = &amp;quot;xxxx&amp;quot;&lt;br /&gt;
password = &amp;quot;xxx&amp;quot;&lt;br /&gt;
transport.connect(username = username, password = password)&lt;br /&gt;
&lt;br /&gt;
sftp = paramiko.SFTPClient.from_transport(transport)&lt;br /&gt;
&lt;br /&gt;
print dir(sftp)&lt;br /&gt;
&lt;br /&gt;
print sftp.chdir(&amp;quot;build-uploader&amp;quot;)&lt;br /&gt;
print sftp.listdir()&lt;br /&gt;
&lt;br /&gt;
sftp.close()&lt;br /&gt;
transport.close()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== paramiko ===&lt;br /&gt;
&lt;br /&gt;
See [[Python/paramiko]]&lt;br /&gt;
&lt;br /&gt;
=== [http://docs.python.org/library/getpass.html Get Password] ===&lt;br /&gt;
&lt;br /&gt;
Prompt for password:&lt;br /&gt;
 getpass.getpass(prompt=&#039;Password: &#039;)&lt;br /&gt;
&lt;br /&gt;
 import getpass&lt;br /&gt;
 user = raw_input(&amp;quot;Enter your remote account: &amp;quot;)&lt;br /&gt;
 password = getpass.getpass()&lt;br /&gt;
&lt;br /&gt;
=== [http://docs.python.org/library/configparser.html ini files] ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ini_filename = &#039;my.ini&#039;&lt;br /&gt;
&lt;br /&gt;
import ConfigParser&lt;br /&gt;
parser = ConfigParser.SafeConfigParser()&lt;br /&gt;
parser.read(ini_filename)&lt;br /&gt;
&lt;br /&gt;
sections = parser.sections() # get sections&lt;br /&gt;
for section in sections:&lt;br /&gt;
  print &amp;quot;[&amp;quot; + section + &amp;quot;]&amp;quot;&lt;br /&gt;
  for name, value in parser.items(section):&lt;br /&gt;
    print name + &amp;quot; = &amp;quot; + value&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if parser.has_option(section, option):&lt;br /&gt;
  print( parser.get(section, option) )&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To have the option names not convert to lower case:&lt;br /&gt;
 parser.optionxform = str&lt;br /&gt;
&lt;br /&gt;
Ignore section: [http://stackoverflow.com/questions/2885190/using-pythons-configparser-to-read-a-file-without-section-name]&lt;br /&gt;
 ini_str = &#039;[root]\n&#039; + open(ini_path, &#039;r&#039;).read()&lt;br /&gt;
 ini_fp = StringIO.StringIO(ini_str)&lt;br /&gt;
 config = ConfigParser.RawConfigParser()&lt;br /&gt;
 config.readfp(ini_fp)&lt;br /&gt;
&lt;br /&gt;
Get option:&lt;br /&gt;
 config.has_option(&#039;root&#039;, &#039;some_key&#039;)&lt;br /&gt;
 config.get(&#039;root&#039;, &#039;some_key&#039;)&lt;br /&gt;
&lt;br /&gt;
 config.items(&#039;root&#039;)  # list of Key Value tuples&lt;br /&gt;
&lt;br /&gt;
=== optparse - Option Parser ===&lt;br /&gt;
&lt;br /&gt;
[http://docs.python.org/library/optparse.html - Option Parser&lt;br /&gt;
&lt;br /&gt;
Note: Deprecated since version 2.7: The optparse module is deprecated and will not be developed further; development will continue with the argparse module.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import optparse&lt;br /&gt;
parser = optparse.OptionParser()&lt;br /&gt;
&lt;br /&gt;
parser.add_option(&#039;--name&#039;, default=None)&lt;br /&gt;
&lt;br /&gt;
parser.add_option(&lt;br /&gt;
    &#039;-l&#039;, &#039;--loglevel&#039;,&lt;br /&gt;
    help=&#039;Log Level (default: info)&#039;,&lt;br /&gt;
    default=&amp;quot;info&amp;quot;, action=&#039;store&#039;, type=&#039;string&#039;)&lt;br /&gt;
&lt;br /&gt;
(options, args) = parser.parse_args()&lt;br /&gt;
&lt;br /&gt;
# if no parameters passed show help&lt;br /&gt;
if len(sys.argv) == 1:&lt;br /&gt;
    parser.print_help()&lt;br /&gt;
    sys.exit(1)&lt;br /&gt;
&lt;br /&gt;
# if a stand alone parameter passed, override option&lt;br /&gt;
if args:&lt;br /&gt;
  options.target = args[0]&lt;br /&gt;
&lt;br /&gt;
# show option:&lt;br /&gt;
print(options.loglevel)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: Order is important when listing add_options!&lt;br /&gt;
&lt;br /&gt;
Pretty Description:&lt;br /&gt;
 parser = optparse.OptionParser(description=&amp;quot;Purpose: to do something&amp;quot;)&lt;br /&gt;
 # or&lt;br /&gt;
 parser.description = &amp;quot;Purpose: to do something&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Parse arguments:&lt;br /&gt;
 (options, args) = parser.parse_args()&lt;br /&gt;
Note: If you like, you can pass a custom argument list to parse_args(), but that’s rarely necessary: by default it uses sys.argv[1:].&lt;br /&gt;
&lt;br /&gt;
Change Usage Message:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
usage = &amp;quot;%prog [options]&amp;quot;  # default message&lt;br /&gt;
# Usage: &amp;lt;prog&amp;gt; [options]&amp;quot;  # where &amp;lt;prog&amp;gt; is replaced with the script name&lt;br /&gt;
&lt;br /&gt;
parser = OptionParser(usage=usage)&lt;br /&gt;
# or&lt;br /&gt;
parser.usage = usage  # default message&lt;br /&gt;
# or&lt;br /&gt;
parser.set_usage(usage)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Remove option: (does not remove default value from &#039;options&#039; variable!!! - stupid!)&lt;br /&gt;
 parser.remove_option(&#039;--loglevel&#039;)&lt;br /&gt;
&lt;br /&gt;
Modify an option: (changes are saved to parser automatically, unless in an option group)&lt;br /&gt;
 option = parser.get_option(&#039;--loglevel&#039;)&lt;br /&gt;
 option.help = &#039;something else&#039;&lt;br /&gt;
 option.default = &#039;debug&#039;&lt;br /&gt;
&lt;br /&gt;
 # or&lt;br /&gt;
 parser.remove_option(&amp;quot;--loglevel&amp;quot;)&lt;br /&gt;
 parser.add_option(&amp;quot;--loglevel&amp;quot;, help=&amp;quot;something else&amp;quot;, default=&amp;quot;info&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Modify an option in an option group:&lt;br /&gt;
 opt_group = parser.get_option_group(&amp;quot;--loglevel&amp;quot;)&lt;br /&gt;
 opt_group.remove_option(&amp;quot;--loglevel&amp;quot;)&lt;br /&gt;
 opt_group.add_option(&amp;quot;--loglevel&amp;quot;, help=&amp;quot;something else&amp;quot;, default=&amp;quot;info&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Types: &amp;quot;string&amp;quot;, &amp;quot;int&amp;quot;, &amp;quot;long&amp;quot;, &amp;quot;choice&amp;quot;, &amp;quot;float&amp;quot; and &amp;quot;complex&amp;quot; [http://docs.python.org/library/optparse.html#optparse-standard-option-types]&lt;br /&gt;
Defaults:&lt;br /&gt;
* Default actions is &#039;store&#039;.&lt;br /&gt;
* Default type is &#039;string&#039;.&lt;br /&gt;
* Default dest is the long name of the parameter (or short name if no long name provided)&lt;br /&gt;
* Default value is None&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from optparse import OptionParser&lt;br /&gt;
[...]&lt;br /&gt;
parser = OptionParser()&lt;br /&gt;
&lt;br /&gt;
# string&lt;br /&gt;
parser.add_option(&amp;quot;-f&amp;quot;, &amp;quot;--file&amp;quot;, dest=&amp;quot;filename&amp;quot;,&lt;br /&gt;
                  help=&amp;quot;write report to FILE&amp;quot;, metavar=&amp;quot;FILE&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
# boolean - action is what to do when flag found&lt;br /&gt;
parser.add_option(&amp;quot;-q&amp;quot;, &amp;quot;--quiet&amp;quot;,&lt;br /&gt;
                  action=&amp;quot;store_true&amp;quot;, dest=&amp;quot;verbose&amp;quot;, default=False,&lt;br /&gt;
                  help=&amp;quot;don&#039;t print status messages to stdout&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
# integer&lt;br /&gt;
parser.add_option(&lt;br /&gt;
    &amp;quot;-m&amp;quot;, &amp;quot;--minutes&amp;quot;,&lt;br /&gt;
    help=&amp;quot;Minutes (default: 60)&amp;quot;,&lt;br /&gt;
    default=60, type=&#039;int&#039;)&lt;br /&gt;
&lt;br /&gt;
(options, args) = parser.parse_args()&lt;br /&gt;
&lt;br /&gt;
print &amp;quot;Filename: &amp;quot; + options.filename&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
fake handling of required option:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if not option.filename:&lt;br /&gt;
    parser.print_help()&lt;br /&gt;
    parser.error(&amp;quot;filename is required&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
change default usage:&lt;br /&gt;
  parser = OptionParser(usage=&amp;quot;Usage: %prog [args] arg1 arg2&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Really ugly way to print help usage  :-(&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def Usage():&lt;br /&gt;
    pname = sys.argv[0]&lt;br /&gt;
    cmd=&#039;%s -h&#039; % (pname)&lt;br /&gt;
    os.system(cmd)&lt;br /&gt;
&lt;br /&gt;
if (len(sys.argv) &amp;lt; 2):&lt;br /&gt;
    Usage()&lt;br /&gt;
    sys.exit(1)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Groups:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#  OptionGroup(parser, title, description=None)&lt;br /&gt;
group = OptionGroup(parser, &amp;quot;Dangerous Options&amp;quot;,&lt;br /&gt;
                    &amp;quot;Caution: use these options at your own risk.  &amp;quot;&lt;br /&gt;
                    &amp;quot;It is believed that some of them bite.&amp;quot;)&lt;br /&gt;
group.add_option(&amp;quot;-g&amp;quot;, action=&amp;quot;store_true&amp;quot;, help=&amp;quot;Group option.&amp;quot;)&lt;br /&gt;
parser.add_option_group(group)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hide an option:&lt;br /&gt;
* Option.help&lt;br /&gt;
: &amp;quot;Help text to print for this option when listing all available options after the user supplies a help option (such as --help). If no help text is supplied, the option will be listed without help text. To hide this option, use the special value optparse.SUPPRESS_HELP.&amp;quot;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
parser.add_option(&amp;quot;--secret&amp;quot;, help=SUPPRESS_HELP)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Issues with Option Parser:&lt;br /&gt;
* No handling for positional arguments&lt;br /&gt;
* No adding help for positional arguments&lt;br /&gt;
* No handling for required field&lt;br /&gt;
&lt;br /&gt;
=== argparse ===&lt;br /&gt;
&lt;br /&gt;
argparse - http://docs.python.org/library/argparse.html&lt;br /&gt;
&lt;br /&gt;
argparse — Parser for command-line options, arguments and sub-commands&lt;br /&gt;
&lt;br /&gt;
NOTE: MUCH MORE POWERFUL THAN OPTION PARSER!&lt;br /&gt;
&lt;br /&gt;
Note: New in version 2.7.&lt;br /&gt;
&lt;br /&gt;
Installation on &amp;lt;= 2.6&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Install argparse: - http://code.google.com/p/argparse/&lt;br /&gt;
# REQUIRES SETUPTOOLS&lt;br /&gt;
mkdir -p ~/.src ; cd ~/.src&lt;br /&gt;
wget http://argparse.googlecode.com/files/argparse-1.2.1.tar.gz&lt;br /&gt;
tar -zvxf argparse-1.2.1.tar.gz&lt;br /&gt;
cd argparse-1.2.1&lt;br /&gt;
sudo python setup.py install&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The argparse module makes it easy to write user-friendly command-line interfaces. The program defines what arguments it requires, and argparse will figure out how to parse those out of sys.argv. The argparse module also automatically generates help and usage messages and issues errors when users give the program invalid arguments.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import argparse&lt;br /&gt;
&lt;br /&gt;
parser = argparse.ArgumentParser(description=&#039;Process some integers.&#039;)&lt;br /&gt;
parser.add_argument(&#039;integers&#039;, metavar=&#039;N&#039;, type=int, nargs=&#039;+&#039;,&lt;br /&gt;
                   help=&#039;an integer for the accumulator&#039;)&lt;br /&gt;
parser.add_argument(&#039;--sum&#039;, dest=&#039;accumulate&#039;, action=&#039;store_const&#039;,&lt;br /&gt;
                   const=sum, default=max,&lt;br /&gt;
                   help=&#039;sum the integers (default: find the max)&#039;)&lt;br /&gt;
&lt;br /&gt;
args = parser.parse_args()&lt;br /&gt;
print args.accumulate(args.integers)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import argparse&lt;br /&gt;
&lt;br /&gt;
argparser = demoproject.util.argparse.ArgumentParser(&lt;br /&gt;
    usage=&#039;Kick off demoproject benchmarks.&#039;)&lt;br /&gt;
argparser.add_argument(&lt;br /&gt;
    &#039;--card&#039;,&lt;br /&gt;
    help=&#039;What cards to run on.  Depends on Jenkins NODE_LABEL environment&#039;&lt;br /&gt;
        &#039;variable for correct mappings.&#039;)&lt;br /&gt;
argparser.add_argument(&lt;br /&gt;
    &#039;--suite&#039;, metavar=&#039;SUITE&#039;,&lt;br /&gt;
    help=&#039;Specify the appropriate benchmark suite as defined in &#039;&lt;br /&gt;
        &#039;the benchmark ini file.  Defaults to standard_perf&#039;,&lt;br /&gt;
    default=&#039;standard_perf&#039;)&lt;br /&gt;
args = argparser.parse_args()&lt;br /&gt;
&lt;br /&gt;
print args.card&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Remove an argument: [http://stackoverflow.com/questions/32807319/disable-remove-argument-in-argparse]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def remove_options(parser, options):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot; remove_options(parser, [&#039;--some-option&#039;, &#039;--some-option2&#039;]) &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    for option in options:&lt;br /&gt;
        for action in parser._actions:&lt;br /&gt;
            if vars(action)[&#039;option_strings&#039;][0] == option:&lt;br /&gt;
                parser._handle_conflict_resolve(None,[(option,action)])&lt;br /&gt;
                break&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [http://docs.python.org/library/commands.html commands] ===&lt;br /&gt;
&lt;br /&gt;
35.16. commands — Utilities for running commands — Python v2.7.1 documentation - http://docs.python.org/library/commands.html&lt;br /&gt;
&lt;br /&gt;
Note: Deprecated since version 2.6: The commands module has been removed in Python 3.0. Use the subprocess module instead.&lt;br /&gt;
&lt;br /&gt;
The commands module contains wrapper functions for os.popen() which take a system command as a string and return any output generated by the command and, optionally, the exit status.&lt;br /&gt;
&lt;br /&gt;
Get status and output:&lt;br /&gt;
 status, output = commands.getstatusoutput(cmd)&lt;br /&gt;
&lt;br /&gt;
Get output ignoring status:&lt;br /&gt;
 output = commands.getoutput(cmd)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
NOTE: DO NOT USE getstatus() AS IT DOES NOT DO WHAT YOU THINK IT DOES!&lt;br /&gt;
 status = commands.getstatus(file)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import commands&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; commands.getstatusoutput(&#039;ls /bin/ls&#039;)&lt;br /&gt;
(0, &#039;/bin/ls&#039;)&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; commands.getstatusoutput(&#039;cat /bin/junk&#039;)&lt;br /&gt;
(256, &#039;cat: /bin/junk: No such file or directory&#039;)&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; commands.getstatusoutput(&#039;/bin/junk&#039;)&lt;br /&gt;
(256, &#039;sh: /bin/junk: not found&#039;)&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; commands.getoutput(&#039;ls /bin/ls&#039;)&lt;br /&gt;
&#039;/bin/ls&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; commands.getstatus(&#039;/bin/ls&#039;)&lt;br /&gt;
&#039;-rwxr-xr-x  1 root        13352 Oct 14  1994 /bin/ls&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [http://docs.python.org/library/_winreg.html Windows Registry] ===&lt;br /&gt;
&lt;br /&gt;
Note: The _winreg module has been renamed to winreg in Python 3.0.&lt;br /&gt;
&lt;br /&gt;
* 32.3. winreg – Windows registry access — Python v3.2 documentation - http://docs.python.org/py3k/library/winreg.html&lt;br /&gt;
* 34.3. _winreg – Windows registry access — Python v2.7.1 documentation - http://docs.python.org/library/_winreg.html&lt;br /&gt;
&lt;br /&gt;
Read from registry:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from _winreg import *&lt;br /&gt;
key = OpenKey(HKEY_LOCAL_MACHINE, r&#039;Software\Microsoft\Outlook Express&#039;, 0, KEY_ALL_ACCESS)&lt;br /&gt;
QueryValueEx(key, &amp;quot;InstallRoot&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Write to registry:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
keyVal = r&#039;Software\Microsoft\Internet Explorer\Main&#039;&lt;br /&gt;
try:&lt;br /&gt;
    key = OpenKey(HKEY_CURRENT_USER, keyVal, 0, KEY_ALL_ACCESS)&lt;br /&gt;
except:&lt;br /&gt;
    key = CreateKey(HKEY_CURRENT_USER, keyVal)&lt;br /&gt;
SetValueEx(key, &amp;quot;Start Page&amp;quot;, 0, REG_SZ, &amp;quot;http://www.blog.pythonlibrary.org/&amp;quot;)&lt;br /&gt;
CloseKey(key)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Enumerate registry keys:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from _winreg import EnumKey, HKEY_USERS&lt;br /&gt;
 &lt;br /&gt;
try:&lt;br /&gt;
    i = 0&lt;br /&gt;
    while True:&lt;br /&gt;
        subkey = EnumKey(HKEY_USERS, i)&lt;br /&gt;
        print subkey&lt;br /&gt;
        i += 1&lt;br /&gt;
except WindowsError:&lt;br /&gt;
    # WindowsError: [Errno 259] No more data is available    &lt;br /&gt;
    pass&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Another enumeration example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# File: winreg-example-1.py&lt;br /&gt;
&lt;br /&gt;
import _winreg&lt;br /&gt;
&lt;br /&gt;
explorer = _winreg.OpenKey(&lt;br /&gt;
    _winreg.HKEY_CURRENT_USER,&lt;br /&gt;
    &amp;quot;Software\\Microsoft\\Windows\\CurrentVersion\\Explorer&amp;quot;&lt;br /&gt;
    )&lt;br /&gt;
&lt;br /&gt;
# list values owned by this registry key&lt;br /&gt;
try:&lt;br /&gt;
    i = 0&lt;br /&gt;
    while 1:&lt;br /&gt;
        name, value, type = _winreg.EnumValue(explorer, i)&lt;br /&gt;
        print repr(name),&lt;br /&gt;
        i += 1&lt;br /&gt;
except WindowsError:&lt;br /&gt;
    print&lt;br /&gt;
&lt;br /&gt;
value, type = _winreg.QueryValueEx(explorer, &amp;quot;Logon User Name&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
print&lt;br /&gt;
print &amp;quot;user is&amp;quot;, repr(value)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Enable Remote Desktop Example: (by Kenneth)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from _winreg import *&lt;br /&gt;
key = OpenKey(HKEY_LOCAL_MACHINE, r&#039;SYSTEM\CurrentControlSet\Control\Terminal Server&#039;, 0, KEY_ALL_ACCESS)&lt;br /&gt;
SetValueEx(key, &amp;quot;fDenyTSConnections&amp;quot;, 0, REG_DWORD, 0)&lt;br /&gt;
ValueTypeTuple = QueryValueEx(key, &amp;quot;fDenyTSConnections&amp;quot;)   # (0, 4)&lt;br /&gt;
print(&amp;quot;Please reboot the system to complete the changes&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* Python’s _winreg: Editing the Windows Registry « The Mouse Vs. The Python - http://www.blog.pythonlibrary.org/2010/03/20/pythons-_winreg-editing-the-windows-registry/&lt;br /&gt;
&lt;br /&gt;
=== JSON ===&lt;br /&gt;
&lt;br /&gt;
JSON - http://docs.python.org/library/json.html&lt;br /&gt;
&lt;br /&gt;
ENCODING TO JSON STRING (type str)&lt;br /&gt;
&lt;br /&gt;
 import json&lt;br /&gt;
 json.dumps([&#039;foo&#039;, {&#039;bar&#039;: (&#039;baz&#039;, None, 1.0, 2)}])&lt;br /&gt;
 # &#039;[&amp;quot;foo&amp;quot;, {&amp;quot;bar&amp;quot;: [&amp;quot;baz&amp;quot;, null, 1.0, 2]}]&#039;&lt;br /&gt;
&lt;br /&gt;
compact encoding:&lt;br /&gt;
 import json&lt;br /&gt;
 json.dumps([1,2,3,{&#039;4&#039;: 5, &#039;6&#039;: 7}], separators=(&#039;,&#039;,&#039;:&#039;))&lt;br /&gt;
 # &#039;[1,2,3,{&amp;quot;4&amp;quot;:5,&amp;quot;6&amp;quot;:7}]&#039;&lt;br /&gt;
&lt;br /&gt;
Pretty printing:&lt;br /&gt;
 import json&lt;br /&gt;
 print json.dumps({&#039;4&#039;: 5, &#039;6&#039;: 7}, sort_keys=True, indent=4)&lt;br /&gt;
 # {&lt;br /&gt;
 #     &amp;quot;4&amp;quot;: 5,&lt;br /&gt;
 #     &amp;quot;6&amp;quot;: 7&lt;br /&gt;
 # }&lt;br /&gt;
&lt;br /&gt;
DECODING JSON STRING TO PYTHON LIST OR DICTIONARY OBJECT&lt;br /&gt;
&lt;br /&gt;
 import json&lt;br /&gt;
 json.loads(&#039;[&amp;quot;foo&amp;quot;, {&amp;quot;bar&amp;quot;:[&amp;quot;baz&amp;quot;, null, 1.0, 2]}]&#039;)&lt;br /&gt;
 # [u&#039;foo&#039;, {u&#039;bar&#039;: [u&#039;baz&#039;, None, 1.0, 2]}]&lt;br /&gt;
&lt;br /&gt;
Load from file:&lt;br /&gt;
 f = open(filename)&lt;br /&gt;
 j = json.load(f)&lt;br /&gt;
 print j[&amp;quot;kind&amp;quot;]  # &amp;quot;dual-controller-adapter&amp;quot;&lt;br /&gt;
 #{&lt;br /&gt;
 #   &amp;quot;kind&amp;quot;: &amp;quot;dual-controller-adapter&amp;quot;,&lt;br /&gt;
 #}&lt;br /&gt;
&lt;br /&gt;
From Command Line:&lt;br /&gt;
 echo &#039;{&amp;quot;foo&amp;quot;: &amp;quot;lorem&amp;quot;, &amp;quot;bar&amp;quot;: &amp;quot;ipsum&amp;quot;}&#039; | python -mjson.tool&lt;br /&gt;
&lt;br /&gt;
 # get value&lt;br /&gt;
 echo &#039;{&amp;quot;test&amp;quot;:1,&amp;quot;test2&amp;quot;:2}&#039; | python -c &#039;import sys,json;data=json.loads(sys.stdin.read()); print data[&amp;quot;test&amp;quot;]&#039;&lt;br /&gt;
&lt;br /&gt;
 # read large file&lt;br /&gt;
 python -c &amp;quot;import json;f=open(&#039;file.json&#039;);data=json.load(f);print json.dumps(data,indent=2)&amp;quot;&lt;br /&gt;
 python -c &amp;quot;import json;print json.dumps(json.load(open(&#039;file.json&#039;)),indent=2)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Load from web:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import httplib&lt;br /&gt;
import json&lt;br /&gt;
&lt;br /&gt;
def get_http_json(server, path):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot; This performs an HTTP GET against a server and path and returns the&lt;br /&gt;
        resulting page data.&lt;br /&gt;
&lt;br /&gt;
        server The server we&#039;re hitting, e.g. demo.com&lt;br /&gt;
        path   The path we&#039;re hitting, e.g. api/part/MA12345/&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    connection = httplib.HTTPConnection(server)&lt;br /&gt;
    try:&lt;br /&gt;
        url = &#039;http://%s/%s&#039; % (server, path)&lt;br /&gt;
        print &#039;Querying url %s&#039; % url&lt;br /&gt;
        connection.request(&#039;GET&#039;, url)&lt;br /&gt;
        response = connection.getresponse()&lt;br /&gt;
        if response.status == httplib.OK:&lt;br /&gt;
            return json.loads(response.read())&lt;br /&gt;
        else:&lt;br /&gt;
            print &#039;Unable to get %s. %s %s&#039; % (url, response.reason,&lt;br /&gt;
                    response.status)&lt;br /&gt;
            return None&lt;br /&gt;
    finally:&lt;br /&gt;
        connection.close()&lt;br /&gt;
&lt;br /&gt;
j = get_http_json(server, path)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pretty printing from the command line:&lt;br /&gt;
 echo &#039;{&amp;quot;json&amp;quot;:&amp;quot;obj&amp;quot;}&#039; | python -mjson.tool&lt;br /&gt;
 #{&lt;br /&gt;
 #   &amp;quot;json&amp;quot;: &amp;quot;obj&amp;quot;&lt;br /&gt;
 #}&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* 18.2. json — JSON encoder and decoder — Python v2.7.1 documentation - http://docs.python.org/library/json.html&lt;br /&gt;
&lt;br /&gt;
=== Sockets ===&lt;br /&gt;
&lt;br /&gt;
See [[Python/Sockets]]&lt;br /&gt;
&lt;br /&gt;
=== [http://docs.python.org/library/base64.html base64] ===&lt;br /&gt;
&lt;br /&gt;
 import base64&lt;br /&gt;
&lt;br /&gt;
Encode:&lt;br /&gt;
 encoded = base64.b64encode(&#039;data to be encoded&#039;)&lt;br /&gt;
&lt;br /&gt;
Decode:&lt;br /&gt;
 base64.b64decode(encoded)&lt;br /&gt;
&lt;br /&gt;
=== daemonize ===&lt;br /&gt;
&lt;br /&gt;
Creating a daemon the Python way « Python recipes « ActiveState Code - http://code.activestate.com/recipes/278731-creating-a-daemon-the-python-way/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import os&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
try:&lt;br /&gt;
    pid = os.fork()&lt;br /&gt;
except OSError, e:&lt;br /&gt;
    raise Exception, &amp;quot;%s [%d]&amp;quot; % (e.strerror, e.errno)&lt;br /&gt;
&lt;br /&gt;
if (pid != 0):  # parent&lt;br /&gt;
    os._exit(0)&lt;br /&gt;
&lt;br /&gt;
# create new process session&lt;br /&gt;
os.setsid()&lt;br /&gt;
&lt;br /&gt;
# redirect stdin, stdout, stderr&lt;br /&gt;
os.open(&#039;/dev/null&#039;, os.O_RDWR)&lt;br /&gt;
os.dup2(0, 1)&lt;br /&gt;
os.dup2(0, 2)&lt;br /&gt;
&lt;br /&gt;
#... tasks ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
My Solution:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import os&lt;br /&gt;
import sys&lt;br /&gt;
import signal&lt;br /&gt;
import syslog&lt;br /&gt;
&lt;br /&gt;
HUP = False&lt;br /&gt;
&lt;br /&gt;
def log(msg):&lt;br /&gt;
    syslog.syslog(str(msg))&lt;br /&gt;
syslog.openlog(&#039;[WATER]&#039;)&lt;br /&gt;
&lt;br /&gt;
def kill_signal_handler(signal, frame):&lt;br /&gt;
    log(&amp;quot;Being killed off: {0} {1}&amp;quot;.format(signal, frame))&lt;br /&gt;
    log(&amp;quot;Shutting Down!&amp;quot;)&lt;br /&gt;
    sys.exit(0)&lt;br /&gt;
signal.signal(signal.SIGTERM, kill_signal_handler)&lt;br /&gt;
signal.signal(signal.SIGALRM, kill_signal_handler)&lt;br /&gt;
&lt;br /&gt;
def hup_signal_handler(signal, frame):&lt;br /&gt;
    global HUP&lt;br /&gt;
    log(&amp;quot;Signal reload received: {0} {1}&amp;quot;.format(signal, frame))&lt;br /&gt;
    HUP=True&lt;br /&gt;
signal.signal(signal.SIGHUP, hup_signal_handler)&lt;br /&gt;
&lt;br /&gt;
def main_loop():&lt;br /&gt;
    global HUP&lt;br /&gt;
&lt;br /&gt;
    while True:&lt;br /&gt;
        #  ... handle HUP=True ...&lt;br /&gt;
&lt;br /&gt;
        # ... main code ...&lt;br /&gt;
&lt;br /&gt;
        # wait 60 seconds before we start the next loop&lt;br /&gt;
        time.sleep(60)  # signals will interrupt this&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
    log(&amp;quot;Starting Daemon...&amp;quot;)&lt;br /&gt;
    child_id = os.fork()&lt;br /&gt;
    if child_id:&lt;br /&gt;
        log(&amp;quot;Daemonized!&amp;quot;)&lt;br /&gt;
        sys.exit(0)&lt;br /&gt;
    os.setsid()&lt;br /&gt;
    # redirect stdin, stdout, stderr&lt;br /&gt;
    os.open(&#039;/dev/null&#039;, os.O_RDWR)&lt;br /&gt;
    os.dup2(0, 1)&lt;br /&gt;
    os.dup2(0, 2)&lt;br /&gt;
&lt;br /&gt;
    # write pid&lt;br /&gt;
    with open(&amp;quot;water.pid&amp;quot;, &amp;quot;w&amp;quot;) as f:&lt;br /&gt;
        f.write(str(os.getpid()))&lt;br /&gt;
&lt;br /&gt;
    while True:&lt;br /&gt;
        try:&lt;br /&gt;
            main_loop()&lt;br /&gt;
        except Exception as e:&lt;br /&gt;
            log(&amp;quot;Critical Failure Caught: %s&amp;quot; % str(e))&lt;br /&gt;
            log(&amp;quot;Critical Failure - Restarting!&amp;quot;)&lt;br /&gt;
            time.sleep(30)&lt;br /&gt;
            #raise e&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 ln -s /opt/pyton27/bin/python pyton-water&lt;br /&gt;
 ./python-water water.py&lt;br /&gt;
 killall python-water&lt;br /&gt;
&lt;br /&gt;
==== fork ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import os&lt;br /&gt;
import sys&lt;br /&gt;
import time&lt;br /&gt;
&lt;br /&gt;
child_id = os.fork()&lt;br /&gt;
if child_id:&lt;br /&gt;
  print &amp;quot;parent exiting&amp;quot;&lt;br /&gt;
  sys.exit(0)&lt;br /&gt;
&lt;br /&gt;
while True:&lt;br /&gt;
    time.sleep(3)&lt;br /&gt;
    print &amp;quot;child&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For windows, to hide the console, see [[#Hide Console]]&lt;br /&gt;
&lt;br /&gt;
=== csv ===&lt;br /&gt;
&lt;br /&gt;
13.1. csv — CSV File Reading and Writing — Python v2.7.2 documentation - http://docs.python.org/library/csv.html&lt;br /&gt;
&lt;br /&gt;
Read:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import csv&lt;br /&gt;
spamReader = csv.reader(open(&#039;eggs.csv&#039;, &#039;rb&#039;), delimiter=&#039; &#039;, quotechar=&#039;|&#039;)&lt;br /&gt;
for row in spamReader:&lt;br /&gt;
  print &#039;, &#039;.join(row)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Write:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import csv&lt;br /&gt;
spamWriter = csv.writer(open(&#039;eggs.csv&#039;, &#039;wb&#039;), delimiter=&#039; &#039;,&lt;br /&gt;
    quotechar=&#039;|&#039;, quoting=csv.QUOTE_MINIMAL)&lt;br /&gt;
spamWriter.writerow([&#039;Spam&#039;] * 5 + [&#039;Baked Beans&#039;])&lt;br /&gt;
spamWriter.writerow([&#039;Spam&#039;, &#039;Lovely Spam&#039;, &#039;Wonderful Spam&#039;])&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== SQLite ===&lt;br /&gt;
&lt;br /&gt;
11.13. sqlite3 — DB-API 2.0 interface for SQLite databases — Python v2.7.2 documentation - http://docs.python.org/library/sqlite3.html&lt;br /&gt;
&lt;br /&gt;
sqlite3 - New in version 2.5.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import sqlite3&lt;br /&gt;
&lt;br /&gt;
conn = sqlite3.connect(&#039;/tmp/example&#039;)&lt;br /&gt;
&lt;br /&gt;
c = conn.cursor()&lt;br /&gt;
&lt;br /&gt;
# Create table&lt;br /&gt;
c.execute(&#039;&#039;&#039;create table stocks&lt;br /&gt;
(date text, trans text, symbol text,&lt;br /&gt;
 qty real, price real)&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
# Insert a row of data&lt;br /&gt;
c.execute(&amp;quot;&amp;quot;&amp;quot;insert into stocks&lt;br /&gt;
          values (&#039;2006-01-05&#039;,&#039;BUY&#039;,&#039;RHAT&#039;,100,35.14)&amp;quot;&amp;quot;&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
# Show affected row count&lt;br /&gt;
print c.rowcount&lt;br /&gt;
&lt;br /&gt;
# Save (commit) the changes&lt;br /&gt;
conn.commit()&lt;br /&gt;
&lt;br /&gt;
# We can also close the cursor if we are done with it&lt;br /&gt;
c.close()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
parameter substitution:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Never do this -- insecure!&lt;br /&gt;
symbol = &#039;IBM&#039;&lt;br /&gt;
c.execute(&amp;quot;... where symbol = &#039;%s&#039;&amp;quot; % symbol)&lt;br /&gt;
&lt;br /&gt;
# Do this instead&lt;br /&gt;
t = (symbol,)&lt;br /&gt;
c.execute(&#039;select * from stocks where symbol=?&#039;, t)&lt;br /&gt;
c.execute(&#039;select * from stocks where symbol=?&#039;, (symbol,))&lt;br /&gt;
&lt;br /&gt;
# Larger example&lt;br /&gt;
for t in [(&#039;2006-03-28&#039;, &#039;BUY&#039;, &#039;IBM&#039;, 1000, 45.00),&lt;br /&gt;
          (&#039;2006-04-05&#039;, &#039;BUY&#039;, &#039;MSOFT&#039;, 1000, 72.00),&lt;br /&gt;
          (&#039;2006-04-06&#039;, &#039;SELL&#039;, &#039;IBM&#039;, 500, 53.00),&lt;br /&gt;
         ]:&lt;br /&gt;
    c.execute(&#039;insert into stocks values (?,?,?,?,?)&#039;, t)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
select results:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
c = conn.cursor()&lt;br /&gt;
c.execute(&#039;select * from stocks order by price&#039;)&lt;br /&gt;
&lt;br /&gt;
for row in c:&lt;br /&gt;
  print row  # row is a tuple&lt;br /&gt;
&lt;br /&gt;
# OR (but not both)&lt;br /&gt;
&lt;br /&gt;
rows = c.fetchall()    # rows is list of tuples&lt;br /&gt;
print len(rows)&lt;br /&gt;
for row in rows:&lt;br /&gt;
  print row&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Show which version of sqlite3: [http://zetcode.com/db/sqlitepythontutorial/]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/python&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&lt;br /&gt;
import sqlite3 as lite&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
con = None&lt;br /&gt;
&lt;br /&gt;
try:&lt;br /&gt;
    con = lite.connect(&#039;test.db&#039;)&lt;br /&gt;
&lt;br /&gt;
    cur = con.cursor()&lt;br /&gt;
    cur.execute(&#039;SELECT SQLITE_VERSION()&#039;)&lt;br /&gt;
&lt;br /&gt;
    data = cur.fetchone()&lt;br /&gt;
&lt;br /&gt;
    print &amp;quot;SQLite version: %s&amp;quot; % data&lt;br /&gt;
&lt;br /&gt;
except lite.Error, e:&lt;br /&gt;
&lt;br /&gt;
    print &amp;quot;Error %s:&amp;quot; % e.args[0]&lt;br /&gt;
    sys.exit(1)&lt;br /&gt;
&lt;br /&gt;
finally:&lt;br /&gt;
&lt;br /&gt;
    if con:&lt;br /&gt;
        con.close()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Or simply: [http://stackoverflow.com/questions/1545479/force-python-to-forego-native-sqlite3-and-use-the-installed-latest-sqlite3-ver]&lt;br /&gt;
 # echo -e &amp;quot;import sqlite3\nprint sqlite3.sqlite_version_info&amp;quot; | python&lt;br /&gt;
 (3, 3, 6)&lt;br /&gt;
&lt;br /&gt;
=== MySQL Database ===&lt;br /&gt;
&lt;br /&gt;
Ubuntu packages:&lt;br /&gt;
* python-mysqldb - Python interface to MySQL&lt;br /&gt;
* python-mysql.connector - pure Python implementation of MySQL Client/Server protocol&lt;br /&gt;
&lt;br /&gt;
 apt-get install python-mysqldb&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; import _mysql&lt;br /&gt;
&lt;br /&gt;
 apt-get install python-mysql.connector&lt;br /&gt;
 &lt;br /&gt;
PIP:&lt;br /&gt;
* https://pypi.python.org/pypi/MySQL-python&lt;br /&gt;
* https://pypi.python.org/pypi/mysqlclient&lt;br /&gt;
&lt;br /&gt;
 pip install MySQL-python&lt;br /&gt;
&lt;br /&gt;
 pip install mysqlclient&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
_mysql - http://mysql-python.sourceforge.net/MySQLdb.html&lt;br /&gt;
&lt;br /&gt;
 apt-get install python-mysqldb&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import _mysql&lt;br /&gt;
&lt;br /&gt;
db=_mysql.connect(host=&amp;quot;localhost&amp;quot;,user=&amp;quot;user&amp;quot;,&lt;br /&gt;
                  passwd=&amp;quot;pass&amp;quot;,db=&amp;quot;db&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
db.query(&amp;quot;&amp;quot;&amp;quot;SELECT spam, eggs, sausage FROM breakfast&lt;br /&gt;
         WHERE price &amp;lt; 5&amp;quot;&amp;quot;&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
r=db.store_result()&lt;br /&gt;
# ...or...&lt;br /&gt;
r=db.use_result()&lt;br /&gt;
&lt;br /&gt;
row = r.fetch_row()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== couchdb ===&lt;br /&gt;
&lt;br /&gt;
Getting started with couchdb-python — couchdb-python v0.8 documentation - http://packages.python.org/CouchDB/getting-started.html&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
couch = couchdb.Server(&#039;http://127.0.0.1:5984/&#039;)&lt;br /&gt;
&lt;br /&gt;
# database&lt;br /&gt;
db = couch.create(&#039;test&#039;) # create new&lt;br /&gt;
db = couch[&#039;mydb&#039;] # or get existing&lt;br /&gt;
&lt;br /&gt;
# print databases:&lt;br /&gt;
for db in couch:&lt;br /&gt;
  print db&lt;br /&gt;
&lt;br /&gt;
doc = {&#039;foo&#039;: &#039;bar&#039;}&lt;br /&gt;
doc_id, doc_rev = db.save(doc)&lt;br /&gt;
# (u&#039;9278f7691c3421227a9f8436540008f9&#039;, u&#039;1-4c6114c65e295552ab1019e2b046b10e&#039;)&lt;br /&gt;
# note: this also updates doc with _rev and _id&lt;br /&gt;
doc = db[&#039;9278f7691c3421227a9f8436540008f9&#039;]&lt;br /&gt;
&lt;br /&gt;
# better to create a document using an id you want, instead of the randomly generated one&lt;br /&gt;
db[doc.id] = doc  # this will write immediately to the database&lt;br /&gt;
&lt;br /&gt;
# print all docs:&lt;br /&gt;
for id in db:&lt;br /&gt;
  print id&lt;br /&gt;
&lt;br /&gt;
# delete doc&lt;br /&gt;
db.delete(doc)&lt;br /&gt;
&lt;br /&gt;
# delete database&lt;br /&gt;
couch.delete(&#039;test&#039;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Search database:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# show all records&lt;br /&gt;
map_fun = &#039;&#039;&#039;function(doc) { emit(doc.name, null); }&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
# row = &amp;lt;Row id=u&#039;12341234123412341234&#039;, key=None, value=None&amp;gt;&lt;br /&gt;
# emit(key, value) - returns the values for key and value&lt;br /&gt;
&lt;br /&gt;
map_fun = &#039;&#039;&#039;&lt;br /&gt;
function(doc) {&lt;br /&gt;
  if (doc.username == &#039;virt-01&#039;)&lt;br /&gt;
     emit(doc.username, null);&lt;br /&gt;
}&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
# row = &amp;lt;Row id=u&#039;12341234123412341234&#039;, key=None, value=None&amp;gt;&lt;br /&gt;
for row in db.query(map_fun):&lt;br /&gt;
  print row.id&lt;br /&gt;
&lt;br /&gt;
for row in db.query(map_fun, descending=True):&lt;br /&gt;
  print row.id&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
couchdb-python - CouchDB Python Library - Google Project Hosting - http://code.google.com/p/couchdb-python/&lt;br /&gt;
&lt;br /&gt;
Installation:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir -p ~/.src ; cd ~/.src&lt;br /&gt;
wget http://pypi.python.org/packages/source/C/CouchDB/CouchDB-0.8.tar.gz#md5=e32b39e459e1fa2586ea252712a11a59&lt;br /&gt;
tar -zvxf CouchDB-0.8.tar.gz&lt;br /&gt;
cd CouchDB-0.8&lt;br /&gt;
python setup.py install&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Test:&lt;br /&gt;
 echo &amp;quot;import couchdb&amp;quot; | python&lt;br /&gt;
&lt;br /&gt;
=== nose ===&lt;br /&gt;
&lt;br /&gt;
nose: nose extends unittest to make testing easier&lt;br /&gt;
&lt;br /&gt;
nose : Python Package Index - http://pypi.python.org/pypi/nose&lt;br /&gt;
&lt;br /&gt;
Install:&lt;br /&gt;
 mkdir -p ~/.src ; cd ~/.src&lt;br /&gt;
 wget http://pypi.python.org/packages/source/n/nose/nose-1.1.2.tar.gz#md5=144f237b615e23f21f6a50b2183aa817&lt;br /&gt;
 tar -zvxf nose-1.1.2.tar.gz&lt;br /&gt;
 cd nose-1.1.2&lt;br /&gt;
 sudo python setup.py install&lt;br /&gt;
&lt;br /&gt;
skeleton:&lt;br /&gt;
 mkdir skeleton&lt;br /&gt;
 cd skeleton&lt;br /&gt;
 mkdir bin NAME tests docs&lt;br /&gt;
 touch NAME/__init__.py&lt;br /&gt;
 touch tests/__init__.py&lt;br /&gt;
 touch tests/NAME_tests.py&lt;br /&gt;
&lt;br /&gt;
nose test skeleton:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# tests/NAME_tests.py&lt;br /&gt;
from nose.tools import *&lt;br /&gt;
import klib&lt;br /&gt;
&lt;br /&gt;
def setup():&lt;br /&gt;
    print &amp;quot;SETUP!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
def teardown():&lt;br /&gt;
    print &amp;quot;TEAR DOWN!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
def test_basic():&lt;br /&gt;
    print &amp;quot;I RAN!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# def test_something_else():&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
 nosetests&lt;br /&gt;
&lt;br /&gt;
See Also:&lt;br /&gt;
* [[#doctest]]&lt;br /&gt;
* [[#unittest]]&lt;br /&gt;
&lt;br /&gt;
=== pydoc ===&lt;br /&gt;
&lt;br /&gt;
25.1. pydoc — Documentation generator and online help system — Python v2.7.2 documentation - http://docs.python.org/library/pydoc.html&lt;br /&gt;
&lt;br /&gt;
pydoc - The pydoc module automatically generates documentation from Python modules.&lt;br /&gt;
&lt;br /&gt;
pydoc - same as &#039;import [library], help([library])&#039;&lt;br /&gt;
 $ pydoc [library]&lt;br /&gt;
&lt;br /&gt;
Note: lists some special &#039;module metadata variables&#039; separately (e.g. version, author).&lt;br /&gt;
&lt;br /&gt;
special pydoc recognized metadata sections:&lt;br /&gt;
 __version__&lt;br /&gt;
 __author__&lt;br /&gt;
 __credits__&lt;br /&gt;
 __date__&lt;br /&gt;
&lt;br /&gt;
==== pydoc function module ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Help on package klib:&lt;br /&gt;
&lt;br /&gt;
NAME&lt;br /&gt;
    klib - This is the name&lt;br /&gt;
&lt;br /&gt;
FILE&lt;br /&gt;
    /root/klib/klib/__init__.py&lt;br /&gt;
&lt;br /&gt;
DESCRIPTION&lt;br /&gt;
    These are module doc strings&lt;br /&gt;
        that give helpful details&lt;br /&gt;
&lt;br /&gt;
PACKAGE CONTENTS&lt;br /&gt;
    markone&lt;br /&gt;
&lt;br /&gt;
FUNCTIONS&lt;br /&gt;
    func1()&lt;br /&gt;
        This is a doc string&lt;br /&gt;
        for func1&lt;br /&gt;
&lt;br /&gt;
DATA&lt;br /&gt;
    PI = 3.141&lt;br /&gt;
    __all__ = [&#039;func1&#039;, &#039;PI&#039;]&lt;br /&gt;
    __author__ = &#039;Kenneth &amp;lt;kenneth@oeey.com&amp;gt;&#039;&lt;br /&gt;
    __copyright__ = &#039;Copyright 2007, The Project&#039;&lt;br /&gt;
    __credits__ = &#039;Credits go to me&#039;&lt;br /&gt;
    __date__ = &#039;26 February 2001&#039;&lt;br /&gt;
    __email__ = &#039;ken@oeey.com&#039;&lt;br /&gt;
    __license__ = &#039;GPL&#039;&lt;br /&gt;
    __maintainer__ = &#039;Ken&#039;&lt;br /&gt;
    __status__ = &#039;Production&#039;&lt;br /&gt;
    __version__ = &#039;$Revision: 83492 $&#039;&lt;br /&gt;
&lt;br /&gt;
VERSION&lt;br /&gt;
    83492&lt;br /&gt;
&lt;br /&gt;
DATE&lt;br /&gt;
    26 February 2001&lt;br /&gt;
&lt;br /&gt;
AUTHOR&lt;br /&gt;
    Kenneth &amp;lt;kenneth@oeey.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
CREDITS&lt;br /&gt;
    Credits go to me&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Source:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
This is the name&lt;br /&gt;
&lt;br /&gt;
These are module doc strings&lt;br /&gt;
    that give helpful details&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#__version__ = &amp;quot;1.0&amp;quot;&lt;br /&gt;
__version__ = &amp;quot;$Revision: 83492 $&amp;quot;&lt;br /&gt;
__author__ = &amp;quot;Kenneth &amp;lt;kenneth@oeey.com&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
__date__ = &amp;quot;26 February 2001&amp;quot;&lt;br /&gt;
__credits__ = &amp;quot;Credits go to me&amp;quot;&lt;br /&gt;
&lt;br /&gt;
__all__ = [&#039;func1&#039;, &#039;PI&#039;]&lt;br /&gt;
&lt;br /&gt;
PI = 3.141&lt;br /&gt;
&lt;br /&gt;
__copyright__ = &#039;hello license&#039;&lt;br /&gt;
__license__ = &amp;quot;GPL&amp;quot;&lt;br /&gt;
__copyright__ = &amp;quot;Copyright 2007, The Project&amp;quot;&lt;br /&gt;
__maintainer__ = &amp;quot;Ken&amp;quot;&lt;br /&gt;
__email__ = &amp;quot;ken@oeey.com&amp;quot;&lt;br /&gt;
__status__ = &amp;quot;Production&amp;quot;&lt;br /&gt;
&lt;br /&gt;
def func1():&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    This is a doc string&lt;br /&gt;
    for func1&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== pydoc class module ====&lt;br /&gt;
&lt;br /&gt;
Sample:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Help on module class_pydoc:&lt;br /&gt;
&lt;br /&gt;
NAME&lt;br /&gt;
    class_pydoc - This is the name&lt;br /&gt;
&lt;br /&gt;
FILE&lt;br /&gt;
    /root/class_pydoc.py&lt;br /&gt;
&lt;br /&gt;
DESCRIPTION&lt;br /&gt;
    These are module doc strings&lt;br /&gt;
        that give helpful details&lt;br /&gt;
&lt;br /&gt;
CLASSES&lt;br /&gt;
    Toad&lt;br /&gt;
&lt;br /&gt;
    class Toad&lt;br /&gt;
     |  doc string for object&lt;br /&gt;
     |&lt;br /&gt;
     |  Methods defined here:&lt;br /&gt;
     |&lt;br /&gt;
     |  __init___(self, name)&lt;br /&gt;
     |      Constructor&lt;br /&gt;
     |&lt;br /&gt;
     |  instance_function(self)&lt;br /&gt;
     |      Instance Function&lt;br /&gt;
     |&lt;br /&gt;
     |  ----------------------------------------------------------------------&lt;br /&gt;
     |  Class methods defined here:&lt;br /&gt;
     |&lt;br /&gt;
     |  class_function(cls) from __builtin__.classobj&lt;br /&gt;
     |      Class Function&lt;br /&gt;
     |&lt;br /&gt;
     |  ----------------------------------------------------------------------&lt;br /&gt;
     |  Data and other attributes defined here:&lt;br /&gt;
     |&lt;br /&gt;
     |  my_class_attribute = &#039;sample class attribute&#039;&lt;br /&gt;
&lt;br /&gt;
DATA&lt;br /&gt;
    PI = 3.141&lt;br /&gt;
    __author__ = &#039;Kenneth &amp;lt;kenneth@oeey.com&amp;gt;&#039;&lt;br /&gt;
    __copyright__ = &#039;Copyright 2007, The Project&#039;&lt;br /&gt;
    __credits__ = &#039;Credits go to me&#039;&lt;br /&gt;
    __date__ = &#039;26 February 2001&#039;&lt;br /&gt;
    __email__ = &#039;ken@oeey.com&#039;&lt;br /&gt;
    __license__ = &#039;GPL&#039;&lt;br /&gt;
    __maintainer__ = &#039;Ken&#039;&lt;br /&gt;
    __status__ = &#039;Production&#039;&lt;br /&gt;
    __version__ = &#039;1.0&#039;&lt;br /&gt;
&lt;br /&gt;
VERSION&lt;br /&gt;
    1.0&lt;br /&gt;
&lt;br /&gt;
DATE&lt;br /&gt;
    26 February 2001&lt;br /&gt;
&lt;br /&gt;
AUTHOR&lt;br /&gt;
    Kenneth &amp;lt;kenneth@oeey.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
CREDITS&lt;br /&gt;
    Credits go to me&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Code:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
This is the name&lt;br /&gt;
&lt;br /&gt;
These are module doc strings&lt;br /&gt;
    that give helpful details&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
__version__ = &amp;quot;1.0&amp;quot;&lt;br /&gt;
#__version__ = &amp;quot;$Revision: 83492 $&amp;quot;&lt;br /&gt;
__author__ = &amp;quot;Kenneth &amp;lt;kenneth@oeey.com&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
__date__ = &amp;quot;26 February 2001&amp;quot;&lt;br /&gt;
__credits__ = &amp;quot;Credits go to me&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#__all__ = [&#039;func1&#039;, &#039;PI&#039;]&lt;br /&gt;
&lt;br /&gt;
PI = 3.141&lt;br /&gt;
&lt;br /&gt;
__copyright__ = &#039;hello license&#039;&lt;br /&gt;
__license__ = &amp;quot;GPL&amp;quot;&lt;br /&gt;
__copyright__ = &amp;quot;Copyright 2007, The Project&amp;quot;&lt;br /&gt;
__maintainer__ = &amp;quot;Ken&amp;quot;&lt;br /&gt;
__email__ = &amp;quot;ken@oeey.com&amp;quot;&lt;br /&gt;
__status__ = &amp;quot;Production&amp;quot;&lt;br /&gt;
&lt;br /&gt;
class Toad:&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot; doc string for object &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    my_class_attribute = &#039;sample class attribute&#039;&lt;br /&gt;
&lt;br /&gt;
    def __init___(self, name):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot; Constructor &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    def instance_function(self):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot; Instance Function &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    @classmethod&lt;br /&gt;
    def class_function(cls):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot; Class Function &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== username ===&lt;br /&gt;
&lt;br /&gt;
User ID:&lt;br /&gt;
 os.getuid()&lt;br /&gt;
&lt;br /&gt;
User Name:&lt;br /&gt;
 # fails it stdin piped to program&lt;br /&gt;
 os.getlogin()&lt;br /&gt;
&lt;br /&gt;
User Name:&lt;br /&gt;
 import sys&lt;br /&gt;
 import pwd&lt;br /&gt;
 def get_username():&lt;br /&gt;
     return pwd.getpwuid( os.getuid() )[ 0 ]&lt;br /&gt;
&lt;br /&gt;
Environment:&lt;br /&gt;
 os.environ[&#039;USER&#039;]&lt;br /&gt;
&lt;br /&gt;
=== hostname ===&lt;br /&gt;
&lt;br /&gt;
 import socket&lt;br /&gt;
 print(socket.gethostname())&lt;br /&gt;
&lt;br /&gt;
 os.uname()[1]&lt;br /&gt;
&lt;br /&gt;
 hostname = os.system(&#039;hostname&#039;)&lt;br /&gt;
&lt;br /&gt;
=== Networking ===&lt;br /&gt;
&lt;br /&gt;
==== Get Hostname ====&lt;br /&gt;
&lt;br /&gt;
 import socket&lt;br /&gt;
 print(socket.gethostname())&lt;br /&gt;
&lt;br /&gt;
==== Convert hostname to ip address ====&lt;br /&gt;
&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; socket.gethostbyaddr(&#039;demo&#039;)&lt;br /&gt;
 (&#039;demo.oeey.com&#039;, [], [&#039;10.10.10.10&#039;])&lt;br /&gt;
&lt;br /&gt;
/usr/local/bin/whatip: (or nametoip)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
# whatip - convert hostname to ip address&lt;br /&gt;
# author: Kenneth Burgener &amp;lt;kenneth@oeey.com&amp;gt; (FEB 2012)&lt;br /&gt;
#&lt;br /&gt;
&lt;br /&gt;
import socket&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
if len(sys.argv) != 2:&lt;br /&gt;
  print &amp;quot;Convert Hostname to IP Address&amp;quot;&lt;br /&gt;
  print &amp;quot;Usage: %s HOSTNAME&amp;quot; % sys.argv[0].split(&#039;/&#039;)[-1]&lt;br /&gt;
  sys.exit(1)&lt;br /&gt;
&lt;br /&gt;
hostname = sys.argv[1]&lt;br /&gt;
try:&lt;br /&gt;
  result = socket.gethostbyaddr(hostname)&lt;br /&gt;
  print result[2][0]&lt;br /&gt;
except (socket.gaierror, socket.herror) as e:&lt;br /&gt;
  print &amp;quot;Error: Unable to resolve &#039;%s&#039;&amp;quot; % hostname&lt;br /&gt;
  sys.exit(1)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Get Public IP Address ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)&lt;br /&gt;
s.connect((&amp;quot;gmail.com&amp;quot;,80))&lt;br /&gt;
print(s.getsockname()[0])&lt;br /&gt;
s.close()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
networking - Finding local IP addresses using Python&#039;s stdlib - Stack Overflow - http://stackoverflow.com/questions/166506/finding-local-ip-addresses-using-pythons-stdlib&lt;br /&gt;
&lt;br /&gt;
==== Python Network Server ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/python           # This is server.py file&lt;br /&gt;
&lt;br /&gt;
import socket               # Import socket module&lt;br /&gt;
&lt;br /&gt;
s = socket.socket()         # Create a socket object&lt;br /&gt;
host = socket.gethostname() # Get local machine name&lt;br /&gt;
port = 12345                # Reserve a port for your service.&lt;br /&gt;
s.bind((host, port))        # Bind to the port&lt;br /&gt;
&lt;br /&gt;
s.listen(5)                 # Now wait for client connection.&lt;br /&gt;
while True:&lt;br /&gt;
   c, addr = s.accept()     # Establish connection with client.&lt;br /&gt;
   print &#039;Got connection from&#039;, addr&lt;br /&gt;
   c.send(&#039;Thank you for connecting&#039;)&lt;br /&gt;
   c.close()                # Close the connection&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Source: http://www.tutorialspoint.com/python/python_networking.htm&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* 17.2. socket — Low-level networking interface — Python v2.7.5 documentation - http://docs.python.org/2/library/socket.html&lt;br /&gt;
&lt;br /&gt;
==== Python Network Client ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/python           # This is client.py file&lt;br /&gt;
&lt;br /&gt;
import socket               # Import socket module&lt;br /&gt;
&lt;br /&gt;
s = socket.socket()         # Create a socket object&lt;br /&gt;
host = socket.gethostname() # Get local machine name&lt;br /&gt;
port = 12345                # Reserve a port for your service.&lt;br /&gt;
&lt;br /&gt;
s.connect((host, port))&lt;br /&gt;
print s.recv(1024)&lt;br /&gt;
s.close                     # Close the socket when done&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Source: http://www.tutorialspoint.com/python/python_networking.htm&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* 17.2. socket — Low-level networking interface — Python v2.7.5 documentation - http://docs.python.org/2/library/socket.html&lt;br /&gt;
&lt;br /&gt;
=== Run Library Module as Script ===&lt;br /&gt;
&lt;br /&gt;
Run python with -m option:&lt;br /&gt;
 -m mod : run library module as a script (terminates option list)&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
 cat [json_file] | python -m json.tool&lt;br /&gt;
 # same as:&lt;br /&gt;
 cat [json_file] | python /opt/python26/lib/python2.6/json/tool.py&lt;br /&gt;
&lt;br /&gt;
Good for when library is buried deep in the library directories&lt;br /&gt;
&lt;br /&gt;
=== Hex ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hex(10)  # print integer as hex string&lt;br /&gt;
&#039;0xa&#039;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; sys.hexversion  # python version as integer&lt;br /&gt;
33817584&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hex(sys.hexversion)  # python version as hex&lt;br /&gt;
&#039;0x20403f0&#039;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; print &amp;quot;0x%08x&amp;quot; % sys.hexversion  # python version as hex&lt;br /&gt;
&#039;0x20403f0&#039;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; int(&#039;0xa&#039;, 16)  # hex string to integer&lt;br /&gt;
10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; int(&#039;0a&#039;, 16)  # hex string to integer&lt;br /&gt;
10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; int(&#039;0xa&#039;, 0)  # hex string to integer auto detected du to &#039;0x&#039;&lt;br /&gt;
10&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Binary ===&lt;br /&gt;
&lt;br /&gt;
Integer to Binary String with Negative Number Support: (2&#039;s complement)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# source: http://www.gossamer-threads.com/lists/python/python/645216&lt;br /&gt;
def bin(x):&lt;br /&gt;
    if x &amp;lt; -32768 or x &amp;gt; 65535:&lt;br /&gt;
        raise Exception(&amp;quot;Out of Range Error: %d&amp;quot; % x)&lt;br /&gt;
    if x &amp;lt; 0:&lt;br /&gt;
        x = 65535 + x + 1&lt;br /&gt;
    bin_str = &#039;&#039;&lt;br /&gt;
    bin_str += &#039;&#039;.join(x &amp;amp; (1 &amp;lt;&amp;lt; i) and &#039;1&#039; or &#039;0&#039; for i in range(15, 11, -1))&lt;br /&gt;
    bin_str += &#039; &#039;&lt;br /&gt;
    bin_str += &#039;&#039;.join(x &amp;amp; (1 &amp;lt;&amp;lt; i) and &#039;1&#039; or &#039;0&#039; for i in range(11, 7, -1))&lt;br /&gt;
    bin_str += &#039; &#039;&lt;br /&gt;
    bin_str += &#039;&#039;.join(x &amp;amp; (1 &amp;lt;&amp;lt; i) and &#039;1&#039; or &#039;0&#039; for i in range(7, 3, -1))&lt;br /&gt;
    bin_str += &#039; &#039;&lt;br /&gt;
    bin_str += &#039;&#039;.join(x &amp;amp; (1 &amp;lt;&amp;lt; i) and &#039;1&#039; or &#039;0&#039; for i in range(3, -1, -1))&lt;br /&gt;
    return bin_str&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Integer to Binary String:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# source: http://www.gossamer-threads.com/lists/python/python/645216&lt;br /&gt;
def bin(x):&lt;br /&gt;
    if x &amp;lt; 0 or x &amp;gt; 65535:&lt;br /&gt;
        raise Exception(&amp;quot;Out of Range Error: %d&amp;quot; % x)&lt;br /&gt;
    bin_str = &#039;&#039;&lt;br /&gt;
    bin_str = &#039;&#039;.join(x &amp;amp; (1 &amp;lt;&amp;lt; i) and &#039;1&#039; or &#039;0&#039; for i in range(15, 7, -1))&lt;br /&gt;
    bin_str = bin_str + &#039; &#039;&lt;br /&gt;
    bin_str = bin_str + &#039;&#039;.join(x &amp;amp; (1 &amp;lt;&amp;lt; i) and &#039;1&#039; or &#039;0&#039; for i in range(7, -1, -1))&lt;br /&gt;
    return bin_str&lt;br /&gt;
&lt;br /&gt;
print bin(0)      # &#039;00000000 00000000&#039;&lt;br /&gt;
print bin(1)      # &#039;00000000 00000001&#039;&lt;br /&gt;
print bin(255)    # &#039;00000000 11111111&#039;&lt;br /&gt;
print bin(256)    # &#039;00000001 00000000&#039;&lt;br /&gt;
print bin(43690)  # &#039;10101010 10101010&#039;&lt;br /&gt;
print bin(65535)  # &#039;11111111 11111111&#039;&lt;br /&gt;
print bin(65536)  # &#039;00000000 00000000&#039; - rolled over to next set!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Integer to Binary:&lt;br /&gt;
 bin(170)  # &#039;0b10101010&#039;&lt;br /&gt;
&lt;br /&gt;
Binary to Integer:&lt;br /&gt;
 int(&#039;10101010&#039;, 2)  # 170&lt;br /&gt;
&lt;br /&gt;
=== bitwise ===&lt;br /&gt;
&lt;br /&gt;
See [[#Binary]]&lt;br /&gt;
&lt;br /&gt;
BitwiseOperators - Python Wiki - http://wiki.python.org/moin/BitwiseOperators&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
The Operators:&lt;br /&gt;
&lt;br /&gt;
x &amp;lt;&amp;lt; y&lt;br /&gt;
    Returns x with the bits shifted to the left by y places (and new bits on the right-hand-side are zeros). This is the same as multiplying x by 2**y. &lt;br /&gt;
x &amp;gt;&amp;gt; y&lt;br /&gt;
    Returns x with the bits shifted to the right by y places. This is the same as //&#039;ing x by 2**y. &lt;br /&gt;
x &amp;amp; y&lt;br /&gt;
    AND - Does a &amp;quot;bitwise and&amp;quot;. Each bit of the output is 1 if the corresponding bit of x AND of y is 1, otherwise it&#039;s 0. &lt;br /&gt;
x | y&lt;br /&gt;
    OR - Does a &amp;quot;bitwise or&amp;quot;. Each bit of the output is 0 if the corresponding bit of x AND of y is 0, otherwise it&#039;s 1. &lt;br /&gt;
~ x&lt;br /&gt;
    Returns the complement of x - the number you get by switching each 1 for a 0 and each 0 for a 1. This is the same as -x - 1. &lt;br /&gt;
x ^ y&lt;br /&gt;
    XOR - Does a &amp;quot;bitwise exclusive or&amp;quot;. Each bit of the output is the same as the corresponding bit in x if that bit in y is 0, and it&#039;s the complement of the bit in x if that bit in y is 1. &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Script Path ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
    # Change directory to where this script lives so we can find relative&lt;br /&gt;
    # paths from here regardless of where the working directory was when we&lt;br /&gt;
    # ran the script.&lt;br /&gt;
    # APP_DIR = os.path.dirname(sys.argv[0])&lt;br /&gt;
    APP_DIR = os.path.dirname(os.path.abspath(sys.argv[0))&lt;br /&gt;
    if APP_DIR:&lt;br /&gt;
        os.chdir(APP_DIR)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 normpath(path)  # Normalize path, eliminating double slashes, etc.&lt;br /&gt;
 abspath(path)   # Return an absolute path&lt;br /&gt;
&lt;br /&gt;
Path to a module: [http://stackoverflow.com/questions/247770/retrieving-python-module-path] (couldn&#039;t fine a_module)&lt;br /&gt;
 import a_module&lt;br /&gt;
 import os&lt;br /&gt;
 path = os.path.dirname(a_module.__file__)&lt;br /&gt;
&lt;br /&gt;
Path to module: [http://stackoverflow.com/questions/50499/in-python-how-do-i-get-the-path-and-name-of-the-file-that-is-currently-executin]&lt;br /&gt;
 import inspect, os&lt;br /&gt;
 print inspect.getfile(inspect.currentframe()) # script filename (usually with path)&lt;br /&gt;
 print os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) # script directory&lt;br /&gt;
&lt;br /&gt;
Even better:&lt;br /&gt;
 print os.path.realpath(__file__)&lt;br /&gt;
 print os.path.dirname(__file__)&lt;br /&gt;
 print os.path.basename(__file__)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
references:&lt;br /&gt;
* http://stackoverflow.com/questions/595305/python-path-of-script&lt;br /&gt;
&lt;br /&gt;
keywords: scriptpath script path program path pathname&lt;br /&gt;
&lt;br /&gt;
=== Singleton ===&lt;br /&gt;
&lt;br /&gt;
GLOBAL OBJECT!&lt;br /&gt;
&lt;br /&gt;
None is a singleton (Python only has one copy of None in the interpreter).&lt;br /&gt;
&lt;br /&gt;
Make your own singleton:&lt;br /&gt;
&lt;br /&gt;
override the new method like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Singleton(object):&lt;br /&gt;
    _instance = None&lt;br /&gt;
    def __new__(cls, *args, **kwargs):&lt;br /&gt;
        if not cls._instance:&lt;br /&gt;
            cls._instance = super(Singleton, cls).__new__(&lt;br /&gt;
                                cls, *args, **kwargs)&lt;br /&gt;
        return cls._instance&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
if __name__ == &#039;__main__&#039;:&lt;br /&gt;
    s1=Singleton()&lt;br /&gt;
    s2=Singleton()&lt;br /&gt;
    if(id(s1)==id(s2)):&lt;br /&gt;
        print &amp;quot;Same&amp;quot;&lt;br /&gt;
    else:&lt;br /&gt;
        print &amp;quot;Different&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Using decorator -implementation from PEP318? Implementing the singleton pattern with a decorator:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def singleton(cls):&lt;br /&gt;
    instances = {}&lt;br /&gt;
    def getinstance():&lt;br /&gt;
        if cls not in instances:&lt;br /&gt;
            instances[cls] = cls()&lt;br /&gt;
        return instances[cls]&lt;br /&gt;
    return getinstance&lt;br /&gt;
&lt;br /&gt;
@singleton&lt;br /&gt;
class MyClass:&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Python and the Singleton Pattern - Stack Overflow - http://stackoverflow.com/questions/42558/python-and-the-singleton-pattern&lt;br /&gt;
&lt;br /&gt;
=== XML ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from xml.dom.minidom import parse, parseString&lt;br /&gt;
&lt;br /&gt;
dom1 = parse(&#039;c:\\temp\\mydata.xml&#039;) # parse an XML file by name&lt;br /&gt;
&lt;br /&gt;
datasource = open(&#039;c:\\temp\\mydata.xml&#039;)&lt;br /&gt;
dom2 = parse(datasource)   # parse an open file&lt;br /&gt;
&lt;br /&gt;
dom3 = parseString(&#039;&amp;lt;myxml&amp;gt;Some data&amp;lt;empty/&amp;gt; some more data&amp;lt;/myxml&amp;gt;&#039;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pretty Print: [http://stackoverflow.com/questions/749796/pretty-printing-xml-in-python]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import xml.dom.minidom&lt;br /&gt;
&lt;br /&gt;
xml = xml.dom.minidom.parse(xml_fname) # or xml.dom.minidom.parseString(xml_string)&lt;br /&gt;
pretty_xml_as_string = xml.toprettyxml()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pretty Print with etree [http://stackoverflow.com/questions/749796/pretty-printing-xml-in-python]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import lxml.etree as etree&lt;br /&gt;
&lt;br /&gt;
x = etree.parse(&amp;quot;filename&amp;quot;)&lt;br /&gt;
print etree.tostring(x, pretty_print = True)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* 19.7. xml.dom.minidom — Lightweight DOM implementation — Python v2.7.3 documentation - http://docs.python.org/library/xml.dom.minidom.html&lt;br /&gt;
* Pretty printing XML in python - Stack Overflow - http://stackoverflow.com/questions/749796/pretty-printing-xml-in-python&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
Simply don&#039;t include self.output.startElement and self.output.endElement for elements you don&#039;t want:&lt;br /&gt;
&lt;br /&gt;
simple_filter_parser.py: (my version of [http://freegeographytools.com/2010/removin-time-data-out-of-a-gpx-or-kml-file-to-make-it-work-right-in-google-earth])&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# this parses out the time element of a gpx for Google Earth&lt;br /&gt;
import os&lt;br /&gt;
import sys&lt;br /&gt;
import optparse&lt;br /&gt;
import fnmatch&lt;br /&gt;
from sys import argv&lt;br /&gt;
import xml.sax, xml.sax.saxutils&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
class my_filter_xml(xml.sax.ContentHandler):&lt;br /&gt;
    def __init__(self, outfile, verbose=False):&lt;br /&gt;
        self.output = xml.sax.saxutils.XMLGenerator(outfile, &#039;utf-8&#039;)&lt;br /&gt;
        self.indent = 0&lt;br /&gt;
        self.ignore = False&lt;br /&gt;
        self.output.startDocument()&lt;br /&gt;
&lt;br /&gt;
    def startElement(self, name, attrs):&lt;br /&gt;
        print &amp;quot; &amp;quot; * self.indent + &amp;quot;start: &amp;quot; + name&lt;br /&gt;
        if attrs.keys():&lt;br /&gt;
            keys = &amp;quot; &amp;quot; * (self.indent + 2) + &amp;quot;attrs:&amp;quot;&lt;br /&gt;
            for key in attrs.keys():&lt;br /&gt;
                keys = keys + &amp;quot; &amp;quot; + key + &amp;quot;=&amp;quot; + attrs[key]&lt;br /&gt;
            print keys&lt;br /&gt;
        self.indent = self.indent + 2&lt;br /&gt;
        #self.output.startElement(name, {})&lt;br /&gt;
        if name == &amp;quot;time&amp;quot;:&lt;br /&gt;
            self.ignore = True&lt;br /&gt;
        #if not self.ignore:&lt;br /&gt;
        self.output.startElement(name, attrs)&lt;br /&gt;
&lt;br /&gt;
    def characters(self, ch):&lt;br /&gt;
        if ch.strip():&lt;br /&gt;
            print &amp;quot; &amp;quot; * self.indent + &amp;quot;ch: &amp;quot; + ch.strip()&lt;br /&gt;
            if not self.ignore:&lt;br /&gt;
                self.output.characters(ch)&lt;br /&gt;
        else:&lt;br /&gt;
            if not self.ignore:&lt;br /&gt;
                self.output.characters(&amp;quot;\n&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    def endElement(self, name):&lt;br /&gt;
        self.indent = self.indent - 2&lt;br /&gt;
        print &amp;quot; &amp;quot; * self.indent + &amp;quot;/end: &amp;quot; + name&lt;br /&gt;
        #if not self.ignore:&lt;br /&gt;
        self.output.endElement(name)&lt;br /&gt;
        if name == &amp;quot;time&amp;quot;:&lt;br /&gt;
            self.ignore = False&lt;br /&gt;
&lt;br /&gt;
if __name__ == &#039;__main__&#039;:&lt;br /&gt;
    source = open(&amp;quot;tracks.gpx&amp;quot;)&lt;br /&gt;
    dest = open(&amp;quot;tracks_out.gpx&amp;quot;, &#039;w+&#039;)&lt;br /&gt;
    xml.sax.parse(source, my_filter_xml(dest, True))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
fixdescriptor.py:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import os&lt;br /&gt;
import sys&lt;br /&gt;
import optparse&lt;br /&gt;
import fnmatch&lt;br /&gt;
from sys import argv&lt;br /&gt;
import xml.sax, xml.sax.saxutils&lt;br /&gt;
&lt;br /&gt;
class fix_descriptor(xml.sax.ContentHandler):&lt;br /&gt;
    def __init__(self, outfile, verbose=False):&lt;br /&gt;
        self._outfile = outfile&lt;br /&gt;
        self._verbose = verbose&lt;br /&gt;
        self.output = xml.sax.saxutils.XMLGenerator(outfile, &#039;utf-8&#039;)&lt;br /&gt;
        self._filter = [ &#039;payload&#039;,&lt;br /&gt;
                         &#039;payloads&#039;,&lt;br /&gt;
                         &#039;file-list&#039;,&lt;br /&gt;
                         &#039;file&#039;,&lt;br /&gt;
                         &#039;checksum&#039; ]&lt;br /&gt;
        self._keep = [ &#039;vib&#039;,&lt;br /&gt;
                       &#039;maintenance-mode&#039; ]&lt;br /&gt;
        self._inside = None&lt;br /&gt;
&lt;br /&gt;
    def startElement(self, name, attrs):&lt;br /&gt;
        # Certain elements are kept unchanged&lt;br /&gt;
        if name in self._keep:&lt;br /&gt;
            if self._verbose:&lt;br /&gt;
                print &#039;%s element start found&#039; % (name)&lt;br /&gt;
            self.output.startElement(name, {})&lt;br /&gt;
            if name == &#039;maintenance-mode&#039;:&lt;br /&gt;
                if self._verbose:&lt;br /&gt;
                    print &#039;inside maintenance-mode&#039;&lt;br /&gt;
                self._inside = name&lt;br /&gt;
            return&lt;br /&gt;
        # Other elements are filtered (removed)&lt;br /&gt;
        elif name in self._filter:&lt;br /&gt;
            if self._verbose:&lt;br /&gt;
                print &#039;%s element start found&#039; % (name)&lt;br /&gt;
            self._inside = name&lt;br /&gt;
            return&lt;br /&gt;
        self.output.startElement(name, attrs)&lt;br /&gt;
&lt;br /&gt;
    def characters(self, ch):&lt;br /&gt;
        if self._inside == &#039;maintenance-mode&#039;:&lt;br /&gt;
            if self._verbose:&lt;br /&gt;
                print &#039;new content for maintenance-mode&#039;&lt;br /&gt;
            self.output.characters(&#039;false&#039;)&lt;br /&gt;
        elif self._inside not in self._filter:&lt;br /&gt;
            self.output.characters(ch)&lt;br /&gt;
&lt;br /&gt;
    def endElement(self, name):&lt;br /&gt;
        # If it&#039;s not a checksum element, only print it&lt;br /&gt;
        if name in self._filter + self._keep:&lt;br /&gt;
            self._inside = None&lt;br /&gt;
            if self._verbose:&lt;br /&gt;
                print &#039;%s element end found&#039; % (name)&lt;br /&gt;
            if name in self._filter:&lt;br /&gt;
                return&lt;br /&gt;
        self.output.endElement(name)&lt;br /&gt;
&lt;br /&gt;
if __name__ == &#039;__main__&#039;:&lt;br /&gt;
    #&lt;br /&gt;
    parser = optparse.OptionParser(usage=&#039;%prog ...&#039;)&lt;br /&gt;
    parser.add_option(&#039;-v&#039;, &#039;--verbose&#039;,&lt;br /&gt;
                       action=&#039;store_true&#039;, default=False,&lt;br /&gt;
                       help=&#039;Print more information.&#039;)&lt;br /&gt;
    parser.add_option(&#039;--input-xml&#039;,&lt;br /&gt;
                       type=&#039;str&#039;, default=&#039;descriptor.xml&#039;,&lt;br /&gt;
                       help=&#039;Name of input XML [default: %default]&#039;)&lt;br /&gt;
    parser.add_option(&#039;--output-xml&#039;,&lt;br /&gt;
                       type=&#039;str&#039;, default=&#039;fixed_descriptor.xml&#039;,&lt;br /&gt;
                       help=&#039;Name of output XML [default: %default]&#039;)&lt;br /&gt;
    opts, args = parser.parse_args(argv[1:])&lt;br /&gt;
    source = open(opts.input_xml)&lt;br /&gt;
    dest = open(opts.output_xml, &#039;w+&#039;)&lt;br /&gt;
    xml.sax.parse(source, fix_descriptor(dest, opts.verbose))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--&lt;br /&gt;
&lt;br /&gt;
Simple read and output parsing:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import os&lt;br /&gt;
import sys&lt;br /&gt;
import optparse&lt;br /&gt;
import fnmatch&lt;br /&gt;
from sys import argv&lt;br /&gt;
import xml.sax, xml.sax.saxutils&lt;br /&gt;
&lt;br /&gt;
class fix_descriptor(xml.sax.ContentHandler):&lt;br /&gt;
    def __init__(self, outfile, verbose=False):&lt;br /&gt;
        self._outfile = outfile&lt;br /&gt;
        self._verbose = verbose&lt;br /&gt;
        self.output = xml.sax.saxutils.XMLGenerator(outfile, &#039;utf-8&#039;)&lt;br /&gt;
        self._inside = None&lt;br /&gt;
&lt;br /&gt;
    def startElement(self, name, attrs):&lt;br /&gt;
        # attrs.items() is a list of tuples (name, value)&lt;br /&gt;
        print &amp;quot;start:&amp;quot;, name, &amp;quot;/&amp;quot;, attrs.items()&lt;br /&gt;
        self.output.startElement(name, attrs)&lt;br /&gt;
&lt;br /&gt;
    def characters(self, ch):&lt;br /&gt;
        print &amp;quot;char:&amp;quot;, self._inside, &amp;quot;/&amp;quot;, ch&lt;br /&gt;
        self.output.characters(ch)&lt;br /&gt;
&lt;br /&gt;
    def endElement(self, name):&lt;br /&gt;
        print &amp;quot;end:&amp;quot;, name&lt;br /&gt;
        self.output.endElement(name)&lt;br /&gt;
&lt;br /&gt;
if __name__ == &#039;__main__&#039;:&lt;br /&gt;
    parser = optparse.OptionParser(usage=&#039;%prog ...&#039;)&lt;br /&gt;
    parser.add_option(&#039;-v&#039;, &#039;--verbose&#039;,&lt;br /&gt;
                       action=&#039;store_true&#039;, default=False,&lt;br /&gt;
                       help=&#039;Print more information.&#039;)&lt;br /&gt;
    parser.add_option(&#039;--input-xml&#039;,&lt;br /&gt;
                       type=&#039;str&#039;, default=&#039;descriptor.xml&#039;,&lt;br /&gt;
                       help=&#039;Name of input XML [default: %default]&#039;)&lt;br /&gt;
    parser.add_option(&#039;--output-xml&#039;,&lt;br /&gt;
                       type=&#039;str&#039;, default=&#039;fixed_descriptor.xml&#039;,&lt;br /&gt;
                       help=&#039;Name of output XML [default: %default]&#039;)&lt;br /&gt;
    opts, args = parser.parse_args(argv[1:])&lt;br /&gt;
    source = open(opts.input_xml)&lt;br /&gt;
    dest = open(opts.output_xml, &#039;w+&#039;)&lt;br /&gt;
    xml.sax.parse(source, fix_descriptor(dest, opts.verbose))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Unicode ===&lt;br /&gt;
&lt;br /&gt;
Unicode string:&lt;br /&gt;
 u&#039;Hello World !&#039;&lt;br /&gt;
&lt;br /&gt;
Raw Unicode string:&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; ur&#039;Hello\u0020World !&#039;&lt;br /&gt;
 u&#039;Hello World !&#039;&lt;br /&gt;
&lt;br /&gt;
Convert:&lt;br /&gt;
 u = u&#039;hello\xe4&#039;&lt;br /&gt;
 str(u)  # UnicodeEncodeError: &#039;ascii&#039; codec can&#039;t encode character u&#039;\xe4&#039; in position 5: ordinal not in range(128)&lt;br /&gt;
 s = u.encode(&#039;utf8&#039;)  # &#039;s&#039; is now type str&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* Introduction to Unicode Strings - http://docs.python.org/tutorial/introduction.html#unicode-strings&lt;br /&gt;
&lt;br /&gt;
=== Zip ===&lt;br /&gt;
&lt;br /&gt;
See [[Python/Zip]]&lt;br /&gt;
&lt;br /&gt;
=== signals ===&lt;br /&gt;
&lt;br /&gt;
 signal.SIGTERM  : kill  [pid]&lt;br /&gt;
 signal.SIGALRM  : kill -ALRM  [pid]&lt;br /&gt;
 signal.SIGHUP   : kill -HUP  [pid]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import signal, os&lt;br /&gt;
&lt;br /&gt;
def handler(signum, frame):&lt;br /&gt;
    print &#039;Signal handler called with signal&#039;, signum&lt;br /&gt;
    raise IOError(&amp;quot;Couldn&#039;t open device!&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
# Set the signal handler and a 5-second alarm&lt;br /&gt;
signal.signal(signal.SIGALRM, handler)&lt;br /&gt;
signal.alarm(5)&lt;br /&gt;
&lt;br /&gt;
# This open() may hang indefinitely&lt;br /&gt;
fd = os.open(&#039;/dev/ttyS0&#039;, os.O_RDWR)&lt;br /&gt;
&lt;br /&gt;
signal.alarm(0)          # Disable the alarm&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: use signal.SIGTERM to handle &amp;quot;kill&amp;quot; command&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* 17.4. signal — Set handlers for asynchronous events — Python v2.7.5 documentation - http://docs.python.org/2/library/signal.html&lt;br /&gt;
&lt;br /&gt;
==== Ctrl+C ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
import signal&lt;br /&gt;
import sys&lt;br /&gt;
def signal_handler(signal, frame):&lt;br /&gt;
        print &#039;You pressed Ctrl+C!&#039;&lt;br /&gt;
        sys.exit(0)&lt;br /&gt;
signal.signal(signal.SIGINT, signal_handler)&lt;br /&gt;
print &#039;Press Ctrl+C&#039;&lt;br /&gt;
&lt;br /&gt;
# linux only:&lt;br /&gt;
signal.pause()&lt;br /&gt;
&lt;br /&gt;
# windows alternative:&lt;br /&gt;
#import time&lt;br /&gt;
#time.sleep(60)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* control - How do I capture SIGINT in Python? - Stack Overflow - http://stackoverflow.com/questions/1112343/how-do-i-capture-sigint-in-python&lt;br /&gt;
&lt;br /&gt;
==== Non-blocking raw_input for Python ====&lt;br /&gt;
&lt;br /&gt;
Non-blocking raw_input for Python:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# source: http://www.garyrobinson.net/2009/10/non-blocking-raw_input-for-python.html&lt;br /&gt;
&lt;br /&gt;
import signal&lt;br /&gt;
&lt;br /&gt;
class AlarmException(Exception):&lt;br /&gt;
    pass&lt;br /&gt;
&lt;br /&gt;
def alarmHandler(signum, frame):&lt;br /&gt;
    raise AlarmException&lt;br /&gt;
&lt;br /&gt;
def nonBlockingRawInput(prompt=&#039;&#039;, timeout=20):&lt;br /&gt;
    signal.signal(signal.SIGALRM, alarmHandler)&lt;br /&gt;
    signal.alarm(timeout)&lt;br /&gt;
    try:&lt;br /&gt;
        text = raw_input(prompt)&lt;br /&gt;
        signal.alarm(0)&lt;br /&gt;
        return text&lt;br /&gt;
    except AlarmException:&lt;br /&gt;
        print &#039;\nPrompt timeout. Continuing...&#039;&lt;br /&gt;
    signal.signal(signal.SIGALRM, signal.SIG_IGN)&lt;br /&gt;
    return &#039;&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== email ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import smtplib&lt;br /&gt;
import email.mime.text&lt;br /&gt;
&lt;br /&gt;
msg_text = &amp;quot;Hello World&amp;quot;&lt;br /&gt;
msg = email.mime.text.MIMEText(msg_text)&lt;br /&gt;
&lt;br /&gt;
# me == the sender&#039;s email address&lt;br /&gt;
# you == the recipient&#039;s email address&lt;br /&gt;
msg[&#039;Subject&#039;] = &#039;The contents of %s&#039; % textfile&lt;br /&gt;
msg[&#039;From&#039;] = me&lt;br /&gt;
msg[&#039;To&#039;] = you&lt;br /&gt;
&lt;br /&gt;
# Send the message via our own SMTP server, but don&#039;t include the&lt;br /&gt;
# envelope header.&lt;br /&gt;
s = smtplib.SMTP(&#039;localhost&#039;)&lt;br /&gt;
s.sendmail(me, [you], msg.as_string())&lt;br /&gt;
s.quit()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
my nagios fake /bin/mail:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
&lt;br /&gt;
import smtplib&lt;br /&gt;
import email.mime.text&lt;br /&gt;
import optparse&lt;br /&gt;
import os&lt;br /&gt;
import sys&lt;br /&gt;
import pwd&lt;br /&gt;
&lt;br /&gt;
os.system(&#039;logger mail called&#039;)&lt;br /&gt;
&lt;br /&gt;
parser = optparse.OptionParser()&lt;br /&gt;
parser.add_option(&lt;br /&gt;
    &#039;-s&#039;, &#039;--subject&#039;,&lt;br /&gt;
    help=&#039;Subject&#039;,&lt;br /&gt;
    default=&amp;quot;&amp;quot;)&lt;br /&gt;
parser.add_option(&lt;br /&gt;
    &#039;-t&#039;, &#039;--to&#039;,&lt;br /&gt;
    help=&#039;To&#039;,&lt;br /&gt;
    dest=&amp;quot;send_to&amp;quot;,&lt;br /&gt;
    default=None)&lt;br /&gt;
parser.add_option(&lt;br /&gt;
    &#039;-f&#039;, &#039;--from&#039;,&lt;br /&gt;
    help=&#039;From&#039;,&lt;br /&gt;
    dest=&amp;quot;send_from&amp;quot;,&lt;br /&gt;
    default=None)&lt;br /&gt;
parser.add_option(&lt;br /&gt;
    &#039;-S&#039;, &#039;--server&#039;,&lt;br /&gt;
    help=&#039;server&#039;,&lt;br /&gt;
    default=&amp;quot;prime&amp;quot;)&lt;br /&gt;
(options, args) = parser.parse_args()&lt;br /&gt;
&lt;br /&gt;
def get_username():&lt;br /&gt;
    return pwd.getpwuid( os.getuid() )[ 0 ]&lt;br /&gt;
&lt;br /&gt;
if options.send_to:&lt;br /&gt;
    send_to = options.send_to&lt;br /&gt;
else:&lt;br /&gt;
    if len(args) == 1:&lt;br /&gt;
        send_to = args[0]&lt;br /&gt;
    else:&lt;br /&gt;
        parser.print_help()&lt;br /&gt;
        sys.exit(1)&lt;br /&gt;
&lt;br /&gt;
if options.send_from:&lt;br /&gt;
    send_from = options.send_from&lt;br /&gt;
else:&lt;br /&gt;
    username = get_username()&lt;br /&gt;
    hostname = os.uname()[1]&lt;br /&gt;
    send_from = username + &amp;quot;@&amp;quot; + hostname&lt;br /&gt;
&lt;br /&gt;
msg_text = sys.stdin.read()&lt;br /&gt;
msg = email.mime.text.MIMEText(msg_text)&lt;br /&gt;
&lt;br /&gt;
msg[&#039;Subject&#039;] = options.subject&lt;br /&gt;
msg[&#039;From&#039;] = send_from&lt;br /&gt;
msg[&#039;To&#039;] = send_to&lt;br /&gt;
&lt;br /&gt;
s = smtplib.SMTP(options.server)&lt;br /&gt;
s.sendmail(send_from, [send_to], msg.as_string())&lt;br /&gt;
s.quit()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Authenticated (with gmail):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import smtplib&lt;br /&gt;
import email.mime.text&lt;br /&gt;
&lt;br /&gt;
# from_email = &amp;quot;kenneth@demo.oeey.com&amp;quot;&lt;br /&gt;
# to_email = &amp;quot;kenneth@demo.oeey.com&amp;quot;&lt;br /&gt;
from_email = &amp;quot;Kenneth Burgener &amp;lt;kenneth@demo.oeey.com&amp;gt;&amp;quot;&lt;br /&gt;
to_emails = [&amp;quot;Kenneth Burgener &amp;lt;kenneth@demo.oeey.com&amp;gt;&amp;quot;, &amp;quot;Kenneth Cell &amp;lt;xxx@xxx.com&amp;gt;&amp;quot;]&lt;br /&gt;
&lt;br /&gt;
msg_text = &amp;quot;hello world&amp;quot;&lt;br /&gt;
msg = email.mime.text.MIMEText(msg_text)&lt;br /&gt;
msg[&#039;Subject&#039;] = &#039;Test text&#039;&lt;br /&gt;
msg[&#039;From&#039;] = from_email&lt;br /&gt;
# msg[&#039;To&#039;] = to_email&lt;br /&gt;
msg[&#039;To&#039;] = &amp;quot;, &amp;quot;.join(to_emails)&lt;br /&gt;
# s = smtplib.SMTP(&#039;localhost&#039;)&lt;br /&gt;
print &amp;quot;sending...&amp;quot;&lt;br /&gt;
s = smtplib.SMTP_SSL(&#039;smtp.gmail.com&#039;, &#039;465&#039;)&lt;br /&gt;
s.login(&#039;xxx&#039;, &#039;xxx&#039;)&lt;br /&gt;
# s.sendmail(from_email, [to_email], msg.as_string())&lt;br /&gt;
s.sendmail(from_email, to_emails, msg.as_string())&lt;br /&gt;
s.quit()&lt;br /&gt;
print &amp;quot;sent!&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Source: &lt;br /&gt;
* 20.12. smtplib — SMTP protocol client — Python v2.7.5 documentation - http://docs.python.org/2/library/smtplib.html&lt;br /&gt;
* 18.1.11. email: Examples — Python v2.7.5 documentation - http://docs.python.org/2/library/email-examples.html&lt;br /&gt;
&lt;br /&gt;
=== pprint ===&lt;br /&gt;
&lt;br /&gt;
8.18. pprint — Data pretty printer — Python v2.7.5 documentation - http://docs.python.org/2/library/pprint.html&lt;br /&gt;
&lt;br /&gt;
 import pprint&lt;br /&gt;
 pprint.pprint(myVar)&lt;br /&gt;
&lt;br /&gt;
 import pprint&lt;br /&gt;
 pp = pprint.PrettyPrinter(indent=4)&lt;br /&gt;
 pp.pprint(myVar)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Note: Useless on objects!&lt;br /&gt;
&lt;br /&gt;
Dump object:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def dumpobject(obj):&lt;br /&gt;
    print &amp;quot;&amp;lt;&amp;lt;&amp;lt;---&amp;quot;&lt;br /&gt;
    print type(obj), obj.__class__.__name__&lt;br /&gt;
    for attr in dir(obj):&lt;br /&gt;
        if attr[0] == &amp;quot;_&amp;quot;: continue  # ignore under/dunder properties&lt;br /&gt;
        if str(type(getattr(obj, attr))) == &amp;quot;&amp;lt;type &#039;instancemethod&#039;&amp;gt;&amp;quot;:&lt;br /&gt;
            print attr, &amp;quot;: METHOD&amp;quot;&lt;br /&gt;
        else:&lt;br /&gt;
            print attr, &amp;quot;:&amp;quot;, type(getattr(obj, attr)), &amp;quot;:&amp;quot;, getattr(obj, attr)&lt;br /&gt;
    print &amp;quot;END ---&amp;gt;&amp;gt;&amp;gt;&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Curses ===&lt;br /&gt;
&lt;br /&gt;
Curses Programming with Python — Python v3.3.2 documentation - http://docs.python.org/3/howto/curses.html&lt;br /&gt;
&lt;br /&gt;
&amp;quot;The curses library supplies a terminal-independent screen-painting and keyboard-handling facility for text-based terminals; such terminals include VT100s, the Linux console, and the simulated terminal provided by various programs. Display terminals support various control codes to perform common operations such as moving the cursor, scrolling the screen, and erasing areas. Different terminals use widely differing codes, and often have their own minor quirks.&lt;br /&gt;
&lt;br /&gt;
In a world of graphical displays, one might ask “why bother”? It’s true that character-cell display terminals are an obsolete technology, but there are niches in which being able to do fancy things with them are still valuable. One niche is on small-footprint or embedded Unixes that don’t run an X server. Another is tools such as OS installers and kernel configurators that may have to run before any graphical support is available.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
Thread from Utah Python User&#039;s Group mailing list:&lt;br /&gt;
&lt;br /&gt;
-&lt;br /&gt;
&lt;br /&gt;
Hello, I am trying to learn more about curses in python for a desktop application. Does anybody have any recommendations on tutorials or documentation? &lt;br /&gt;
&lt;br /&gt;
-Corban&lt;br /&gt;
&lt;br /&gt;
-&lt;br /&gt;
&lt;br /&gt;
We&#039;ve use urwid at work. Seems to be a good approach if you aren&#039;t already tied to something. Learning curve can be a bit steep (well, compared to what you&#039;d think it should be). Good luck!&lt;br /&gt;
&lt;br /&gt;
 http://excess.org/urwid/&lt;br /&gt;
&lt;br /&gt;
Gabriel Gunderson&lt;br /&gt;
&lt;br /&gt;
-&lt;br /&gt;
&lt;br /&gt;
This video series looks pretty good:&lt;br /&gt;
&lt;br /&gt;
http://www.youtube.com/user/pythoncursestutorial?feature=watch&lt;br /&gt;
&lt;br /&gt;
Official HOWTOs from the python.org site:&lt;br /&gt;
&lt;br /&gt;
http://docs.python.org/2/howto/curses.html&lt;br /&gt;
http://docs.python.org/3/howto/curses.html&lt;br /&gt;
&lt;br /&gt;
As Gabe mentioned, there are other libraries that provide similar or&lt;br /&gt;
greater functionality, so if you aren&#039;t doing this specifically to&lt;br /&gt;
learn curses, it&#039;s worth at least looking at a few of them to compare.&lt;br /&gt;
&lt;br /&gt;
There&#039;s a brief comparison of three possibilities here:&lt;br /&gt;
&lt;br /&gt;
http://stackoverflow.com/questions/8349085/python-ncurses-cdk-urwid-difference&lt;br /&gt;
&lt;br /&gt;
Daniel Fackrell&lt;br /&gt;
&lt;br /&gt;
-&lt;br /&gt;
&lt;br /&gt;
Here&#039;s another option that looks promising:&lt;br /&gt;
&lt;br /&gt;
https://pypi.python.org/pypi/blessings/&lt;br /&gt;
&lt;br /&gt;
Daniel Fackrell&lt;br /&gt;
&lt;br /&gt;
=== dialog ===&lt;br /&gt;
&lt;br /&gt;
pythondialog - http://pythondialog.sourceforge.net/&lt;br /&gt;
: &amp;quot;pythondialog is a Python wrapper for the dialog utility originally written by Savio Lam, and later rewritten by Thomas E. Dickey. Its purpose is to provide an easy to use, pythonic and comprehensive Python interface to dialog. This allows one to make simple text-mode user interfaces on Unix-like systems (including Linux). &amp;quot;&lt;br /&gt;
&lt;br /&gt;
Note: The latest versions (2.12 and later) only support Python 3; users who really want to stick to Python 2 should use version 2.11 for now.&lt;br /&gt;
&lt;br /&gt;
Install:&lt;br /&gt;
 # latest:&lt;br /&gt;
 # wget http://sourceforge.net/projects/pythondialog/files/latest/download?source=dlp&lt;br /&gt;
&lt;br /&gt;
 wget http://sourceforge.net/projects/pythondialog/files/pythondialog/2.11/python2-pythondialog-2.11.tar.gz/download&lt;br /&gt;
 tar -zvxf python2-pythondialog-2.11.tar.gz&lt;br /&gt;
 cd pythondialog-2.11&lt;br /&gt;
&lt;br /&gt;
 import dialog&lt;br /&gt;
 d = dialog.Dialog()&lt;br /&gt;
 if d.yesno(&amp;quot;Continue?&amp;quot;) == d.DIALOG_OK:&lt;br /&gt;
  print &amp;quot;Continuing...&amp;quot;&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
My solution&lt;br /&gt;
&lt;br /&gt;
kiloforce / dialog / source / — Bitbucket - https://bitbucket.org/kiloforce/dialog&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot; Wrapper for Linux &#039;dialog&#039; command &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
__author__ = &amp;quot;Kenneth Burgener &amp;lt;kenneth@k.ttak.org&amp;gt;&amp;quot;&lt;br /&gt;
__copyright__ = &amp;quot;(c) 2013&amp;quot;&lt;br /&gt;
__date__ = &amp;quot;$Sep 27, 2013$&amp;quot;&lt;br /&gt;
__version__ = &amp;quot;1.0&amp;quot;&lt;br /&gt;
__credits__ = r&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
XXXXXXXXXXXXXXXXXX&lt;br /&gt;
X Dialog Wrapper #&lt;br /&gt;
##################&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
import subprocess&lt;br /&gt;
import time&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
class Dialog():&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot; Python wrapper for Linux &#039;dialog&#039; command&lt;br /&gt;
&lt;br /&gt;
    dialog - display dialog boxes from shell scripts&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import dialog&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dlg = dialog.Dialog()&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; rc = dlg.msgbox(&#039;hello world&#039;)&lt;br /&gt;
&lt;br /&gt;
    Return codes:&lt;br /&gt;
        YES = 0&lt;br /&gt;
        OK = 0&lt;br /&gt;
        EXIT = 0&lt;br /&gt;
        NO = 1&lt;br /&gt;
        CANCEL = 1&lt;br /&gt;
        ESC = 255&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    YES = 0&lt;br /&gt;
    OK = 0&lt;br /&gt;
    EXIT = 0&lt;br /&gt;
    NO = 1&lt;br /&gt;
    CANCEL = 1&lt;br /&gt;
    ESC = 255&lt;br /&gt;
&lt;br /&gt;
    def __init__(self):&lt;br /&gt;
        rc = self._exe(&#039;which dialog &amp;gt; /dev/null&#039;)[0]&lt;br /&gt;
        if rc != 0:&lt;br /&gt;
            print &amp;quot;Error: failed to find Linux dialog command&amp;quot;&lt;br /&gt;
            sys.exit(1)&lt;br /&gt;
&lt;br /&gt;
    def _exe(self, cmd, strip=True):&lt;br /&gt;
        p = subprocess.Popen(cmd, shell=True, stderr=subprocess.PIPE)&lt;br /&gt;
        output = &amp;quot;\n&amp;quot;.join(p.stderr.readlines())&lt;br /&gt;
        if strip:&lt;br /&gt;
            output = output.strip()&lt;br /&gt;
        rc = p.wait()&lt;br /&gt;
        return (rc, output)&lt;br /&gt;
&lt;br /&gt;
    def rc_to_str(self, rc):&lt;br /&gt;
        if rc == 0:&lt;br /&gt;
            return &amp;quot;YES&amp;quot;&lt;br /&gt;
        elif rc == 1:&lt;br /&gt;
            return &amp;quot;NO&amp;quot;&lt;br /&gt;
        elif rc == 255:&lt;br /&gt;
            return &amp;quot;ESX&amp;quot;&lt;br /&gt;
        else:&lt;br /&gt;
            raise Exception(&amp;quot;Unknown return code: %s&amp;quot; % rc)&lt;br /&gt;
&lt;br /&gt;
    def clear(self):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Clear screen&lt;br /&gt;
&lt;br /&gt;
        Example:&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt; dialog.clear()&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        rc, output = self._exe(&#039;clear&#039;)&lt;br /&gt;
        assert rc in (0,), &amp;quot;clear rc&amp;quot;&lt;br /&gt;
        return rc&lt;br /&gt;
&lt;br /&gt;
    def msgbox(self, msg):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Simple message box&lt;br /&gt;
&lt;br /&gt;
        @param msg (str) = display message&lt;br /&gt;
        @return: rc (int)&lt;br /&gt;
&lt;br /&gt;
        Example:&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt; rc = dialog.msgbox(&#039;hello world&#039;)&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        rc, output = self._exe(&#039;dialog --msgbox &amp;quot;{msg}&amp;quot; 0 0&#039;.format(msg=msg))&lt;br /&gt;
        assert rc in (self.YES, self.ESC), &amp;quot;msgbox rc&amp;quot;&lt;br /&gt;
        return rc&lt;br /&gt;
&lt;br /&gt;
    def yesno(self, msg):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Yes/No dialog&lt;br /&gt;
&lt;br /&gt;
        @param msg (str) = display message&lt;br /&gt;
        @return: rc (int)&lt;br /&gt;
&lt;br /&gt;
        Example:&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt; rc = dialog.yesno(&#039;continue&#039;)&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        rc, output = self._exe(&#039;dialog --yesno &amp;quot;{msg}&amp;quot; 0 0&#039;.format(msg=msg))&lt;br /&gt;
        assert rc in (self.YES, self.NO, self.ESC), &amp;quot;yesno rc&amp;quot;&lt;br /&gt;
        return rc&lt;br /&gt;
&lt;br /&gt;
    def infobox(self, msg):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Dialog that does not wait for user&#039;s response&lt;br /&gt;
        (do your own pause)&lt;br /&gt;
&lt;br /&gt;
        @param msg (str) = display message&lt;br /&gt;
        @return: rc (int) always zero&lt;br /&gt;
&lt;br /&gt;
        Example:&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt; for i in range(10):&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt;   dialog.infobox(&#039;counting: &#039; + str(i))&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt;   time.sleep(3)&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        rc, output = self._exe(&#039;dialog --infobox &amp;quot;{msg}&amp;quot; 0 0&#039;.format(msg=msg))&lt;br /&gt;
        assert rc in (self.YES,), &amp;quot;infobox rc&amp;quot;&lt;br /&gt;
        return rc&lt;br /&gt;
&lt;br /&gt;
    def inputbox(self, msg):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Get user input&lt;br /&gt;
&lt;br /&gt;
        @param msg (str) = display message&lt;br /&gt;
        @return: rc (int), output (str/None)&lt;br /&gt;
&lt;br /&gt;
        Example:&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt; rc, output = dialog.inputbox(&#039;name:&#039;)&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        rc, output = self._exe(&#039;dialog --inputbox &amp;quot;{msg}&amp;quot; 0 0&#039;.format(msg=msg))&lt;br /&gt;
        assert rc in (self.YES, self.NO, self.ESC), &amp;quot;inputbox rc&amp;quot;&lt;br /&gt;
        if not output:&lt;br /&gt;
            output = None&lt;br /&gt;
        return rc, output&lt;br /&gt;
&lt;br /&gt;
    def textbox(self, filename):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Display a file&lt;br /&gt;
&lt;br /&gt;
        @param filename (str) = file to display&lt;br /&gt;
        @return: rc (int)&lt;br /&gt;
&lt;br /&gt;
        Example:&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt; dialog.textbox(&#039;/etc/passwd&#039;)&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        rc, output = self._exe(&#039;dialog --textbox {filename} 0 0&#039;.format(filename=filename))&lt;br /&gt;
        assert rc in (self.YES, self.ESC), &amp;quot;textbox rc&amp;quot;&lt;br /&gt;
        return rc&lt;br /&gt;
&lt;br /&gt;
    def menu(self, msg, item_list):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Single selection checkbox menu&lt;br /&gt;
&lt;br /&gt;
        @param msg (str) = display message&lt;br /&gt;
        @param item_list (str list) = list of items to display&lt;br /&gt;
        @return: rc (int), selection (int/None)&lt;br /&gt;
&lt;br /&gt;
        Example:&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt; rc, selection = dialog.menu(&#039;Select multiple options:&#039;,&lt;br /&gt;
        ...     (&#039;option 1&#039;, &#039;option 2&#039;))&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        item_str = &amp;quot;&amp;quot;&lt;br /&gt;
        for i in range(len(item_list)):&lt;br /&gt;
            item_str += &amp;quot; &amp;quot; + str(i+1) + &amp;quot; \&amp;quot;&amp;quot; + item_list[i] + &amp;quot;\&amp;quot;&amp;quot;&lt;br /&gt;
        rc, output = self._exe(&#039;dialog --menu &amp;quot;{msg}&amp;quot; 0 0 0 {item_str}&#039;.format(msg=msg, item_str=item_str))&lt;br /&gt;
        if output:&lt;br /&gt;
            selection = int(output)&lt;br /&gt;
        else:&lt;br /&gt;
            selection = None&lt;br /&gt;
        assert rc in (self.YES, self.NO, self.ESC), &amp;quot;menu rc&amp;quot;&lt;br /&gt;
        return rc, selection&lt;br /&gt;
&lt;br /&gt;
    def checklist(self, msg, item_list, checked_list=None):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Multiple selection checkbox menu&lt;br /&gt;
&lt;br /&gt;
        @param msg (str) = display message&lt;br /&gt;
        @param item_list (str list) = list of items&lt;br /&gt;
        @param checked_list (int list) = default items to check&lt;br /&gt;
        @return: rc (int), selections (int list/None)&lt;br /&gt;
&lt;br /&gt;
        Example:&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt; rc, selections = dialog.checklist(&#039;Select multiple options:&#039;,&lt;br /&gt;
        ...     (&#039;option 1&#039;, &#039;option 2&#039;)&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        item_str = &amp;quot;&amp;quot;&lt;br /&gt;
        assert type(item_list) in (type(None), type(()), type([])), &amp;quot;checklist: item_list must be a list&amp;quot;&lt;br /&gt;
        assert type(checked_list) in (type(None), type(()), type([])), &amp;quot;checklist: checked_list must be a list&amp;quot;&lt;br /&gt;
        for i in range(len(item_list)):&lt;br /&gt;
            item_str += &amp;quot; &amp;quot; + str(i+1) + &amp;quot; \&amp;quot;&amp;quot; + item_list[i] + &amp;quot;\&amp;quot;&amp;quot;&lt;br /&gt;
            if checked_list and i+1 in checked_list:&lt;br /&gt;
                item_str += &amp;quot; on&amp;quot;&lt;br /&gt;
            else:&lt;br /&gt;
                item_str += &amp;quot; off&amp;quot;&lt;br /&gt;
        rc, output = self._exe(&#039;dialog --checklist &amp;quot;{msg}&amp;quot; 0 0 0 {item_str}&#039;.format(msg=msg, item_str=item_str))&lt;br /&gt;
        print item_str&lt;br /&gt;
        selections = []&lt;br /&gt;
        for choice in output.split(&#039;&amp;quot;&#039;):&lt;br /&gt;
            if choice.strip():&lt;br /&gt;
                selections.append(int(choice))&lt;br /&gt;
        if selections:&lt;br /&gt;
            selections = tuple(selections)&lt;br /&gt;
        else:&lt;br /&gt;
            selections = None&lt;br /&gt;
        assert rc in (self.YES, self.NO, self.ESC), &amp;quot;checklist rc&amp;quot;&lt;br /&gt;
        return rc, selections&lt;br /&gt;
&lt;br /&gt;
    def radiolist(self, msg, item_list, checked_item=None):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Single selection radio menu, with default&lt;br /&gt;
&lt;br /&gt;
        @param msg (str) = display message&lt;br /&gt;
        @param item_list (str list) = list of items&lt;br /&gt;
        @param checked_item (int) = default item to select&lt;br /&gt;
        @return: rc (int), selection (int)&lt;br /&gt;
&lt;br /&gt;
        Example:&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt; rc, selection = dialog.radiolist(&#039;Select one option:&#039;,&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt;     (&#039;option 1&#039;, &#039;option 2&#039;), 2)&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        item_str = &amp;quot;&amp;quot;&lt;br /&gt;
        for i in range(len(item_list)):&lt;br /&gt;
            item_str += &amp;quot; &amp;quot; + str(i+1) + &amp;quot; \&amp;quot;&amp;quot; + item_list[i] + &amp;quot;\&amp;quot;&amp;quot;&lt;br /&gt;
            if checked_item and i+1 == int(checked_item):&lt;br /&gt;
                item_str += &amp;quot; on&amp;quot;&lt;br /&gt;
            else:&lt;br /&gt;
                item_str += &amp;quot; off&amp;quot;&lt;br /&gt;
        rc, selection = self._exe(&#039;dialog --radiolist &amp;quot;{msg}&amp;quot; 0 0 0 {item_str}&#039;.format(msg=msg, item_str=item_str))&lt;br /&gt;
        if not selection:&lt;br /&gt;
            selection = None&lt;br /&gt;
        assert rc in (self.YES, self.NO, self.ESC), &amp;quot;radiolist rc&amp;quot;&lt;br /&gt;
        return rc, selection&lt;br /&gt;
&lt;br /&gt;
    def gauge(self, msg, percent):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Progress bar (does not wait for user&#039;s input)&lt;br /&gt;
&lt;br /&gt;
        @param msg (str) = display message&lt;br /&gt;
        @param percent (int) = progress&lt;br /&gt;
        @return: rc (int) always zero&lt;br /&gt;
&lt;br /&gt;
        Example:&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt; for i in range(0, 100+1, 2):&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt;   dialog.gauge(&#039;Progress:&#039;, i)&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt;   time.sleep(.1)&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        rc, output = self._exe(&#039;echo {percent} | dialog --gauge &amp;quot;{msg}&amp;quot; 0 0&#039;.format(percent=percent, msg=msg))&lt;br /&gt;
        assert rc in (self.YES,), &amp;quot;guage rc&amp;quot;&lt;br /&gt;
        return rc&lt;br /&gt;
&lt;br /&gt;
    def progress(self, msg, percent):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Alias for self.guage()&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        return self.gauge(msg=msg, percent=percent)&lt;br /&gt;
&lt;br /&gt;
    def form(self, msg, item_list):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Multiple item entry form&lt;br /&gt;
&lt;br /&gt;
        @param msg (str) = display message&lt;br /&gt;
        @param item_list (str list) = list of items&lt;br /&gt;
        @return: rc (int), answers (str list)&lt;br /&gt;
&lt;br /&gt;
        Example:&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt; rc, answers = dialog.form(&#039;Enter details&#039;,&lt;br /&gt;
        ...     (&#039;first name&#039;, &#039;last name&#039;))&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        item_str = &amp;quot;&amp;quot;&lt;br /&gt;
        name_len = 1&lt;br /&gt;
        for i in range(len(item_list)):&lt;br /&gt;
            if len(item_list[i])+3 &amp;gt; name_len:&lt;br /&gt;
                name_len = len(item_list[i])+3&lt;br /&gt;
        for i in range(len(item_list)):&lt;br /&gt;
            item_str += &amp;quot; \&amp;quot;&amp;quot; + item_list[i] + &amp;quot;:\&amp;quot; &amp;quot; + str(i+1) + &amp;quot; 1 \&amp;quot;\&amp;quot; &amp;quot; + str(i+1) +\&lt;br /&gt;
                &amp;quot; &amp;quot; + str(name_len) + &amp;quot; 40 0&amp;quot;&lt;br /&gt;
        rc, answers = self._exe(&#039;dialog --form &amp;quot;{msg}&amp;quot; 0 0 0 {item_str}&#039;.format(msg=msg, item_str=item_str),&lt;br /&gt;
                                strip=False)&lt;br /&gt;
        answers = answers.split(&#039;\n\n&#039;)&lt;br /&gt;
        if not answers:&lt;br /&gt;
            answers = None&lt;br /&gt;
        assert rc in (self.YES, self.NO, self.ESC), &amp;quot;form rc&amp;quot;&lt;br /&gt;
        return rc, answers&lt;br /&gt;
&lt;br /&gt;
    def test(self):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Test features&lt;br /&gt;
&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt; import dialog&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt; dlg = dialog.Dialog()&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt; dlg.test()&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
        def wait_user(msg):&lt;br /&gt;
            self.msgbox(&amp;quot;%s&amp;quot; % msg)&lt;br /&gt;
&lt;br /&gt;
        # rc_to_str&lt;br /&gt;
        wait_user(&amp;quot;Testing return code...&amp;quot;)&lt;br /&gt;
        print self.rc_to_str(self.YES)  # YES&lt;br /&gt;
        print self.rc_to_str(self.NO)  # NO&lt;br /&gt;
        print self.rc_to_str(self.ESC)  # ESX&lt;br /&gt;
        try:&lt;br /&gt;
            print self.rc_to_str(111)  # exception&lt;br /&gt;
            raise Exception(&amp;quot;Did not throw exception&amp;quot;)&lt;br /&gt;
        except Exception as rc:&lt;br /&gt;
            pass&lt;br /&gt;
&lt;br /&gt;
        # msgbox&lt;br /&gt;
        wait_user(&amp;quot;Testing msgbox...&amp;quot;)&lt;br /&gt;
        rc = self.msgbox(&amp;quot;msgbox&amp;quot;)&lt;br /&gt;
        if rc not in (self.YES, self.ESC):&lt;br /&gt;
            raise Exception(&amp;quot;Unknown return code for msgbox: %s&amp;quot; % rc)&lt;br /&gt;
&lt;br /&gt;
        # yesno&lt;br /&gt;
        wait_user(&amp;quot;Testing yesno...&amp;quot;)&lt;br /&gt;
        rc = self.yesno(&amp;quot;yesno&amp;quot;)&lt;br /&gt;
        if rc not in (self.YES, self.NO, self.ESC):&lt;br /&gt;
            raise Exception(&amp;quot;Unknown return code for yesno: %s&amp;quot; % rc)&lt;br /&gt;
&lt;br /&gt;
        # infobox&lt;br /&gt;
        wait_user(&amp;quot;Testing infobox...&amp;quot;)&lt;br /&gt;
        rc = self.infobox(&amp;quot;infobox sleep 1 sec&amp;quot;)&lt;br /&gt;
        if rc not in (self.YES,):&lt;br /&gt;
            raise Exception(&amp;quot;Unknown return code for infobox %s&amp;quot; % rc)&lt;br /&gt;
        time.sleep(1)&lt;br /&gt;
&lt;br /&gt;
        # inputbox&lt;br /&gt;
        wait_user(&amp;quot;Testing inputbox...&amp;quot;)&lt;br /&gt;
        rc, output = self.inputbox(&amp;quot;inputbox&amp;quot;)&lt;br /&gt;
        if rc not in (self.YES, self.NO, self.ESC):&lt;br /&gt;
            raise Exception(&amp;quot;Unknown return code for inputbox: %s&amp;quot; % rc)&lt;br /&gt;
        wait_user(&amp;quot;Result: %s&amp;quot; % output)&lt;br /&gt;
&lt;br /&gt;
        # textbox&lt;br /&gt;
        wait_user(&amp;quot;Testing textbox...&amp;quot;)&lt;br /&gt;
        rc = self.textbox(&amp;quot;/etc/passwd&amp;quot;)&lt;br /&gt;
        if rc not in (self.YES, self.ESC):&lt;br /&gt;
            raise Exception(&amp;quot;Unknown return code for textbox: %s&amp;quot; % rc)&lt;br /&gt;
&lt;br /&gt;
        # menu&lt;br /&gt;
        wait_user(&amp;quot;Testing menu...&amp;quot;)&lt;br /&gt;
        rc, selection = self.menu(&amp;quot;menu&amp;quot;, (&amp;quot;option 1&amp;quot;, &amp;quot;option 2&amp;quot;))&lt;br /&gt;
        if rc not in (self.YES, self.NO, self.ESC):&lt;br /&gt;
            raise Exception(&amp;quot;Unknown return code for menu: %s&amp;quot; % rc)&lt;br /&gt;
        wait_user(&amp;quot;Result: %s&amp;quot; % selection)&lt;br /&gt;
&lt;br /&gt;
        # checklist&lt;br /&gt;
        wait_user(&amp;quot;Testing checklist...&amp;quot;)&lt;br /&gt;
        rc, selection = self.checklist(&amp;quot;menu&amp;quot;, [&amp;quot;option 1&amp;quot;, &amp;quot;option 2&amp;quot;])&lt;br /&gt;
        if rc not in (self.YES, self.NO, self.ESC):&lt;br /&gt;
            raise Exception(&amp;quot;Unknown return code for checklist: %s&amp;quot; % rc)&lt;br /&gt;
        wait_user(&amp;quot;Result: %s&amp;quot; % str(selection))&lt;br /&gt;
        wait_user(&amp;quot;Testing checklist with default selection...&amp;quot;)&lt;br /&gt;
        rc, selection = self.checklist(&amp;quot;menu&amp;quot;, [&amp;quot;option 1&amp;quot;, &amp;quot;option 2&amp;quot;], [1, 2])&lt;br /&gt;
        if rc not in (self.YES, self.NO, self.ESC):&lt;br /&gt;
            raise Exception(&amp;quot;Unknown return code for checklist: %s&amp;quot; % rc)&lt;br /&gt;
        wait_user(&amp;quot;Result: %s&amp;quot; % str(selection))&lt;br /&gt;
&lt;br /&gt;
        # radiolist&lt;br /&gt;
        wait_user(&amp;quot;Testing radiolist...&amp;quot;)&lt;br /&gt;
        rc, selection = self.radiolist(&amp;quot;menu&amp;quot;, [&amp;quot;option 1&amp;quot;, &amp;quot;option 2&amp;quot;])&lt;br /&gt;
        if rc not in (self.YES, self.NO, self.ESC):&lt;br /&gt;
            raise Exception(&amp;quot;Unknown return code for radiolist: %s&amp;quot; % rc)&lt;br /&gt;
        wait_user(&amp;quot;Result: %s&amp;quot; % str(selection))&lt;br /&gt;
        wait_user(&amp;quot;Testing radiolist with default selection...&amp;quot;)&lt;br /&gt;
        rc, selection = self.radiolist(&amp;quot;menu&amp;quot;, [&amp;quot;option 1&amp;quot;, &amp;quot;option 2&amp;quot;], 2)&lt;br /&gt;
        if rc not in (self.YES, self.NO, self.ESC):&lt;br /&gt;
            raise Exception(&amp;quot;Unknown return code for radiolist: %s&amp;quot; % rc)&lt;br /&gt;
        wait_user(&amp;quot;Result: %s&amp;quot; % str(selection))&lt;br /&gt;
&lt;br /&gt;
        # guage&lt;br /&gt;
        wait_user(&amp;quot;Testing guage...&amp;quot;)&lt;br /&gt;
        for i in range(4+1):&lt;br /&gt;
            rc = self.gauge(&amp;quot;test guage&amp;quot;, i*25)&lt;br /&gt;
            # rc = self.progress(&amp;quot;test progress&amp;quot;, i*25)&lt;br /&gt;
            if rc not in (self.YES,):&lt;br /&gt;
                raise Exception(&amp;quot;Unknown return code for guage: %s&amp;quot; % rc)&lt;br /&gt;
            time.sleep(1)&lt;br /&gt;
&lt;br /&gt;
        # form&lt;br /&gt;
        wait_user(&amp;quot;Testing form...&amp;quot;)&lt;br /&gt;
        rc, answers = self.form(&amp;quot;form&amp;quot;, [&amp;quot;option 1&amp;quot;, &amp;quot;option 2&amp;quot;])&lt;br /&gt;
        if rc not in (self.YES, self.NO, self.ESC):&lt;br /&gt;
            raise Exception(&amp;quot;Unknown return code for form: %s&amp;quot; % rc)&lt;br /&gt;
        wait_user(&amp;quot;Result: %s&amp;quot; % str(answers))&lt;br /&gt;
&lt;br /&gt;
        # done with test, cleanup&lt;br /&gt;
        wait_user(&amp;quot;Done with tests...&amp;quot;)&lt;br /&gt;
        self.clear()&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
    # dialog = Dialog()&lt;br /&gt;
    # dialog.test()&lt;br /&gt;
    pass&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Busy Loop and Thread.yield() ===&lt;br /&gt;
&lt;br /&gt;
&amp;quot;I want to tell my Python threads to yield, and so avoid hogging the CPU unnecessarily. In Java, you could do that using the Thread.yield() function&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Solution:&lt;br /&gt;
 time.sleep(0)&lt;br /&gt;
 time.sleep(0.00001)&lt;br /&gt;
 time.sleep(epsilon)&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* multithreading - In there something similar to Java&#039;s Thread.yield() in Python? Does that even make sense? - Stack Overflow - http://stackoverflow.com/questions/1908206/in-there-something-similar-to-javas-thread-yield-in-python-does-that-even-ma&lt;br /&gt;
* multithreading - How does a threading.Thread yield the rest of its quantum in Python? - Stack Overflow - http://stackoverflow.com/questions/787803/how-does-a-threading-thread-yield-the-rest-of-its-quantum-in-python&lt;br /&gt;
&lt;br /&gt;
=== USB ===&lt;br /&gt;
&lt;br /&gt;
Programming with PyUSB 1.0 - http://pyusb.sourceforge.net/docs/1.0/tutorial.html&lt;br /&gt;
&lt;br /&gt;
PyUSB - http://pyusb.sourceforge.net/&lt;br /&gt;
&lt;br /&gt;
 git clone https://github.com/walac/pyusb&lt;br /&gt;
&lt;br /&gt;
 import usb.core&lt;br /&gt;
 dev = usb.core.find()&lt;br /&gt;
&lt;br /&gt;
 # find our device&lt;br /&gt;
 dev = usb.core.find(idVendor=0xfffe, idProduct=0x0001)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&#039;&#039;&#039;Dealing with multiple identical devices&#039;&#039;&#039; - Sometimes you may have two identical devices connected to the computer. How can you differentiate them? Device objects come with two additional attributes which are not part of the USB Spec, but are very useful: bus and address attributes. First of all, it is worth to say that these attributes come from the backend and a backend is free to not support them, in which case they are set to None. That said, these attributes represent the bus number and bus address of the device and, as you might already have imagined, can be used to differentiate two devices with the same idVendor and idProduct attributes.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Tkinter ===&lt;br /&gt;
&lt;br /&gt;
Python GUI Bitcoin: [http://bitcoin.stackexchange.com/questions/10594/simplest-way-of-obtaining-mtgox-exchange-rate-via-an-api]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import json&lt;br /&gt;
import urllib2&lt;br /&gt;
from Tkinter import *&lt;br /&gt;
&lt;br /&gt;
url=&#039;http://api.bitcoincharts.com/v1/markets.json&#039;&lt;br /&gt;
req=urllib2.Request(url)&lt;br /&gt;
response=urllib2.urlopen(req).read()&lt;br /&gt;
output=json.loads(response)&lt;br /&gt;
&lt;br /&gt;
mtusd_price = output[-10][&#039;avg&#039;]&lt;br /&gt;
mteur_price = output[31][&#039;avg&#039;]&lt;br /&gt;
mtgbp_price = output[44][&#039;avg&#039;]&lt;br /&gt;
&lt;br /&gt;
MTUSD= &#039;USD&#039; + &#039; &#039; + str(mtusd_price)&lt;br /&gt;
MTEUR= &#039;EUR&#039; + &#039; &#039; + str(mteur_price)&lt;br /&gt;
MTGBP = &#039;GBP&#039; + &#039; &#039; + str(mtgbp_price)&lt;br /&gt;
&lt;br /&gt;
root= Tk()&lt;br /&gt;
root.title(&amp;quot;Bitcoin Price&amp;quot;)&lt;br /&gt;
root.geometry(&amp;quot;250x100&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
USD = Label(root, text=MTUSD)&lt;br /&gt;
EUR = Label(root, text=MTEUR)&lt;br /&gt;
GBP = Label(root, text=MTGBP)&lt;br /&gt;
USD.pack()&lt;br /&gt;
EUR.pack()&lt;br /&gt;
GBP.pack()&lt;br /&gt;
mainloop()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== ctypes ===&lt;br /&gt;
&lt;br /&gt;
&amp;quot;ctypes is a foreign function library for Python. It provides C compatible data types, and allows calling functions in DLLs or shared libraries. It can be used to wrap these libraries in pure Python.&amp;quot;&lt;br /&gt;
:-- 15.17. ctypes — A foreign function library for Python — Python v2.7.7 documentation - https://docs.python.org/2/library/ctypes.html&lt;br /&gt;
&lt;br /&gt;
Use &amp;quot;c scope&amp;quot; to build a database of symbols to see what options are available.&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
testlib.c&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void myprint(void);&lt;br /&gt;
&lt;br /&gt;
void myprint()&lt;br /&gt;
{&lt;br /&gt;
    printf(&amp;quot;hello world\n&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Compile:&lt;br /&gt;
 gcc -shared -Wl,-soname,testlib -o testlib.so -fPIC testlib.c&lt;br /&gt;
&lt;br /&gt;
testlibwrapper.py&lt;br /&gt;
&lt;br /&gt;
Python:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import ctypes&lt;br /&gt;
&lt;br /&gt;
testlib = ctypes.CDLL(&#039;/full/path/to/testlib.so&#039;)&lt;br /&gt;
testlib.myprint()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Source: python - ctypes - Beginner - Stack Overflow - http://stackoverflow.com/questions/5081875/ctypes-beginner&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
nzjrs&#039;s Gists - https://gist.github.com/nzjrs&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int sum(double *x,int n)&lt;br /&gt;
{&lt;br /&gt;
  int i;&lt;br /&gt;
  double counter;&lt;br /&gt;
  counter = 0;&lt;br /&gt;
  for(i=0;i&amp;lt;n;i++)&lt;br /&gt;
    {&lt;br /&gt;
      counter=counter+x[i];&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
  return counter;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -c sum.c&lt;br /&gt;
gcc -shared -o sum.so sum.o&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from ctypes import *&lt;br /&gt;
my_sum=CDLL(&#039;sum.so&#039;)&lt;br /&gt;
a=numpy.array(range(10),dtype=float)&lt;br /&gt;
my_sum.sum(a.ctypes.data_as(c_void_p),int(10))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
a=(c_double*10)()&lt;br /&gt;
for i in range(10):&lt;br /&gt;
   a[i]=i&lt;br /&gt;
my_sum.sum(a,int(10))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Source: Ctypes — Numerical Computing with Sage v6.2 - http://www.sagemath.org/doc/numerical_sage/ctypes.html&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
=== Warnings ===&lt;br /&gt;
&lt;br /&gt;
 if sys.version_info &amp;gt;= (1, 0, 0):&lt;br /&gt;
   warnings.warn(&amp;quot;Danger Will Robinson: trying Phi on untested Python 3.0!&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
=== enum ===&lt;br /&gt;
&lt;br /&gt;
Python 3: https://docs.python.org/3/library/enum.html&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from enum import Enum&lt;br /&gt;
&lt;br /&gt;
# class syntax&lt;br /&gt;
class Color(Enum):&lt;br /&gt;
    RED = 1&lt;br /&gt;
    GREEN = 2&lt;br /&gt;
    BLUE = 3&lt;br /&gt;
&lt;br /&gt;
# functional syntax&lt;br /&gt;
Color = Enum(&#039;Color&#039;, [&#039;RED&#039;, &#039;GREEN&#039;, &#039;BLUE&#039;])&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
Python 2: [http://stackoverflow.com/questions/36932/how-can-i-represent-an-enum-in-python]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Enum(set):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot; Basic enumerated type&lt;br /&gt;
    &lt;br /&gt;
    Example&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt; Animals = phi.Enum([&amp;quot;DOG&amp;quot;, &amp;quot;CAT&amp;quot;, &amp;quot;HORSE&amp;quot;])&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt; Animals.DOG&lt;br /&gt;
        &#039;DOG&#039;&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt; &#039;HORSE&#039; in Animals&lt;br /&gt;
        True&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    def __getattr__(self, name):&lt;br /&gt;
        if name in self:&lt;br /&gt;
            return name&lt;br /&gt;
        raise AttributeError(&amp;quot;Missing Enum property: %s&amp;quot; % name)&lt;br /&gt;
    def __setattr__(self, name, value):  # this makes it read-only&lt;br /&gt;
        raise AttributeError(&amp;quot;Unable to modify Enum property: %s (%s)&amp;quot; % (name, value))&lt;br /&gt;
&lt;br /&gt;
Animals = Enum([&amp;quot;DOG&amp;quot;, &amp;quot;CAT&amp;quot;, &amp;quot;HORSE&amp;quot;])&lt;br /&gt;
&lt;br /&gt;
print(Animals.DOG)  # &#039;DOG&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----------&lt;br /&gt;
&lt;br /&gt;
Alternative:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Stationery:&lt;br /&gt;
    Pen, Pencil, Eraser = range(0, 3)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
One liner:&lt;br /&gt;
 class Enum(tuple): __getattr__ = tuple.index&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; State = Enum([&#039;Unclaimed&#039;, &#039;Claimed&#039;])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; State.Claimed&lt;br /&gt;
1&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; State[1]&lt;br /&gt;
&#039;Claimed&#039;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; State&lt;br /&gt;
(&#039;Unclaimed&#039;, &#039;Claimed&#039;)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; range(len(State))&lt;br /&gt;
[0, 1]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; [(k, State[k]) for k in range(len(State))]&lt;br /&gt;
[(0, &#039;Unclaimed&#039;), (1, &#039;Claimed&#039;)]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; [(k, getattr(State, k)) for k in State]&lt;br /&gt;
[(&#039;Unclaimed&#039;, 0), (&#039;Claimed&#039;, 1)]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Python 3 supports enum natively with the enum.Enum library:&lt;br /&gt;
&lt;br /&gt;
=== pySerial ===&lt;br /&gt;
&lt;br /&gt;
https://pythonhosted.org/pyserial/&lt;br /&gt;
&lt;br /&gt;
&amp;quot;This module encapsulates the access for the serial port. It provides backends for Python running on Windows, OSX, Linux, BSD (possibly any POSIX compliant system) and IronPython. The module named “serial” automatically selects the appropriate backend.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
https://github.com/pyserial/&lt;br /&gt;
&lt;br /&gt;
Intro - https://pythonhosted.org/pyserial/shortintro.html&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import serial&lt;br /&gt;
import time&lt;br /&gt;
&lt;br /&gt;
ser = serial.Serial(&lt;br /&gt;
    port=&#039;COM4&#039;,\&lt;br /&gt;
    baudrate=9600,\&lt;br /&gt;
    parity=serial.PARITY_NONE,\&lt;br /&gt;
    stopbits=serial.STOPBITS_ONE,\&lt;br /&gt;
    bytesize=serial.EIGHTBITS,\&lt;br /&gt;
        timeout=0)&lt;br /&gt;
&lt;br /&gt;
print(&amp;quot;connected to: &amp;quot; + ser.portstr)&lt;br /&gt;
&lt;br /&gt;
#this will store the line&lt;br /&gt;
seq = []&lt;br /&gt;
count = 1&lt;br /&gt;
&lt;br /&gt;
while True:&lt;br /&gt;
    for c in ser.read():&lt;br /&gt;
        seq.append(chr(c)) #convert from ANSII&lt;br /&gt;
        joined_seq = &#039;&#039;.join(str(v) for v in seq) #Make a string from array&lt;br /&gt;
&lt;br /&gt;
        if chr(c) == &#039;\n&#039;:&lt;br /&gt;
            print(&amp;quot;Line &amp;quot; + str(count) + &#039;: &#039; + joined_seq)&lt;br /&gt;
            seq = []&lt;br /&gt;
            count += 1&lt;br /&gt;
            break&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ser.close()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ref: http://stackoverflow.com/questions/16077912/python-serial-how-to-use-the-read-or-readline-function-to-read-more-than-1-char&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
I modified the code to monitor a COM port: (Windows)&lt;br /&gt;
&lt;br /&gt;
Monitor Serial:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import serial, time, sys&lt;br /&gt;
&lt;br /&gt;
logger = open(&amp;quot;serial.txt&amp;quot;, &amp;quot;w&amp;quot;)&lt;br /&gt;
timer = time.time()&lt;br /&gt;
&lt;br /&gt;
def log(msg, head=False):&lt;br /&gt;
    msg = msg.strip()&lt;br /&gt;
    if head:&lt;br /&gt;
      msg = &amp;quot;&amp;gt;&amp;gt;&amp;gt; &amp;quot; + msg&lt;br /&gt;
    logger.write(msg + &amp;quot;\n&amp;quot;)&lt;br /&gt;
    sys.stdout.write(msg + &amp;quot;\n&amp;quot;)&lt;br /&gt;
    newtime = time.time()&lt;br /&gt;
    if newtime &amp;gt; timer + 1:&lt;br /&gt;
        logger.flush()&lt;br /&gt;
        sys.stdout.flush()&lt;br /&gt;
&lt;br /&gt;
while True:&lt;br /&gt;
&lt;br /&gt;
    ser = None&lt;br /&gt;
    try:&lt;br /&gt;
        ser = serial.Serial(&lt;br /&gt;
            port=&#039;COM1&#039;,\&lt;br /&gt;
            baudrate=115200,\&lt;br /&gt;
            parity=serial.PARITY_NONE,\&lt;br /&gt;
            stopbits=serial.STOPBITS_ONE,\&lt;br /&gt;
            bytesize=serial.EIGHTBITS,\&lt;br /&gt;
                timeout=0)&lt;br /&gt;
    except serial.serialutil.SerialException as e:&lt;br /&gt;
        log(str(e), True)&lt;br /&gt;
        time.sleep(1)&lt;br /&gt;
        continue&lt;br /&gt;
&lt;br /&gt;
    log(&amp;quot;Connected to: &amp;quot; + ser.portstr, True)&lt;br /&gt;
    count=1&lt;br /&gt;
&lt;br /&gt;
    try:&lt;br /&gt;
        line = []&lt;br /&gt;
        while True:&lt;br /&gt;
            for c in ser.readline():&lt;br /&gt;
                line.append(c)&lt;br /&gt;
                if c == &amp;quot;\n&amp;quot;:&lt;br /&gt;
                    log(&amp;quot;&amp;quot;.join(line))&lt;br /&gt;
                    line = []&lt;br /&gt;
    except serial.serialutil.SerialException as e:&lt;br /&gt;
        log(str(e), True)&lt;br /&gt;
        time.sleep(1)&lt;br /&gt;
    ser.close()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== MyBool ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; class NewBool(int):&lt;br /&gt;
...    def __new__(cls, value):&lt;br /&gt;
...        return int.__new__(cls, bool(value))&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; y = NewBool(2)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; y == 1&lt;br /&gt;
True&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
https://jfine-python-classes.readthedocs.io/en/latest/subclass-int.html&lt;br /&gt;
&lt;br /&gt;
Also check out the __cmp__&lt;br /&gt;
&lt;br /&gt;
== md5 ==&lt;br /&gt;
&lt;br /&gt;
 import md5&lt;br /&gt;
 md5.new(&amp;quot;Nobody inspects the spammish repetition&amp;quot;).hexdigest()&lt;br /&gt;
 # &#039;bb649c83dd1ea5c9d9dec9a18df0ffe9&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ echo -n &amp;quot;Nobody inspects the spammish repetition&amp;quot; | md5sum&lt;br /&gt;
bb649c83dd1ea5c9d9dec9a18df0ffe9  -&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== External Libraries ==&lt;br /&gt;
&lt;br /&gt;
=== execnet ===&lt;br /&gt;
&lt;br /&gt;
Python Package Index - execnet - https://pypi.python.org/pypi/execnet&lt;br /&gt;
&lt;br /&gt;
Examples - http://codespeak.net/execnet/examples.html&lt;br /&gt;
* basic local and remote communication - http://codespeak.net/execnet/example/test_info.html&lt;br /&gt;
&lt;br /&gt;
Execute source code in subprocess, communicate through a channel:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import execnet&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; gw = execnet.makegateway()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; channel = gw.remote_exec(&amp;quot;channel.send(channel.receive()+1)&amp;quot;)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; channel.send(1)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; channel.receive()&lt;br /&gt;
2&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Compare current working directories&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import execnet, os&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; gw = execnet.makegateway()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; ch = gw.remote_exec(&amp;quot;import os; channel.send(os.getcwd())&amp;quot;)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; res = ch.receive()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; assert res == os.getcwd()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Get information from remote ssh account&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import execnet, os&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; gw = execnet.makegateway(&amp;quot;ssh=codespeak.net&amp;quot;)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; channel = gw.remote_exec(&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
...     import sys, os&lt;br /&gt;
...     channel.send((sys.platform, sys.version_info, os.getpid()))&lt;br /&gt;
... &amp;quot;&amp;quot;&amp;quot;)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; platform, version_info, remote_pid = channel.receive()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; platform&lt;br /&gt;
&#039;linux2&#039;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; version_info&lt;br /&gt;
(2, 4, 2, &#039;final&#039;, 0)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
remote-exec a function (avoiding inlined source part I)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import execnet&lt;br /&gt;
&lt;br /&gt;
def multiplier(channel, factor):&lt;br /&gt;
    while not channel.isclosed():&lt;br /&gt;
        param = channel.receive()&lt;br /&gt;
        channel.send(param * factor)&lt;br /&gt;
&lt;br /&gt;
gw = execnet.makegateway()&lt;br /&gt;
channel = gw.remote_exec(multiplier, factor=10)&lt;br /&gt;
&lt;br /&gt;
for i in range(5):&lt;br /&gt;
    channel.send(i)&lt;br /&gt;
    result = channel.receive()&lt;br /&gt;
    assert result == i * 10&lt;br /&gt;
&lt;br /&gt;
gw.exit()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
remote-exec a module (avoiding inlined source part II)&lt;br /&gt;
:&amp;quot;You can pass a module object to remote_exec in which case its source code will be sent. No dependencies will be transferred so the module must be self-contained or only use modules that are installed on the “other” side. Module code can detect if it is running in a remote_exec situation by checking for the special __name__ attribute.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# content of a module remote1.py&lt;br /&gt;
&lt;br /&gt;
if __name__ == &#039;__channelexec__&#039;:&lt;br /&gt;
    channel.send(&#039;initialization complete&#039;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import execnet, remote1&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; gw = execnet.makegateway()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; ch = gw.remote_exec(remote1)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; print (ch.receive())&lt;br /&gt;
initialization complete&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use a callback instead of receive() and wait for completion&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import execnet&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; gw = execnet.makegateway()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; channel = gw.remote_exec(&amp;quot;for i in range(10): channel.send(i)&amp;quot;)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; l = []&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; channel.setcallback(l.append, endmarker=None)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; channel.waitclose() # waits for closing, i.e. remote exec finish&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; l&lt;br /&gt;
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, None]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
a simple command loop pattern&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# contents of: remotecmd.py&lt;br /&gt;
import os&lt;br /&gt;
&lt;br /&gt;
def simple(arg):&lt;br /&gt;
    return arg + 1&lt;br /&gt;
&lt;br /&gt;
def listdir(path):&lt;br /&gt;
    return os.listdir(path)&lt;br /&gt;
    &lt;br /&gt;
if __name__ == &#039;__channelexec__&#039;:&lt;br /&gt;
    for item in channel:&lt;br /&gt;
        channel.send(eval(item))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import execnet, remotecmd&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; gw = execnet.makegateway()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; ch = gw.remote_exec(remotecmd)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; ch.send(&#039;simple(10)&#039;) # execute func-call remotely&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; ch.receive()&lt;br /&gt;
11&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== evdev ===&lt;br /&gt;
&lt;br /&gt;
Install:&lt;br /&gt;
 apt-get install python-setuptools python-dev&lt;br /&gt;
 easy_install pip&lt;br /&gt;
 pip install evdev&lt;br /&gt;
&lt;br /&gt;
Simple read usage:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from evdev import InputDevice&lt;br /&gt;
from evdev import ecodes&lt;br /&gt;
&lt;br /&gt;
# look for a /dev/input/by-id/usb...kbd or similar&lt;br /&gt;
DEVICE = &amp;quot;/dev/input/by-id/usb-ORTEK_USB_Keyboard_Hub-event-kbd&amp;quot;&lt;br /&gt;
&lt;br /&gt;
dev = InputDevice(DEVICE)&lt;br /&gt;
&lt;br /&gt;
while True:&lt;br /&gt;
    r, w, x = select([dev], [], [], 5)&lt;br /&gt;
    for event in dev.read():&lt;br /&gt;
        if event.type == 1 and event.value == 1:&lt;br /&gt;
            print event.code&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
List LED states:&lt;br /&gt;
 dev.leds()&lt;br /&gt;
 dev.leds(verbose=True)&lt;br /&gt;
&lt;br /&gt;
Inject usage: (does not appear to really work)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from evdev import InputDevice&lt;br /&gt;
from evdev import ecodes&lt;br /&gt;
from evdev import UInput&lt;br /&gt;
&lt;br /&gt;
DEVICE = &amp;quot;/dev/input/by-id/usb-ORTEK_USB_Keyboard_Hub-event-kbd&amp;quot;&lt;br /&gt;
dev = InputDevice(DEVICE)&lt;br /&gt;
&lt;br /&gt;
ui = UInput()&lt;br /&gt;
&lt;br /&gt;
ui.write(ecodes.EV_KEY, ecodes.KEY_4, 1)&lt;br /&gt;
ui.write(ecodes.EV_KEY, ecodes.KEY_4, 0)&lt;br /&gt;
ui.syn()&lt;br /&gt;
&lt;br /&gt;
ui.write(ecodes.EV_KEY, ecodes.KEY_NUMLOCK, 1)&lt;br /&gt;
ui.write(ecodes.EV_KEY, ecodes.KEY_NUMLOCK, 0)&lt;br /&gt;
ui.syn()&lt;br /&gt;
&lt;br /&gt;
ui.close()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Tutorial:&lt;br /&gt;
* evdev documentation — python-evdev 0.4.3 documentation - http://pythonhosted.org/evdev/index.html&lt;br /&gt;
References:&lt;br /&gt;
* python-evdev/doc/tutorial.rst at master · gvalkov/python-evdev · GitHub - https://github.com/gvalkov/python-evdev/blob/master/doc/tutorial.rst&lt;br /&gt;
&lt;br /&gt;
=== ldap-python ===&lt;br /&gt;
&lt;br /&gt;
python-ldap: LDAP client API for Python - http://www.python-ldap.org/&lt;br /&gt;
&lt;br /&gt;
Index of Packages : Python Package Index - https://pypi.python.org/pypi/python-ldap/&lt;br /&gt;
&lt;br /&gt;
 yum install python-devel openldap-devel&lt;br /&gt;
 pip install python-ldap&lt;br /&gt;
&lt;br /&gt;
Articles:&lt;br /&gt;
* Python LDAP Applications: Part 1 - Installing and Configuring the Python-LDAP Library and Binding to an LDAP Directory | Packt Publishing - http://www.packtpub.com/article/installing-and-configuring-the-python-ldap-library-and-binding-to-an-ldap-directory&lt;br /&gt;
&lt;br /&gt;
=== xmmp ===&lt;br /&gt;
&lt;br /&gt;
PDF:&lt;br /&gt;
* XMPP: The Definitive Guide - Oreilly - http://oriolrius.cat/blog/wp-content/uploads/2009/10/Oreilly.XMPP.The.Definitive.Guide.May.2009.pdf&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
xmmp is the Jabber protocol&lt;br /&gt;
&lt;br /&gt;
Best options:&lt;br /&gt;
&lt;br /&gt;
MIT libraries.&lt;br /&gt;
* sleekxmpp (was: sleekxmpp) is pretty popular and is used for examples in Peter Saint-Andre&#039;s XMPP book from O&#039;Reilly. It reportedly works well, and finally got an email list in April 2010, and has a chat room at sleek@conference.jabber.org.&lt;br /&gt;
&lt;br /&gt;
GPL libraries.&lt;br /&gt;
* xmpppy is used by gajim.&lt;br /&gt;
&lt;br /&gt;
LPGL libraries.&lt;br /&gt;
* pyxmpp is pretty good and uses libxml2 internally for xml parsing.&lt;br /&gt;
* pyxmpp2 is the next version of pyxmpp, runs on python 2.7 and 3.2, and removes the libxml2 requirement. Like many, it requires dnspython.&lt;br /&gt;
* jabberpy is the original and still works for a lot of tasks, but is thoroughly unmaintained.&lt;br /&gt;
&lt;br /&gt;
Other libraries.&lt;br /&gt;
* Wokkel, mentioned in another post. That&#039;s a new one for me, based on twisted.&lt;br /&gt;
&lt;br /&gt;
chat - Best python XMPP / Jabber client library? - Stack Overflow - http://stackoverflow.com/questions/1901828/best-python-xmpp-jabber-client-library&lt;br /&gt;
&lt;br /&gt;
=== xmpppy ===&lt;br /&gt;
&lt;br /&gt;
xmpppy: the jabber python project - http://xmpppy.sourceforge.net/&lt;br /&gt;
&lt;br /&gt;
&amp;quot;xmpppy is a Python library that is targeted to provide easy scripting with Jabber. Similar projects are Twisted Words and jabber.py.&lt;br /&gt;
&lt;br /&gt;
This library was not designed from scratch. It inherits some code from jabberpy and have very similar API in many places. Though it is separate project since it have almost completely different architecture and primarily aims to work with jabberd2 - the new Open Source Jabber Server.&lt;br /&gt;
&lt;br /&gt;
xmpppy is distributed under the terms of GNU General Public License and can be freely redistributed without any charge.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 wget http://sourceforge.net/projects/xmpppy/files/xmpppy/0.4.1/xmpppy-0.4.1.tar.gz/download -O xmpppy-0.4.1.tar.gz&lt;br /&gt;
 tar -zvxf xmpppy-0.4.1.tar.gz&lt;br /&gt;
 pip install pydns&lt;br /&gt;
&lt;br /&gt;
--- basic connection ---&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
 &lt;br /&gt;
import xmpp&lt;br /&gt;
 &lt;br /&gt;
user=&amp;quot;username@gmail.com&amp;quot;&lt;br /&gt;
password=&amp;quot;password&amp;quot;&lt;br /&gt;
server=&amp;quot;gmail.com&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
jid = xmpp.JID(user)&lt;br /&gt;
connection = xmpp.Client(server,debug=[])&lt;br /&gt;
connection.connect()&lt;br /&gt;
result = connection.auth(jid.getNode(), password,&amp;quot;LFY-client&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
connection.sendInitPresence()&lt;br /&gt;
 &lt;br /&gt;
while connection.Process(1):&lt;br /&gt;
    pass&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* Use XMPP to Create Your Own Google Talk Client - LINUX For You - http://www.linuxforu.com/2012/06/use-xmpp-to-create-your-own-google-talk-client/&lt;br /&gt;
&lt;br /&gt;
--- basic receive ---&lt;br /&gt;
&lt;br /&gt;
Print messages when received:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
 &lt;br /&gt;
import xmpp&lt;br /&gt;
 &lt;br /&gt;
user=&amp;quot;username@gmail.com&amp;quot;&lt;br /&gt;
password=&amp;quot;password&amp;quot;&lt;br /&gt;
server=&amp;quot;gmail.com&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
def message_handler(connect_object, message_node):&lt;br /&gt;
        message = &amp;quot;Welcome to my first Gtalk Bot :)&amp;quot;&lt;br /&gt;
        connect_object.send( xmpp.Message( message_node.getFrom() ,message))&lt;br /&gt;
 &lt;br /&gt;
jid = xmpp.JID(user)&lt;br /&gt;
connection = xmpp.Client(server)&lt;br /&gt;
connection.connect()&lt;br /&gt;
result = connection.auth(jid.getNode(), password, &amp;quot;LFY-client&amp;quot;)&lt;br /&gt;
connection.RegisterHandler(&#039;message&#039;, message_handler)&lt;br /&gt;
 &lt;br /&gt;
connection.sendInitPresence()&lt;br /&gt;
 &lt;br /&gt;
while connection.Process(1):&lt;br /&gt;
    pass&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* Use XMPP to Create Your Own Google Talk Client - LINUX For You - http://www.linuxforu.com/2012/06/use-xmpp-to-create-your-own-google-talk-client/&lt;br /&gt;
&lt;br /&gt;
--- remote-control shell bot ---&lt;br /&gt;
&lt;br /&gt;
Replace the simple bot’s message_handler() function with this new one:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def message_handler(connect_object,message_node):&lt;br /&gt;
        command = str(message_node.getBody())&lt;br /&gt;
 &lt;br /&gt;
        process = subprocess.Popen(command,shell=True,stdout=subprocess.PIPE, stderr=subprocess.PIPE)&lt;br /&gt;
        message = process.stdout.read()&lt;br /&gt;
        if message==&amp;quot;&amp;quot;:&lt;br /&gt;
            message=process.stderr.read()&lt;br /&gt;
 &lt;br /&gt;
        connect_object.send( xmpp.Message( message_node.getFrom() ,message))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* Use XMPP to Create Your Own Google Talk Client - LINUX For You - http://www.linuxforu.com/2012/06/use-xmpp-to-create-your-own-google-talk-client/&lt;br /&gt;
&lt;br /&gt;
--- roster ---&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import xmpp&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
userID   = &#039;myname@gmail.com&#039; &lt;br /&gt;
password = &#039;mypassword&#039;&lt;br /&gt;
ressource = &#039;Script&#039;&lt;br /&gt;
&lt;br /&gt;
jid  = xmpp.protocol.JID(userID)&lt;br /&gt;
jabber  = xmpp.Client(jid.getDomain(), debug=[])&lt;br /&gt;
&lt;br /&gt;
connection = jabber.connect((&#039;talk.google.com&#039;,5222))&lt;br /&gt;
auth = jabber.auth(jid.getNode(), password, ressource)&lt;br /&gt;
&lt;br /&gt;
jabber.sendInitPresence(requestRoster=1)&lt;br /&gt;
myroster = jabber.getRoster()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To get status, you have to wait for the other clients to send you their status:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
jabber.RegisterHandler(&#039;presence&#039;, myPresenceHandler)&lt;br /&gt;
&lt;br /&gt;
def myPresenceHandler(con, event):&lt;br /&gt;
  fromjid = event.getFrom().getStripped()&lt;br /&gt;
  status = myroster.getStatus(fromjid)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
python - XMPP chat: accessing contacts&#039; status messages with xmppPy&#039;s Roster - Stack Overflow - http://stackoverflow.com/questions/2381597/xmpp-chat-accessing-contacts-status-messages-with-xmpppys-roster&lt;br /&gt;
&lt;br /&gt;
--- full roster script ---&lt;br /&gt;
&lt;br /&gt;
kparal/jabber-roster · GitHub - https://github.com/kparal/jabber-roster&lt;br /&gt;
&lt;br /&gt;
A simple Python tool for listing your Jabber roster contacts. You can use it to easily backup list of your buddies.&lt;br /&gt;
&lt;br /&gt;
This program is maintained, but not further developed. Bugs will be fixed, but no new features will be added. If you want to work on this program, don&#039;t hesitate to contact me, I will gladly assign you to the development team.&lt;br /&gt;
&lt;br /&gt;
 git clone https://github.com/kparal/jabber-roster&lt;br /&gt;
 python jabber_roster.py&lt;br /&gt;
&lt;br /&gt;
https://pypi.python.org/pypi/jabber-roster&lt;br /&gt;
&lt;br /&gt;
--- vcard ---&lt;br /&gt;
&lt;br /&gt;
This information is not in the roster. You will need to query the clients individually and get their vCard by sending this IQ :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;iq from=&#039;stpeter@jabber.org/roundabout&#039;&lt;br /&gt;
    id=&#039;v1&#039;&lt;br /&gt;
    type=&#039;get&#039;&amp;gt;&lt;br /&gt;
  &amp;lt;vCard xmlns=&#039;vcard-temp&#039;/&amp;gt;&lt;br /&gt;
&amp;lt;/iq&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
My solution:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def vcard(disp, jid):&lt;br /&gt;
    msg = xmpp.protocol.Iq()&lt;br /&gt;
    msg.setType(&#039;get&#039;)&lt;br /&gt;
    msg.setTo(jid)&lt;br /&gt;
    qc = msg.addChild(&#039;vCard&#039;)&lt;br /&gt;
    qc.setAttr(&#039;xmlns&#039;, &#039;vcard-temp&#039;)&lt;br /&gt;
    rep = disp.SendAndWaitForResponse(msg)&lt;br /&gt;
    # to see what other fields are available in the XML output:&lt;br /&gt;
    # print rep&lt;br /&gt;
    userid=fname=lname=title=department=region=None&lt;br /&gt;
    for i in rep.getChildren():&lt;br /&gt;
        for j in i.getChildren():&lt;br /&gt;
            if j.getName() == &amp;quot;TITLE&amp;quot;:&lt;br /&gt;
                title = j.getData().encode(&#039;utf-8&#039;)&lt;br /&gt;
            for k in j.getChildren():&lt;br /&gt;
                if k.getName() == &amp;quot;GIVEN&amp;quot;:&lt;br /&gt;
                    fname = k.getData().encode(&#039;utf-8&#039;)&lt;br /&gt;
                if k.getName() == &amp;quot;FAMILY&amp;quot;:&lt;br /&gt;
                    lname = k.getData().encode(&#039;utf-8&#039;)&lt;br /&gt;
                if k.getName() == &amp;quot;ORGUNIT&amp;quot;:&lt;br /&gt;
                    department = k.getData().encode(&#039;utf-8&#039;)&lt;br /&gt;
                if k.getName() == &amp;quot;REGION&amp;quot;:&lt;br /&gt;
                    region = k.getData().encode(&#039;utf-8&#039;)&lt;br /&gt;
    return fname, lname, title, department, region&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* xmpppy - Retrieve gtalk nickname in python xmpp - Stack Overflow - http://stackoverflow.com/questions/4539477/retrieve-gtalk-nickname-in-python-xmpp&lt;br /&gt;
* XEP-0054: vcard-temp - http://xmpp.org/extensions/xep-0054.html&lt;br /&gt;
&lt;br /&gt;
=== google-api-python-client ===&lt;br /&gt;
&lt;br /&gt;
Google APIs Client Library for Python, which includes:&lt;br /&gt;
* google-api-python-client: The core Python library for accessing Google APIs.&lt;br /&gt;
* oauth2client: A Python client library for OAuth 2.0.&lt;br /&gt;
* Sample applications using google-api-python-client and oauth2client &lt;br /&gt;
&lt;br /&gt;
-&lt;br /&gt;
&lt;br /&gt;
https://developers.google.com/api-client-library/python/start/installation&lt;br /&gt;
* Calendar API - Python/Command Line&lt;br /&gt;
&lt;br /&gt;
-&lt;br /&gt;
Download:&lt;br /&gt;
 wget https://code.google.com/p/google-api-python-client/downloads/detail?name=google-api-python-client-1.2.zip&lt;br /&gt;
 wget https://code.google.com/p/google-api-python-client/downloads/detail?name=oauth2client-1.2.zip&lt;br /&gt;
&lt;br /&gt;
Git:&lt;br /&gt;
 git clone https://github.com/google/google-api-python-client&lt;br /&gt;
 git clone https://github.com/google/oauth2client&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* google-api-python-client - Google APIs Client Library for Python - Google Project Hosting - https://code.google.com/p/google-api-python-client/&lt;br /&gt;
&lt;br /&gt;
== Documentation Tools ==&lt;br /&gt;
&lt;br /&gt;
=== pydoc ===&lt;br /&gt;
&lt;br /&gt;
pydoc - http://docs.python.org/library/pydoc.html&lt;br /&gt;
: Documentation generator and online help system&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Doxygen and Doxypy ===&lt;br /&gt;
&lt;br /&gt;
See [[Python/Doxygen]]&lt;br /&gt;
&lt;br /&gt;
=== Sphinx ===&lt;br /&gt;
&lt;br /&gt;
Sphinx - http://sphinx.pocoo.org/&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Sphinx is a tool that makes it easy to create intelligent and beautiful documentation, written by Georg Brandl and licensed under the BSD license.&lt;br /&gt;
&lt;br /&gt;
It was originally created for the new Python documentation, and it has excellent facilities for the documentation of Python projects, but C/C++ is already supported as well, and it is planned to add special support for other languages as well. Of course, this site is also created from reStructuredText sources using Sphinx!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== epydoc ===&lt;br /&gt;
&lt;br /&gt;
epydoc - http://epydoc.sourceforge.net/&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Epydoc is a tool for generating API documentation for Python modules, based on their docstrings. For an example of epydoc&#039;s output, see the API documentation for epydoc itself (html, pdf). A lightweight markup language called epytext can be used to format docstrings, and to add information about specific fields, such as parameters and instance variables. Epydoc also understands docstrings written in reStructuredText, Javadoc, and plaintext. For a more extensive example of epydoc&#039;s output, see the API documentation for Python 2.5. &amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Python 3 ==&lt;br /&gt;
&lt;br /&gt;
=== Python 3 Wall of Superpowers ===&lt;br /&gt;
&lt;br /&gt;
Python 3 Wall of Superpowers - https://python3wos.appspot.com/&lt;br /&gt;
&lt;br /&gt;
&amp;quot;As listed on PyPI - packages in red don&#039;t support python 3, packages in green do. Hopefully one day everything will be greener. &amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== New in Python 3 ===&lt;br /&gt;
&lt;br /&gt;
==== qualnames ====&lt;br /&gt;
&lt;br /&gt;
New in 3.3&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; def f():&lt;br /&gt;
...   def g():&lt;br /&gt;
...     class H: pass&lt;br /&gt;
...     return H&lt;br /&gt;
...   return g&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; H=f()()&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; # 3.3:&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; H&lt;br /&gt;
&amp;lt;class &#039;__main__.f.&amp;lt;locals&amp;gt;.g.&amp;lt;locals&amp;gt;.H&#039;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; H.__qualname__&lt;br /&gt;
&#039;f.&amp;lt;locals&amp;gt;.g.&amp;lt;locals&amp;gt;.H&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; # 2.6:&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; H&lt;br /&gt;
&amp;lt;class __main__.H at 0x2b885044b890&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; H.__qualname__&lt;br /&gt;
AttributeError: class H has no attribute &#039;__qualname__&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Python 2 or Python 3 ==&lt;br /&gt;
&lt;br /&gt;
Python2orPython3 - PythonInfo Wiki - http://wiki.python.org/moin/Python2orPython3&lt;br /&gt;
:Short version: Python 2.x is the status quo, Python 3.x is the shiny new thing.&lt;br /&gt;
:At the time of writing (July 4, 2010), the final 2.7 release is out, with a statement of extended support for this end-of-life release. The 2.x branch will see no new major releases after that. 3.x is under active and continued development, with 3.1 already available and 3.2 due for release around the turn of the year.&lt;br /&gt;
&lt;br /&gt;
Python 2.7.1 Release - http://www.python.org/download/releases/2.7.1/&lt;br /&gt;
&lt;br /&gt;
What’s New In Python 3.0 — Python v3.0.1 documentation - http://docs.python.org/release/3.0.1/whatsnew/3.0.html&lt;br /&gt;
* print() requires parenthesis&lt;br /&gt;
* raw_input() is now input()&lt;br /&gt;
&lt;br /&gt;
== Python for Windows ==&lt;br /&gt;
&lt;br /&gt;
Python for Windows - http://www.python.org/download/windows/&lt;br /&gt;
&lt;br /&gt;
=== Windows IDEs ===&lt;br /&gt;
&lt;br /&gt;
==== PyCharm ====&lt;br /&gt;
&lt;br /&gt;
 http://www.pycharm.com/&lt;br /&gt;
&lt;br /&gt;
=== Hide Console ===&lt;br /&gt;
&lt;br /&gt;
fork() does not work on windows.  So what else can we do?&lt;br /&gt;
&lt;br /&gt;
How to hide console window in python? - http://stackoverflow.com/questions/764631/how-to-hide-console-window-in-python&lt;br /&gt;
* &amp;quot;Simply save it with a .pyw extension. This will prevent the console window from opening. Explanation at the bottom of section [http://docs.python.org/2/tutorial/interpreter.html#executable-python-scripts]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== 32bit vs 64bit ===&lt;br /&gt;
&lt;br /&gt;
IDLE:&lt;br /&gt;
&lt;br /&gt;
32bit:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
C:\Python27&amp;gt;python&lt;br /&gt;
Python 2.7.6 (default, Nov 10 2013, 19:24:18) [MSC v.1500 32 bit (Intel)] on win32&lt;br /&gt;
Type &amp;quot;help&amp;quot;, &amp;quot;copyright&amp;quot;, &amp;quot;credits&amp;quot; or &amp;quot;license&amp;quot; for more information.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
64bit: (note: default path is C:\Python27)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
C:\Python27-64bit&amp;gt;python.exe&lt;br /&gt;
Python 2.7.6 (default, Nov 10 2013, 19:24:24) [MSC v.1500 64 bit (AMD64)] on win32&lt;br /&gt;
Type &amp;quot;help&amp;quot;, &amp;quot;copyright&amp;quot;, &amp;quot;credits&amp;quot; or &amp;quot;license&amp;quot; for more information.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Task Manager:&lt;br /&gt;
 python.exe *32&lt;br /&gt;
&lt;br /&gt;
 python.exe&lt;br /&gt;
&lt;br /&gt;
Platform:&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; import platform&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; platform.python_compiler()&lt;br /&gt;
 &#039;MSC v.1500 32 bit (Intel)&#039;&lt;br /&gt;
&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; import platform&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; platform.python_compiler()&lt;br /&gt;
 &#039;MSC v.1500 64 bit (AMD64)&#039;&lt;br /&gt;
&lt;br /&gt;
Code: [http://stackoverflow.com/questions/2208828/detect-64bit-os-windows-in-python]&lt;br /&gt;
 import struct&lt;br /&gt;
 def is_python_64bit():&lt;br /&gt;
     return (struct.calcsize(&amp;quot;P&amp;quot;) == 8)&lt;br /&gt;
&lt;br /&gt;
=== Stand-Alone Executable ===&lt;br /&gt;
&lt;br /&gt;
==== Python ZIP Application ====&lt;br /&gt;
&lt;br /&gt;
Python can be run from a single bundled zip file - similar to a Java WAR!  Python has been able to (Allow interpreter to execute a zip file http://bugs.python.org/issue1739468)&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Python quietly added a new feature in 2.6 that makes it possible to bundle up a directory full of Python code into a single executable file.&amp;quot; [http://blog.ablepear.com/2012/10/bundling-python-files-into-stand-alone.html]&lt;br /&gt;
&lt;br /&gt;
When a python zip application is executed, it will execute &#039;__main__.py&#039; [http://docs.python.org/using/cmdline.html#interface-options]&lt;br /&gt;
&lt;br /&gt;
 mkdir app&lt;br /&gt;
 touch app/__main__.py&lt;br /&gt;
 cd app&lt;br /&gt;
 zip -r ../app.zip *&lt;br /&gt;
 cd ..&lt;br /&gt;
 python app.zip&lt;br /&gt;
&lt;br /&gt;
Load a resource - The easiest way to find and load a program bundle like this is to use the pkg_resources module. - http://packages.python.org/distribute/pkg_resources.html&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# file: app/__main__.py&lt;br /&gt;
&lt;br /&gt;
import pkg_resources&lt;br /&gt;
&lt;br /&gt;
def main():&lt;br /&gt;
  print(&#039;The rain in Spain falls mainly in the plain.&#039;)&lt;br /&gt;
  print(pkg_resources.resource_string(&#039;resources&#039;, &#039;inFrance.txt&#039;))&lt;br /&gt;
&lt;br /&gt;
if __name__ == &#039;__main__&#039;:&lt;br /&gt;
  main()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now use a bit of UNIX magic to turn app2.zip into an executable:&lt;br /&gt;
 echo &#039;#!/usr/bin/env python&#039; | cat - app2.zip &amp;gt; app2&lt;br /&gt;
 chmod +x app2&lt;br /&gt;
&lt;br /&gt;
&amp;quot;The zip file format is designed to allow a small executable program to be inserted at the front (that&#039;s how self-extracting zip files are created), so this is kosher and doesn&#039;t corrupt the zip file.&amp;quot; [http://blog.ablepear.com/2012/10/bundling-python-files-into-stand-alone.html]&lt;br /&gt;
&lt;br /&gt;
Now you can simply run app2 like any executable.&lt;br /&gt;
 $ ./app2&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* Able Pear Software: Bundling Python files into a stand-alone executable - http://blog.ablepear.com/2012/10/bundling-python-files-into-stand-alone.html&lt;br /&gt;
* PEP 441 -- Improving Python ZIP Application Support - http://www.python.org/dev/peps/pep-0441/&lt;br /&gt;
* Issue 1739468: Allow interpreter to execute a zip file - Python tracker - http://bugs.python.org/issue1739468&lt;br /&gt;
* Package Discovery and Resource Access using pkg_resources — Distribute documentation - http://packages.python.org/distribute/pkg_resources.html&lt;br /&gt;
&lt;br /&gt;
==== Shell Python Loader ====&lt;br /&gt;
&lt;br /&gt;
Came before the Python ZIP Application support.&lt;br /&gt;
&lt;br /&gt;
Python zip exe - Noah.org - http://www.noah.org/wiki/Python_zip_exe&lt;br /&gt;
&lt;br /&gt;
&amp;quot;This takes your Python application and packages it into a single executable shell script. You application can be made of up multiple python scripts. The executable shell script is also compressed, so the resulting script is smaller than the original. This should work on any system that has Python and a Bourne shell (works on Cygwin too). Note that this does not package the Python interpreter into the executable. This packages only you python code into a zip file, but this still allows you to distribute your application as a single shell script that will run on any system with Python installed.  In theory, you could zip the .pyc files, but the byte code is guaranteed to run only on exactly the same version Python interpreter (including minor version). It is safer to just package the .py files.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
First you need to zip all your python files:&lt;br /&gt;
 zip main.zip main.py spam.py eggs.py&lt;br /&gt;
&lt;br /&gt;
zipheader.sh:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/sh&lt;br /&gt;
# This is a self-extracting executable.&lt;br /&gt;
# Execute this like any normal executable.&lt;br /&gt;
# You may need to &amp;quot;chmod a+x&amp;quot; this file.&lt;br /&gt;
# This is a binary ZIP file with a Python loader header.&lt;br /&gt;
#&lt;br /&gt;
# Bourne shell loader:&lt;br /&gt;
PYTHON=$(which python 2&amp;gt;/dev/null)&lt;br /&gt;
if [ ! -x &amp;quot;$PYTHON&amp;quot; ] ; then&lt;br /&gt;
    echo &amp;quot;Python not found!&amp;quot;&lt;br /&gt;
    exit 1&lt;br /&gt;
fi&lt;br /&gt;
exec $PYTHON -c &amp;quot;&lt;br /&gt;
# Python loader:&lt;br /&gt;
import sys, os&lt;br /&gt;
if int(sys.version[0])&amp;lt;2:&lt;br /&gt;
    print &#039;Python version 2.3 final or greater is required.&#039;&lt;br /&gt;
    print &#039;Your version is&#039;, sys.version&lt;br /&gt;
    os._exit(1)&lt;br /&gt;
major = sys.version_info[0]&lt;br /&gt;
minor = sys.version_info[1]&lt;br /&gt;
releaselevel = sys.version_info[3]&lt;br /&gt;
if (major==2 and minor&amp;lt;3) or (major==2 and minor==3 and releaselevel!=&#039;final&#039;):&lt;br /&gt;
    print &#039;Python version 2.3 final or greater is required.&#039;&lt;br /&gt;
    print &#039;Your version is&#039;, sys.version&lt;br /&gt;
    os._exit(1)&lt;br /&gt;
sys.path.insert(0, sys.argv[1])&lt;br /&gt;
del sys.argv[0:1]&lt;br /&gt;
import main&lt;br /&gt;
main.main()&lt;br /&gt;
&amp;quot; $0 $@&lt;br /&gt;
# Zip file:&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Concatinate zipheader.sh with the zip file.&lt;br /&gt;
 cat zipheader.sh main.zip &amp;gt; main&lt;br /&gt;
&lt;br /&gt;
Set main as executable.&lt;br /&gt;
 chmod +x main&lt;br /&gt;
&lt;br /&gt;
&amp;quot;This is an improvement on Joerg Raedler&#039;s Python recipe, [http://code.activestate.com/recipes/215301-binding-main-skript-and-modules-to-one-executable-/ 215301]. The original closes stdin. The herefile in the shell script redirects stdin before python gets a chance to start. This disables raw_input() and anything else that reads sys.stdin. Unfortunately, Raedler&#039;s boot script closes stdin, which is a fairly big limitation. The herefile in the shell script (END_OF_PYTHON_CODE) redirects stdin before python starts; stdin is closed at the end of the herefile. This disables raw_input() and anything else that reads sys.stdin. &amp;quot;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* Python zip exe - Noah.org - http://www.noah.org/wiki/Python_zip_exe&lt;br /&gt;
* Build a compressed self-extracting executable script on UNIX « Python recipes « ActiveState Code - http://code.activestate.com/recipes/497000-build-a-compressed-self-extracting-executable-scri/&lt;br /&gt;
* binding main skript and modules to one executable with python-2.3 under UNIX « Python recipes « ActiveState Code - http://code.activestate.com/recipes/215301-binding-main-skript-and-modules-to-one-executable-/&lt;br /&gt;
&lt;br /&gt;
==== py2exe ====&lt;br /&gt;
&lt;br /&gt;
py2exe - http://www.py2exe.org/&lt;br /&gt;
: &amp;quot;py2exe is a Python Distutils extension which converts Python scripts into executable Windows programs, able to run without requiring a Python installation. &amp;quot;&lt;br /&gt;
&lt;br /&gt;
Tutorial - http://www.py2exe.org/index.cgi/Tutorial&lt;br /&gt;
&lt;br /&gt;
Note: Install the version that matches your version of python&lt;br /&gt;
&lt;br /&gt;
Note: run installer &amp;quot;as administrator&amp;quot;&lt;br /&gt;
&lt;br /&gt;
setup.py&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from distutils.core import setup&lt;br /&gt;
import py2exe&lt;br /&gt;
&lt;br /&gt;
setup(console=[&#039;hello.py&#039;])&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
No console window version: [http://ubuntuforums.org/showthread.php?t=728170] [http://stackoverflow.com/questions/3275293/hiding-console-window-of-python-gui-app-with-py2exe]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from distutils.core import setup&lt;br /&gt;
import py2exe&lt;br /&gt;
&lt;br /&gt;
setup(windows=[&#039;hello.py&#039;])&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Build:&lt;br /&gt;
 python setup.py py2exe&lt;br /&gt;
&lt;br /&gt;
pygame is more complex: http://www.pygame.org/wiki/Pygame2exe&lt;br /&gt;
&lt;br /&gt;
==== py2app ====&lt;br /&gt;
&lt;br /&gt;
==== pyinstaller ====&lt;br /&gt;
&lt;br /&gt;
==== cx_Freeze ====&lt;br /&gt;
&lt;br /&gt;
=== Windows Libraries ===&lt;br /&gt;
&lt;br /&gt;
==== Python for Windows Extensions - PyWin32 ====&lt;br /&gt;
&lt;br /&gt;
Python for Windows Extensions - http://starship.python.net/~skippy/win32/&lt;br /&gt;
* There is a build for each python version and architecture (32bit vs 64bit)&lt;br /&gt;
&lt;br /&gt;
Follow event viewer&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import win32evtlog  # install Python for Windows Extensions - http://starship.python.net/~skippy/win32/&lt;br /&gt;
&lt;br /&gt;
# open event viewer&lt;br /&gt;
server = &amp;quot;localhost&amp;quot;&lt;br /&gt;
source = &amp;quot;System&amp;quot;&lt;br /&gt;
handle = win32evtlog.OpenEventLog(server, source)&lt;br /&gt;
&lt;br /&gt;
# seek to end of log&lt;br /&gt;
flags = win32evtlog.EVENTLOG_BACKWARDS_READ | win32evtlog.EVENTLOG_SEQUENTIAL_READ&lt;br /&gt;
events = win32evtlog.ReadEventLog(handle, flags, 0)&lt;br /&gt;
&lt;br /&gt;
# return to normal reading direction&lt;br /&gt;
flags = win32evtlog.EVENTLOG_FORWARDS_READ | win32evtlog.EVENTLOG_SEQUENTIAL_READ&lt;br /&gt;
win32evtlog.ReadEventLog(handle, flags, 0)  # ignore initial logs&lt;br /&gt;
&lt;br /&gt;
# loop through events&lt;br /&gt;
while True:&lt;br /&gt;
    events = win32evtlog.ReadEventLog(handle, flags, 0)&lt;br /&gt;
    if events:&lt;br /&gt;
        for event in events:&lt;br /&gt;
            data = event.StringInserts&lt;br /&gt;
            if data:&lt;br /&gt;
                # Example: 07/03/14 12:34:35 - MYEVENTSOURCE - 0 - 1 - 4  &amp;quot;HELLO&amp;quot;&lt;br /&gt;
                print event.TimeGenerated, &#039;-&#039;, event.SourceName, &#039;-&#039;, event.EventCategory, &#039;-&#039;, event.EventID, &#039;-&#039;, event.EventType, &#039;-&#039;, &#039;&amp;quot;%s&amp;quot;&#039; % &amp;quot; &amp;quot;.join(data)&lt;br /&gt;
    time.sleep(.5)  # yield cpu&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* PyWin32: Getting Windows Event Logs « The Mouse Vs. The Python - http://www.blog.pythonlibrary.org/2010/07/27/pywin32-getting-windows-event-logs/&lt;br /&gt;
&lt;br /&gt;
==== PyCrypto for Windows ====&lt;br /&gt;
&lt;br /&gt;
Download Install: http://www.voidspace.org.uk/python/modules.shtml#pycrypto&lt;br /&gt;
&lt;br /&gt;
Installation: [http://stackoverflow.com/questions/11405549/how-do-i-install-pycrypto-on-windows]&lt;br /&gt;
 easy_install http://www.voidspace.org.uk/downloads/pycrypto26/pycrypto-2.6.win32-py2.7.exe&lt;br /&gt;
 easy_install http://www.voidspace.org.uk/downloads/pycrypto26/pycrypto-2.6.win-amd64-py2.7.exe&lt;br /&gt;
&lt;br /&gt;
==== Paramiko for Windows ====&lt;br /&gt;
&lt;br /&gt;
# Install PyCrypto (above)&lt;br /&gt;
# pip install paramiko&lt;br /&gt;
&lt;br /&gt;
==== PyGame for Windows ====&lt;br /&gt;
&lt;br /&gt;
Download - http://www.pygame.org/download.shtml&lt;br /&gt;
* http://pygame.org/ftp/pygame-1.9.1.win32-py2.7.msi&lt;br /&gt;
&lt;br /&gt;
== Indentation ==&lt;br /&gt;
&lt;br /&gt;
Python: Myths about Indentation - http://www.secnetix.de/olli/Python/block_indentation.hawk&lt;br /&gt;
:There are quite some prejudices and myths about Python&#039;s indentation rules among people who don&#039;t really know Python. I&#039;ll try to address a few of these concerns on this page. &lt;br /&gt;
*&amp;quot;Whitespace is significant in Python source code.&amp;quot;&lt;br /&gt;
*&amp;quot;Python forces me to use a certain indentation style.&amp;quot;&lt;br /&gt;
*&amp;quot;You cannot safely mix tabs and spaces in Python.&amp;quot;&lt;br /&gt;
*&amp;quot;I just don&#039;t like it.&amp;quot;&lt;br /&gt;
*&amp;quot;How does the compiler parse the indentation?&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== PEP - Python Enhancement Proposals ==&lt;br /&gt;
&lt;br /&gt;
Python Enhancement Proposals (PEPs)&lt;br /&gt;
&lt;br /&gt;
* Index of Python Enhancement Proposals (PEPs) - http://www.python.org/dev/peps/&lt;br /&gt;
&lt;br /&gt;
== Convert Tabs to Spaces ==&lt;br /&gt;
&lt;br /&gt;
Convert tabs to 4 spaces:&lt;br /&gt;
 sed -i &#039;s/\t/    /g&#039;  script.py&lt;br /&gt;
&lt;br /&gt;
== Linting ==&lt;br /&gt;
&lt;br /&gt;
* pep8 - python style guide checker&lt;br /&gt;
* pychecker - more verbose, imports code, slower&lt;br /&gt;
* pylint - most verbose, configurable, &amp;quot;rates&amp;quot; code&lt;br /&gt;
* pyflakes - least verbose (dead/redundant code)&lt;br /&gt;
&lt;br /&gt;
rpmforge:&lt;br /&gt;
 yum install pyflakes pychecker&lt;br /&gt;
 # pylint - not sure which pacakge includes&lt;br /&gt;
&lt;br /&gt;
=== pep8 ===&lt;br /&gt;
&lt;br /&gt;
See [[Python/pep8]]&lt;br /&gt;
&lt;br /&gt;
=== pychecker ===&lt;br /&gt;
&lt;br /&gt;
See [[Python/pychecker]]&lt;br /&gt;
&lt;br /&gt;
=== pylint ===&lt;br /&gt;
&lt;br /&gt;
See [[Python/pylint]]&lt;br /&gt;
&lt;br /&gt;
== PEP8 Style Guidlines ==&lt;br /&gt;
&lt;br /&gt;
PEP 8 -- Style Guide for Python Code - http://www.python.org/dev/peps/pep-0008/&lt;br /&gt;
&lt;br /&gt;
* Use spaces - Use 4 spaces per indentation level.&lt;br /&gt;
* Never mix tabs and spaces.&lt;br /&gt;
* Limit all lines to a maximum of 79 characters.&lt;br /&gt;
* Line wrapping - The preferred way of wrapping long lines is by using Python&#039;s implied line continuation inside parentheses, brackets and braces.  Long lines can be broken over multiple lines by wrapping expressions in parentheses.&lt;br /&gt;
* Encoding - For Python 3.0 and beyond, UTF-8 is preferred over Latin-1, see PEP 3120.&lt;br /&gt;
* Imports should usually be on separate lines&lt;br /&gt;
* Avoid extraneous whitespace in most situations&lt;br /&gt;
* Always use &#039;self&#039; for the first argument to instance methods.&lt;br /&gt;
&lt;br /&gt;
=== PEP8 Style Checker ===&lt;br /&gt;
&lt;br /&gt;
See [[#pep8]]&lt;br /&gt;
&lt;br /&gt;
== Benefits of Python ==&lt;br /&gt;
&lt;br /&gt;
What is the return on investment for this group by learning Python? The list of benefits below sums up what the language has to offer:&lt;br /&gt;
* Python is designed from the ground up to encourage maintainable, readable and reusable code. It has great support for particular paradigms such as object-oriented programming.&lt;br /&gt;
* Python code is usually around a quarter of the length of code generated by C++ or Java - less typing, less debugging and less maintenance.&lt;br /&gt;
* Python does not need to be compiled or linked, which allows for a more iterative programming style and a quicker development cycle.&lt;br /&gt;
* Python is extremely portable. Code can be easily exchanged between Windows, Mac OS and Linux with little to no modification.&lt;br /&gt;
* Python comes with a staggering array of standard libraries and mature third-party projects. Web development, scientific computing, operator system access and network scripting are all supported.&lt;br /&gt;
* Python can talk with many other languages easily. It has support for invoking C and C++ code and can itself be called from libraries written in these languages. &lt;br /&gt;
&lt;br /&gt;
Source: http://quantstart.com/articles/Quant-Reading-List-Python-Programming/ - Quant Reading List Python Programming&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Benefits of Python:&lt;br /&gt;
* Python is available for most operating systems, including Windows, UNIX, Linux, and Mac OS.&lt;br /&gt;
* Python&#039;s clean object-oriented design and extensive support libraries offer two to ten fold the programmer productivity seen with languages like C, C++, C#, Java, VB, and Perl.&lt;br /&gt;
&lt;br /&gt;
Source: Python Development - Benefits of Python - Digital Mesh - http://www.digitalmesh.com/offshore-development-center/python-development/benefits-of-python.html&lt;br /&gt;
&lt;br /&gt;
== Python Package Management ==&lt;br /&gt;
&lt;br /&gt;
=== Install Module ===&lt;br /&gt;
&lt;br /&gt;
Installing Python Modules — Python v2.7.1 documentation - http://docs.python.org/install/index.html&lt;br /&gt;
&lt;br /&gt;
The new standard: Distutils&lt;br /&gt;
 python setup.py install&lt;br /&gt;
&lt;br /&gt;
Download and extract target package, then:&lt;br /&gt;
 sudo python setup.py install&lt;br /&gt;
&lt;br /&gt;
Note: Running setup.py install builds and installs all modules in one run&lt;br /&gt;
&lt;br /&gt;
Help:&lt;br /&gt;
 python setup.py --help&lt;br /&gt;
&lt;br /&gt;
Incremental method:&lt;br /&gt;
 python setup.py build&lt;br /&gt;
 python setup.py install&lt;br /&gt;
 python setup.py build --help   # help&lt;br /&gt;
&lt;br /&gt;
Force rebuild and install:&lt;br /&gt;
 python setup.py build --force    # if have to repeat&lt;br /&gt;
 python setup.py install --force  # if have to repeat&lt;br /&gt;
&lt;br /&gt;
Default installation paths:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Platform	Standard installation location		Default value&lt;br /&gt;
Unix (pure)	prefix/lib/pythonX.Y/site-packages	/usr/local/lib/pythonX.Y/site-packages&lt;br /&gt;
Unix (non-pure)	exec-prefix/lib/pythonX.Y/site-packages	/usr/local/lib/pythonX.Y/site-packages&lt;br /&gt;
Windows		prefix					C:\Python&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alternate install path:&lt;br /&gt;
 python setup.py install --home=&amp;lt;dir&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alternate base folders:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Type of file			Installation Directory	Override option&lt;br /&gt;
pure module distribution	home/lib/python		--install-purelib&lt;br /&gt;
non-pure module distribution	home/lib/python		--install-platlib&lt;br /&gt;
scripts				home/bin		--install-scripts&lt;br /&gt;
data				home/share		--install-data&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Modifying Python’s Search Path:&lt;br /&gt;
 import sys&lt;br /&gt;
 sys.path.append(&#039;/www/python/&#039;)&lt;br /&gt;
&lt;br /&gt;
=== Python Package Index ===&lt;br /&gt;
&lt;br /&gt;
user-submitted Python packages:&lt;br /&gt;
 http://pypi.python.org/pypi&lt;br /&gt;
&lt;br /&gt;
 sudo python setup.py install&lt;br /&gt;
&lt;br /&gt;
Package Site:&lt;br /&gt;
 http://pypi.python.org/pypi/[PACKAGE]&lt;br /&gt;
 http://pypi.python.org/pypi/test&lt;br /&gt;
&lt;br /&gt;
If they are on http://pypi.python.org/:&lt;br /&gt;
 pip install foo&lt;br /&gt;
&lt;br /&gt;
[http://stackoverflow.com/questions/410163/for-python-programmers-is-there-anything-equivalent-to-perls-cpan For Python programmers, is there anything equivalent to Perl&#039;s CPAN? - Stack Overflow]&lt;br /&gt;
&lt;br /&gt;
=== Easy Installation ===&lt;br /&gt;
&lt;br /&gt;
EasyInstall - The PEAK Developers&#039; Center - http://peak.telecommunity.com/DevCenter/EasyInstall&lt;br /&gt;
: Easy Install is a python module (easy_install) bundled with setuptools that lets you automatically download, build, install, and manage Python packages.&lt;br /&gt;
&lt;br /&gt;
CheeseShopTutorial - PythonInfo Wiki - http://wiki.python.org/moin/CheeseShopTutorial&lt;br /&gt;
: EasyInstall (easy_install) gives you a quick and painless way to install packages remotely by connecting to the Package Index or even other websites via HTTP. It is somewhat analogous to the CPAN and PEAR tools for Perl and PHP, respectively.&lt;br /&gt;
&lt;br /&gt;
=== pip ===&lt;br /&gt;
&lt;br /&gt;
See [[Python/pip]]&lt;br /&gt;
&lt;br /&gt;
==== Create PIP Package ====&lt;br /&gt;
&lt;br /&gt;
See [[Python/pip#Create PIP Package]]&lt;br /&gt;
&lt;br /&gt;
=== Distribute ===&lt;br /&gt;
&lt;br /&gt;
distribute - Easily download, build, install, upgrade, and uninstall Python packages&lt;br /&gt;
&lt;br /&gt;
distribute 0.6.24 : Python Package Index - http://pypi.python.org/pypi/distribute&lt;br /&gt;
&lt;br /&gt;
Installation:&lt;br /&gt;
 mkdir -p ~/.src ; cd ~/.src&lt;br /&gt;
 wget http://pypi.python.org/packages/source/d/distribute/distribute-0.6.24.tar.gz#md5=17722b22141aba8235787f79800cc452&lt;br /&gt;
 tar -zvxf distribute-0.6.24.tar.gz&lt;br /&gt;
 cd distribute-0.6.24&lt;br /&gt;
 sudo python setup.py install&lt;br /&gt;
&lt;br /&gt;
Test:&lt;br /&gt;
 echo &amp;quot;import distribute&amp;quot; | grep python&lt;br /&gt;
&lt;br /&gt;
== Named Parameters ==&lt;br /&gt;
&lt;br /&gt;
http://diveintopython.org/power_of_introspection/optional_arguments.html&lt;br /&gt;
&lt;br /&gt;
Python allows function arguments to have default values; if the function is called without the argument, the argument gets its default value. Futhermore, arguments can be specified in any order by using named arguments. Stored procedures in SQL Server Transact/SQL can do this, so if you&#039;re a SQL Server scripting guru, you can skim this part.&lt;br /&gt;
&lt;br /&gt;
Here is an example of info, a function with two optional arguments:&lt;br /&gt;
&lt;br /&gt;
 def info(object, spacing=10, collapse=1):&lt;br /&gt;
&lt;br /&gt;
spacing and collapse are optional, because they have default values defined. object is required, because it has no default value. If info is called with only one argument, spacing defaults to 10 and collapse defaults to 1. If info is called with two arguments, collapse still defaults to 1.&lt;br /&gt;
&lt;br /&gt;
Say you want to specify a value for collapse but want to accept the default value for spacing. In most languages, you would be out of luck, because you would need to call the function with three arguments. But in Python, arguments can be specified by name, in any order. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
http://www.wellho.net/mouth/1871_Optional-and-named-parameters-in-Python.html&lt;br /&gt;
&lt;br /&gt;
If you add a parameter with two asterixes (**) on the end of a function definition, that parameter is taken as being the name of a dictionary into which all otherwise unidentified parameters are stored. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def getnet(gross, taxrate=17.5, **others):&lt;br /&gt;
  net = gross / (1.0 + taxrate*0.01)&lt;br /&gt;
  for more in others.keys():&lt;br /&gt;
    print &amp;quot;GETNET:&amp;quot;,more,&amp;quot; - &amp;quot;,others[more]&lt;br /&gt;
  return neto&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Python vs other languages ==&lt;br /&gt;
&lt;br /&gt;
[http://www.strombergers.com/python/ Python is Cool (and Perl is not), Especially for C/C++ Programmers]&lt;br /&gt;
&lt;br /&gt;
==Experimenting with Memory Remanence==&lt;br /&gt;
[http://citp.princeton.edu/memory/exp/ Experimenting with Memory Remanence]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    #!/usr/bin/env python&lt;br /&gt;
&lt;br /&gt;
    # a pirate&#039;s favorite chemical element&lt;br /&gt;
    a = &amp;quot;&amp;quot;&lt;br /&gt;
    while 1: a += &amp;quot;ARGON&amp;quot; &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 sudo strings /dev/mem | less&lt;br /&gt;
&lt;br /&gt;
==UTOSC 2008 - 90 percent of the Python you need to know (in 90 minutes)==&lt;br /&gt;
See [[UTOSC 2008 - 90 percent of the Python you need to know (in 90 minutes)]]&lt;br /&gt;
&lt;br /&gt;
== Program Layout Best Practices Presentation ==&lt;br /&gt;
&lt;br /&gt;
Program layout best practices - Seth House &amp;lt;seth@eseth.com&amp;gt; - Utah Django User Group - 2011-06-23&lt;br /&gt;
* Slides - https://github.com/whiteinge/presentations/tree/master/upyug_2011-06-09_program-layout&lt;br /&gt;
* Video - http://blip.tv/utah-open-source/python-layout-best-practices-for-modules-django-cli-utah-django-user-group-5315808&lt;br /&gt;
&lt;br /&gt;
Module skeleton:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
# coding: utf-8&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;Module docstring&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
__author__ = ’Mr. Me &amp;lt;me@example.net&amp;gt;’&lt;br /&gt;
__version__ = ’1.2.3’&lt;br /&gt;
&lt;br /&gt;
if __name__==’__main__’:&lt;br /&gt;
 main()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Executing modules as scripts&lt;br /&gt;
 # PEP 338:&lt;br /&gt;
 python -m SimpleHTTPServer&lt;br /&gt;
&lt;br /&gt;
== CLI package ==&lt;br /&gt;
&lt;br /&gt;
cli — command line tools — pyCLI v1.1.1 documentation - http://packages.python.org/pyCLI/&lt;br /&gt;
&lt;br /&gt;
== Python IDE ==&lt;br /&gt;
&lt;br /&gt;
IntegratedDevelopmentEnvironments - PythonInfo Wiki - http://wiki.python.org/moin/IntegratedDevelopmentEnvironments&lt;br /&gt;
* IDEs with introspection-based code completion and integrated debugger&lt;br /&gt;
* IDEs with introspection-based code completion /or/ integrated debugger&lt;br /&gt;
* IDEs with integrated gui builder&lt;br /&gt;
* Editors&lt;br /&gt;
* Reviews&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Is there a good, free Python IDE for Windows? - Stack Overflow - http://stackoverflow.com/questions/126753/is-there-a-good-free-python-ide-for-windows&lt;br /&gt;
* Eclipse with PyDev&lt;br /&gt;
* Aptana Studio 3&lt;br /&gt;
* Active State also offers Komodo Edit&lt;br /&gt;
* WingWare - http://www.wingware.com/&lt;br /&gt;
* Eric IDE - http://www.die-offenbachs.de/eric/index.html&lt;br /&gt;
* MMM-Experts - Products - http://mmm-experts.com/Products.aspx?ProductId=4&lt;br /&gt;
** PyScripter is a Python IDE built in Python for Delphi(P4D) components and created with the ambition to become competitive in functionality with commercial Windows-based IDEs available for other languages. Being built in a compiled language is rather snappier than some of the other Python IDEs and provides an extensive blend of features that make it a productive Python development environment. &lt;br /&gt;
* ActiveState Python comes with PythonWin which is reasonably good&lt;br /&gt;
* PyCharm from JetBrains is not free in general, but has free early access program.&lt;br /&gt;
* SPE - Stani&#039;s Python Editor, is pretty awesome. See http://pythonide.blogspot.com/.&lt;br /&gt;
* You may want to take a look at the pdb module - http://docs.python.org/lib/module-pdb.html&lt;br /&gt;
* Geany (http://www.geany.org/) is a fairly light text editor that does a lot of IDE-like stuff.&lt;br /&gt;
* SciTE: http://www.scintilla.org/SciTE.html&lt;br /&gt;
* Editra: http://editra.org/ &lt;br /&gt;
* Netbeans has support for python development in their Python Early Access version. - http://www.netbeans.org/features/python/&lt;br /&gt;
* I use Notepad++ with the appropriate settings.&lt;br /&gt;
* The Eric Python IDE - http://www.die-offenbachs.de/eric/index.html&lt;br /&gt;
* BOa Constructor www.boa-constructor.sourceforge.net really nice! drag and drop stuff!&lt;br /&gt;
* DrPtyhon is also very nice, and has many plug-ins. http://drpython.sourceforge.net/&lt;br /&gt;
* Vim&lt;br /&gt;
* I will make a plug for my preference of Python development environments: SPE. SPE is an integrated development environment that provides code completion, integrated Python shell, calltips, and various helper tools like notes and todo lists. It also includes wxGlade so you can make wxPython applications easily. Plus, it includes the python debugger WinPdb.&lt;br /&gt;
* http://groups.google.com.tr/group/python_opengl this software is my sample visual python ide.its demo version.&lt;br /&gt;
* I use PyScripter, and find it pretty awesome.&lt;br /&gt;
* There is one Python IDE written in Java: jHepWork: http://jwork.org/jhepwork/ it can detect Python&#039;s indentation rules rather nicely (+ detects structure of a code and syntax)&lt;br /&gt;
* gvim built with your python version support and with this plugins:&lt;br /&gt;
** NERDTree (don&#039;t read he&#039;s blog ;)&lt;br /&gt;
** matchit (it&#039;s builtin in new versions just put a symlink or junction)&lt;br /&gt;
** pyflakes&lt;br /&gt;
** pysmell&lt;br /&gt;
* Try Python Tools for Visual Studio. Supports CPython and IronPython. - http://pytools.codeplex.com/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
PythonEditors - PythonInfo Wiki - http://wiki.python.org/moin/PythonEditors&lt;br /&gt;
* List of editors&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Python Ide - http://c2.com/cgi/wiki?PythonIde&lt;br /&gt;
: There are a lot of Ides for PythonLanguage springing up. Many of them written in Python &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Is there a better Python IDE? « Lennart Regebro: Python, Plone, Web - http://regebro.wordpress.com/2010/10/09/is-there-a-better-python-ide/&lt;br /&gt;
: I’m currently a user of WingIDE, but sometimes I feel the need for something better, mainly something that is a bit more stable. WingIDE often hangs when switching projects, sometimes the file listing decides that you must double-click on the expand arrow instead of just click on it, etc. It still doesn’t have macros despite this being a much requested feature (how hard can it be to add, really?) and I never really get the hang of the SVN integration, so I just ignore it. And they keep recommending me to use WingIDE’s separate instance of GTK instead of the System GTK, which is daft. Their designs are ugly, and it should work with the system GTK so it looks the same. Anything else is just silly.&lt;br /&gt;
&lt;br /&gt;
=== Open Komodo ===&lt;br /&gt;
&lt;br /&gt;
Open Komodo - http://www.openkomodo.com/&lt;br /&gt;
: Open Komodo is the source code repository for Komodo Edit - a free multi-language editor for dynamic languages, based on the award-winning Komodo IDE. ActiveState created the Open Komodo code repository in August 2007 and it has been used since then for building all Komodo Edit releases.&lt;br /&gt;
&lt;br /&gt;
=== Eclipse ===&lt;br /&gt;
&lt;br /&gt;
Build an Eclipse development environment for Perl, Python, and PHP - http://www.eclipse.org/resources/resource.php?id=485&lt;br /&gt;
: This tutorial shows how Eclipse&#039;s DLTK makes it possible to build development tools for scripting languages. In particular, it explains how to implement syntax coloring, user preferences, and interpreter integration in a plug-in-based project.&lt;br /&gt;
&lt;br /&gt;
See [[#PyDev]]&lt;br /&gt;
&lt;br /&gt;
=== EasyEclipse ===&lt;br /&gt;
&lt;br /&gt;
EasyEclipse - http://www.easyeclipse.org/&lt;br /&gt;
:EasyEclipse packages together Eclipse, the open-source software&lt;br /&gt;
development platform, and selected open source plugins.&lt;br /&gt;
:We select, assemble, test, patch, build installers and document&lt;br /&gt;
a full IDE, offered as reliable distributions and plugins.&lt;br /&gt;
:EasyEclipse is:&lt;br /&gt;
* Free and open-source,&lt;br /&gt;
* Easy to download and install, and&lt;br /&gt;
* Simple to maintain, without version and dependency issues.&lt;br /&gt;
&lt;br /&gt;
EasyEclipse for Python - http://www.easyeclipse.org/site/distributions/python.html&lt;br /&gt;
&lt;br /&gt;
EclipsePythonIntegration - PythonInfo Wiki - http://wiki.python.org/moin/EclipsePythonIntegration&lt;br /&gt;
: Using Eclipse as a Python editor&lt;br /&gt;
&lt;br /&gt;
=== PyDev ===&lt;br /&gt;
&lt;br /&gt;
PyDev - http://pydev.org/&lt;br /&gt;
: PyDev is a Python IDE for Eclipse, which may be used in Python, Jython and IronPython development.&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
Pydev - http://pydev.sourceforge.net/ (old link)&lt;br /&gt;
&lt;br /&gt;
How to Configure Eclipse for Python - http://www.rose-hulman.edu/class/csse/resources/Eclipse/eclipse-python-configuration.htm&lt;br /&gt;
&lt;br /&gt;
Python Development with PyDev and Eclipse - Tutorial - http://www.vogella.de/articles/Python/article.html&lt;br /&gt;
: This article describes how to write and debug Python programs with Eclipse&lt;br /&gt;
&lt;br /&gt;
PyDev Getting Started - http://pydev.org/manual_101_root.html&lt;br /&gt;
&lt;br /&gt;
Running a program - http://pydev.org/manual_101_run.html&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
Supported Task Tags:&lt;br /&gt;
* TODO:&lt;br /&gt;
* TASK:&lt;br /&gt;
* FIXME:&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
Installation:&lt;br /&gt;
# Platform Runtime Binary (download around 45-50 MB) - http://download.eclipse.org/eclipse/downloads/ or http://www.eclipse.org/downloads/&lt;br /&gt;
#* Example: Eclipse Classic 4.2.2&lt;br /&gt;
# Eclipse Software Add - PyDev: http://pydev.org/updates&lt;br /&gt;
# Eclipse Software Add - MercurialEclipse: http://cbes.javaforge.com/update  [http://javaforge.com/project/HGE] [http://mercurial.selenic.com/wiki/MercurialEclipse]&lt;br /&gt;
# Switch perspectives to PyDev&lt;br /&gt;
&lt;br /&gt;
=== The Eric Python IDE ===&lt;br /&gt;
&lt;br /&gt;
The Eric Python IDE - http://eric-ide.python-projects.org/&lt;br /&gt;
:Eric is a full featured Python and Ruby editor and IDE, written in python. It is based on the cross platform Qt gui toolkit, integrating the highly flexible Scintilla editor control. It is designed to be usable as everdays&#039; quick and dirty editor as well as being usable as a professional project management tool integrating many advanced features Python offers the professional coder. eric4 includes a plugin system, which allows easy extension of the IDE functionality with plugins downloadable from the net.&lt;br /&gt;
&lt;br /&gt;
Eric Python IDE - Wikipedia - http://en.wikipedia.org/wiki/Eric_Python_IDE&lt;br /&gt;
&lt;br /&gt;
=== Wingware Python IDE ===&lt;br /&gt;
&lt;br /&gt;
The Intelligent Development Environment for Python Programmers - Wingware Python IDE - http://www.wingware.com/&lt;br /&gt;
:Wingware&#039;s Python IDE is an Integrated Development Environment designed specifically for the Python programming language. Since 1999, Wingware has focused on Python.&lt;br /&gt;
&lt;br /&gt;
=== VIM ===&lt;br /&gt;
&lt;br /&gt;
Python .vimrc:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;quot; Kenneth&#039;s Preferences&lt;br /&gt;
&lt;br /&gt;
set nobackup            &amp;quot; don&#039;t create backup files&lt;br /&gt;
&amp;quot;set nohlsearch          &amp;quot; don&#039;t highlight search results&lt;br /&gt;
set hlsearch            &amp;quot; do highlight search results&lt;br /&gt;
set incsearch           &amp;quot; incremental search&lt;br /&gt;
set ignorecase          &amp;quot; ignore case during search&lt;br /&gt;
set smartcase           &amp;quot; do case sensitive search when upper case is typed&lt;br /&gt;
set shiftwidth=4        &amp;quot; shift blocks in 4 space increments&lt;br /&gt;
set tabstop=4           &amp;quot; the (typewriter) tab stops are every 4 spaces&lt;br /&gt;
set smarttab            &amp;quot; tab at beginning of line inserts 4 spaces (shiftwidth)&lt;br /&gt;
set showmatch           &amp;quot; briefly highlight matching bracket&lt;br /&gt;
set matchtime=1         &amp;quot; highlight match for 0.1 seconds&lt;br /&gt;
set background=dark     &amp;quot; black background&lt;br /&gt;
set shiftwidth=4        &amp;quot; shift blocks by 4 spaces&lt;br /&gt;
set shortmess=at        &amp;quot; use short messages so we don&#039;t have to hit enter&lt;br /&gt;
set expandtab           &amp;quot; expand tabs into spaces&lt;br /&gt;
set scrolloff=5         &amp;quot; always show 5 lines before &amp;amp; after cursor&lt;br /&gt;
set shell=bash          &amp;quot; use bash for the command shell&lt;br /&gt;
set shellcmdflag=-lc    &amp;quot; make bash startup as a login shell for ~/.bashrc&lt;br /&gt;
&amp;quot;set nowrap              &amp;quot; do not wrap long lines&lt;br /&gt;
set visualbell          &amp;quot; flash the screen rather than beep&lt;br /&gt;
set noerrorbells        &amp;quot; don&#039;t beep on errors&lt;br /&gt;
set wildmenu            &amp;quot; enable filename tab completion&lt;br /&gt;
set ruler               &amp;quot; display the ruler: shows cursor position&lt;br /&gt;
set cpoptions+=$        &amp;quot; display &#039;$&#039; at end of cw sequence&lt;br /&gt;
set title               &amp;quot; display filename and vim info in window title bar&lt;br /&gt;
set modelines=5         &amp;quot; search the first and last 5 lines for &amp;quot;vim:&amp;quot; modeline&lt;br /&gt;
set backspace=2         &amp;quot; backspace deletes&lt;br /&gt;
&lt;br /&gt;
set wildignore=*.o,*.class,*.pyc,*.pyo,*.a,*.so,*.dll,*.exe,core,*.jar,*.zip&lt;br /&gt;
&lt;br /&gt;
&amp;quot;let loaded_matchparen = 1 &amp;quot; don&#039;t highlight parenthesis match&lt;br /&gt;
&lt;br /&gt;
filetype indent on&lt;br /&gt;
&lt;br /&gt;
&amp;quot;if v:version &amp;gt; 700&lt;br /&gt;
&amp;quot;    set cursorline          &amp;quot; underline the current line&lt;br /&gt;
&amp;quot;endif&lt;br /&gt;
&lt;br /&gt;
if &amp;amp;t_Co &amp;gt; 2 || has( &amp;quot;gui_running&amp;quot; )&lt;br /&gt;
    syntax on&lt;br /&gt;
endif&lt;br /&gt;
&lt;br /&gt;
if has( &#039;mouse&#039; )&lt;br /&gt;
    set mouse=a &amp;quot; enable mouse&lt;br /&gt;
endif&lt;br /&gt;
&lt;br /&gt;
if has( &amp;quot;autocmd&amp;quot; )&lt;br /&gt;
    &amp;quot; open the file in the last place we were editing&lt;br /&gt;
    autocmd BufReadPost *&lt;br /&gt;
        \ if line(&amp;quot;&#039;\&amp;quot;&amp;quot;) &amp;gt; 1 &amp;amp;&amp;amp; line(&amp;quot;&#039;\&amp;quot;&amp;quot;) &amp;lt;= line(&amp;quot;$&amp;quot;) |&lt;br /&gt;
        \     exe &amp;quot;normal! g&#039;\&amp;quot;&amp;quot; |&lt;br /&gt;
        \ endif&lt;br /&gt;
endif&lt;br /&gt;
&lt;br /&gt;
&amp;quot;folding settings&lt;br /&gt;
set foldmethod=indent   &amp;quot;fold based on indent&lt;br /&gt;
set foldnestmax=10      &amp;quot;deepest fold is 10 levels&lt;br /&gt;
set nofoldenable        &amp;quot;dont fold by default&lt;br /&gt;
set foldlevel=10        &amp;quot;this is just what i use&lt;br /&gt;
&lt;br /&gt;
&amp;quot; Auto clear trailing white space in Python files&lt;br /&gt;
func! DeleteTrailingWS()&lt;br /&gt;
    exec &amp;quot;normal mz&amp;quot;&lt;br /&gt;
    %s/\s\+$//ge&lt;br /&gt;
    exe &amp;quot;normal `z&amp;quot;&lt;br /&gt;
endfunc&lt;br /&gt;
autocmd BufWrite *.py :call DeleteTrailingWS()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Older versions:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;quot; KENNETH SETTINGS&lt;br /&gt;
set nocp                &amp;quot; turn off compatibility mode&lt;br /&gt;
set nomodeline          &amp;quot; do not allow files to dictate vim behavior&lt;br /&gt;
&lt;br /&gt;
set incsearch           &amp;quot; incremental search&lt;br /&gt;
set ignorecase          &amp;quot; ignore case during search&lt;br /&gt;
&lt;br /&gt;
set visualbell          &amp;quot; flash the screen rather than beep&lt;br /&gt;
set noerrorbells        &amp;quot; don&#039;t beep on errors&lt;br /&gt;
set background=dark     &amp;quot; black background&lt;br /&gt;
syntax on               &amp;quot; turn on syntax highlighting&lt;br /&gt;
set hlsearch            &amp;quot; highligh last search pattern&lt;br /&gt;
&lt;br /&gt;
set nowrap              &amp;quot; do not wrap long lines&lt;br /&gt;
set scrolloff=5         &amp;quot; always show 5 lines before &amp;amp; after cursor&lt;br /&gt;
set ruler               &amp;quot; show the cursor position all the time&lt;br /&gt;
set backspace=2         &amp;quot; allow backspace deletion&lt;br /&gt;
set bs=indent,eol,start &amp;quot; allow backspacing over everything in insert mode&lt;br /&gt;
&lt;br /&gt;
set shiftwidth=4        &amp;quot; shift blocks in 4 space increments&lt;br /&gt;
set tabstop=4           &amp;quot; the (typewriter) tab stops are every 4 spaces&lt;br /&gt;
set expandtab           &amp;quot; expand tab into spaces&lt;br /&gt;
set smarttab            &amp;quot; tab at beginning of line inserts 4 spaces (shiftwidth)&lt;br /&gt;
filetype indent on      &amp;quot; turn on auto indent for specific file types&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Other options:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
set number              &amp;quot; show line numbers&lt;br /&gt;
set numberwidth=1       &amp;quot; remove space before largest line numbers&lt;br /&gt;
&lt;br /&gt;
set smartindent         &amp;quot; ?? - maybe included in &#039;filetype indent on&#039;&lt;br /&gt;
&lt;br /&gt;
set ai                  &amp;quot; always auto indent&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
if has( &amp;quot;autocmd&amp;quot; )&lt;br /&gt;
    &amp;quot; open the file in the last place we were editing&lt;br /&gt;
    autocmd BufReadPost *&lt;br /&gt;
        \ if line(&amp;quot;&#039;\&amp;quot;&amp;quot;) &amp;gt; 1 &amp;amp;&amp;amp; line(&amp;quot;&#039;\&amp;quot;&amp;quot;) &amp;lt;= line(&amp;quot;$&amp;quot;) |&lt;br /&gt;
        \     exe &amp;quot;normal! g&#039;\&amp;quot;&amp;quot; |&lt;br /&gt;
        \ endif&lt;br /&gt;
endif&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Kenneth&#039;s fio .vimrc:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;quot;source $VIM/mswin.vim&lt;br /&gt;
&lt;br /&gt;
set nobackup            &amp;quot; don&#039;t create backup files&lt;br /&gt;
&amp;quot;set nohlsearch          &amp;quot; don&#039;t highlight search results&lt;br /&gt;
set incsearch           &amp;quot; incremental search&lt;br /&gt;
set ignorecase          &amp;quot; ignore case during search&lt;br /&gt;
set smartcase           &amp;quot; do case sensitive search when upper case is typed&lt;br /&gt;
set shiftwidth=4        &amp;quot; shift blocks in 4 space increments&lt;br /&gt;
set tabstop=4           &amp;quot; the (typewriter) tab stops are every 4 spaces&lt;br /&gt;
set smarttab            &amp;quot; tab at beginning of line inserts 4 spaces (shiftwidth)&lt;br /&gt;
set showmatch           &amp;quot; briefly highlight matching bracket&lt;br /&gt;
set matchtime=1         &amp;quot; highlight match for 0.1 seconds&lt;br /&gt;
set background=dark     &amp;quot; black background&lt;br /&gt;
set shiftwidth=4        &amp;quot; shift blocks by 4 spaces&lt;br /&gt;
set shortmess=at        &amp;quot; use short messages so we don&#039;t have to hit enter&lt;br /&gt;
set expandtab           &amp;quot; expand tabs into spaces&lt;br /&gt;
set scrolloff=5         &amp;quot; always show 5 lines before &amp;amp; after cursor&lt;br /&gt;
set shell=bash          &amp;quot; use bash for the command shell&lt;br /&gt;
set shellcmdflag=-lc    &amp;quot; make bash startup as a login shell for ~/.bashrc&lt;br /&gt;
&amp;quot;set nowrap              &amp;quot; do not wrap long lines&lt;br /&gt;
set visualbell          &amp;quot; flash the screen rather than beep&lt;br /&gt;
set noerrorbells        &amp;quot; don&#039;t beep on errors&lt;br /&gt;
set wildmenu            &amp;quot; enable filename tab completion&lt;br /&gt;
set ruler               &amp;quot; display the ruler: shows cursor position&lt;br /&gt;
set cpoptions+=$        &amp;quot; display &#039;$&#039; at end of cw sequence&lt;br /&gt;
set title               &amp;quot; display filename and vim info in window title bar&lt;br /&gt;
set modelines=5         &amp;quot; search the first and last 5 lines for &amp;quot;vim:&amp;quot; modeline&lt;br /&gt;
&lt;br /&gt;
set wildignore=*.o,*.class,*.pyc,*.pyo,*.a,*.so,*.dll,*.exe,core,*.jar,*.zip&lt;br /&gt;
&lt;br /&gt;
&amp;quot;let loaded_matchparen = 1 &amp;quot; don&#039;t highlight parenthesis match&lt;br /&gt;
&lt;br /&gt;
filetype indent on&lt;br /&gt;
&lt;br /&gt;
if v:version &amp;gt; 700&lt;br /&gt;
    set cursorline          &amp;quot; underline the current line&lt;br /&gt;
endif&lt;br /&gt;
&lt;br /&gt;
if &amp;amp;t_Co &amp;gt; 2 || has( &amp;quot;gui_running&amp;quot; )&lt;br /&gt;
    syntax on&lt;br /&gt;
endif&lt;br /&gt;
&lt;br /&gt;
if has( &#039;mouse&#039; )&lt;br /&gt;
    set mouse=a &amp;quot; enable mouse&lt;br /&gt;
endif&lt;br /&gt;
&lt;br /&gt;
if has( &amp;quot;autocmd&amp;quot; )&lt;br /&gt;
    &amp;quot; open the file in the last place we were editing&lt;br /&gt;
    autocmd BufReadPost *&lt;br /&gt;
        \ if line(&amp;quot;&#039;\&amp;quot;&amp;quot;) &amp;gt; 1 &amp;amp;&amp;amp; line(&amp;quot;&#039;\&amp;quot;&amp;quot;) &amp;lt;= line(&amp;quot;$&amp;quot;) |&lt;br /&gt;
        \     exe &amp;quot;normal! g&#039;\&amp;quot;&amp;quot; |&lt;br /&gt;
        \ endif&lt;br /&gt;
endif&lt;br /&gt;
&lt;br /&gt;
&amp;quot;folding settings&lt;br /&gt;
set foldmethod=indent   &amp;quot;fold based on indent&lt;br /&gt;
set foldnestmax=10      &amp;quot;deepest fold is 10 levels&lt;br /&gt;
set nofoldenable        &amp;quot;dont fold by default&lt;br /&gt;
set foldlevel=10        &amp;quot;this is just what i use&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Interpreter vs Script ==&lt;br /&gt;
&lt;br /&gt;
Interpreter:&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; import os&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; os.uname()&lt;br /&gt;
 (&#039;Linux&#039;, &#039;demo.oeey.com&#039;, &#039;2.6.18-194.8.1.el5&#039;, &#039;#1 SMP Thu Jul 1 19:07:06 EDT 2010&#039;, &#039;i686&#039;)&lt;br /&gt;
&lt;br /&gt;
Script:&lt;br /&gt;
 #!/usr/bin/env python&lt;br /&gt;
 import os&lt;br /&gt;
 print os.uname()&lt;br /&gt;
&lt;br /&gt;
== Web Development ==&lt;br /&gt;
&lt;br /&gt;
WebProgramming - PythonInfo Wiki - http://wiki.python.org/moin/WebProgramming&lt;br /&gt;
: This topic guide attempts to cover every aspect of programming Web applications (both clients and servers) using Python. &lt;br /&gt;
&lt;br /&gt;
HOWTO Use Python in the web — Python v2.7.2 documentation - http://docs.python.org/howto/webservers.html&lt;br /&gt;
: This document shows how Python fits into the web. It presents some ways to integrate Python with a web server, and general practices useful for developing web sites.&lt;br /&gt;
&lt;br /&gt;
=== Plug Simple Python Web App ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
-------- Original Message --------&lt;br /&gt;
Subject: 	Re: Writing a simple python web app&lt;br /&gt;
Date: 	Mon, 25 Oct 2010 19:03:31 -0400&lt;br /&gt;
From: 	Roberto Mello &amp;lt;roberto.mello@gmail.com&amp;gt;&lt;br /&gt;
To: 	Provo Linux Users Group &amp;lt;plug@plug.org&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
On Sat, Sep 11, 2010 at 5:40 PM, Dave Smith &amp;lt;dave@thesmithfam.org&amp;gt; wrote:&lt;br /&gt;
&amp;gt; I&#039;m creating a very simple web application, and I want to use python. My first guess was that mod_python&lt;br /&gt;
would provide the easiest entry point. Boy, was I wrong. All the mod_python tutorials spend 80% of their&lt;br /&gt;
time extolling the virtues of mod_python over CGI, but they are quite lean on specific examples. It&#039;s quite&lt;br /&gt;
disappointing. A natural progression then leads me to mod_wsgi, and since that has equally poor&lt;br /&gt;
documentation, to Django. However, Django is overkill for my app (I don&#039;t even have a database).&lt;br /&gt;
&lt;br /&gt;
For something as simple as you have described, and to run on an&lt;br /&gt;
embedded platform, I would probably stay away from frameworks designed&lt;br /&gt;
to run on full hardware, and go with something more minimalistic.&lt;br /&gt;
&lt;br /&gt;
Take a look at CherryPy [1] or web.py [2].&lt;br /&gt;
&lt;br /&gt;
[1] http://www.cherrypy.org/&lt;br /&gt;
[2] http://webpy.org/&lt;br /&gt;
&lt;br /&gt;
Roberto Mello&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
See also [[web.py]]&lt;br /&gt;
&lt;br /&gt;
See also [[CherryPy]]&lt;br /&gt;
&lt;br /&gt;
See also [[Django]]&lt;br /&gt;
&lt;br /&gt;
=== Apache CGI ===&lt;br /&gt;
&lt;br /&gt;
See [[CGI]]&lt;br /&gt;
&lt;br /&gt;
Great tutorial: https://www.tutorialspoint.com/python/python_cgi_programming.htm&lt;br /&gt;
&lt;br /&gt;
My favorite option, make all .cgi files executable: (or .py)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 DirectoryIndex index.html index.php index.py&lt;br /&gt;
 &amp;lt;Location /&amp;gt;&lt;br /&gt;
   # AddHandler cgi-script .cgi&lt;br /&gt;
   AddHandler cgi-script .py&lt;br /&gt;
   Options +ExecCGI &lt;br /&gt;
 &amp;lt;/Location&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you want to allow .htaccess:&lt;br /&gt;
* see [[Apache#.htaccess]]&lt;br /&gt;
&lt;br /&gt;
To enable on Ubuntu:&lt;br /&gt;
 sudo a2enmod cgi&lt;br /&gt;
 service apache2 restart&lt;br /&gt;
&lt;br /&gt;
Directory index:&lt;br /&gt;
 DirectoryIndex index.py&lt;br /&gt;
&lt;br /&gt;
Or if you really want to go crazy, this will try to run *every* file: [http://blog.kapsobor.de/archives/2006/09/05/apache_addhandler_multiple_extensions/]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    # this has problems with / directory being run as a script, instead of index too!&lt;br /&gt;
    #&amp;lt;Location /&amp;gt;&lt;br /&gt;
    #    SetHandler cgi-script&lt;br /&gt;
    #    Options +ExecCGI&lt;br /&gt;
    #&amp;lt;/Location&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;Files ~ &amp;quot;.&amp;quot;&amp;gt;&lt;br /&gt;
        SetHandler cgi-script&lt;br /&gt;
        Options +ExecCGI&lt;br /&gt;
    &amp;lt;/Files&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    &amp;lt;Files ~ &amp;quot;^.[a-zA-Z]*$&amp;quot;&amp;gt;&lt;br /&gt;
        SetHandler cgi-script&lt;br /&gt;
        Options +ExecCGI&lt;br /&gt;
    &amp;lt;/Files&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Or just have index file:&lt;br /&gt;
    &amp;lt;Files &amp;quot;index&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: Place within a &amp;lt;VirtualHost&amp;gt; section if needed.&lt;br /&gt;
&lt;br /&gt;
Note: Make sure to &#039;chmod +x&#039; the files.&lt;br /&gt;
&lt;br /&gt;
Start all HTML output with:&lt;br /&gt;
 print &amp;quot;Content-Type: text/html\n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If you want just text output:&lt;br /&gt;
 print &amp;quot;Content-Type: text/plain\n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
GET (from Environment):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
print &amp;quot;&amp;amp;lt;pre&amp;gt;&amp;quot;&lt;br /&gt;
for env in os.environ:&lt;br /&gt;
    print &amp;quot;%s = %s&amp;quot; % (env, os.environ[env])&lt;br /&gt;
print &amp;quot;&amp;amp;lt;/pre&amp;gt;&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# sample for: http://oeey.com/py/test.py/test?var1=ken&amp;amp;var2=barbie&lt;br /&gt;
&lt;br /&gt;
REQUEST_URI = /py/index.py/test?var1=ken&amp;amp;var2=barbie&lt;br /&gt;
QUERY_STRING = var1=ken&amp;amp;var2=barbie&lt;br /&gt;
PATH_INFO = /test&lt;br /&gt;
REQUEST_METHOD = GET&lt;br /&gt;
&lt;br /&gt;
SCRIPT_NAME = /py/test.py&lt;br /&gt;
SERVER_NAME = oeey.com&lt;br /&gt;
REMOTE_ADDR = 216.51.42.66&lt;br /&gt;
SERVER_ADDR = 192.168.108.4&lt;br /&gt;
DOCUMENT_ROOT = /www/py&lt;br /&gt;
SCRIPT_FILENAME = /www/py/test.py&lt;br /&gt;
HTTP_HOST = cgi.oeey.com&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
POST (from stdin):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
post = sys.stdin.readline()&lt;br /&gt;
if post:&lt;br /&gt;
    print post&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CONTENT_TYPE = application/x-www-form-urlencoded&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
yin=one+two+three&amp;amp;yang=four+five+six&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
cgi helper class:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import cgi&lt;br /&gt;
&lt;br /&gt;
print &amp;quot;Content-Type: text/html\n\n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
form = cgi.FieldStorage()&lt;br /&gt;
&lt;br /&gt;
# field keys&lt;br /&gt;
print &amp;quot;fields keys: &amp;quot;, form.keys()  # list of field keys&lt;br /&gt;
&lt;br /&gt;
# fild values&lt;br /&gt;
if &amp;quot;name&amp;quot; in form:  # if form.has_key(&#039;name&#039;):&lt;br /&gt;
    print &amp;quot;field &#039;name&#039; is: &amp;quot;, form[&amp;quot;name&amp;quot;].value&lt;br /&gt;
    print &amp;quot;field &#039;name&#039; is: &amp;quot;, form.getvalue(&#039;name&#039;)&lt;br /&gt;
&lt;br /&gt;
# headers&lt;br /&gt;
print &amp;quot;dictionary of headers: &amp;quot;, form.headers&lt;br /&gt;
print form.type&lt;br /&gt;
print form.headers[&#039;content-type&#039;]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To prevent XSS escape the characters:&lt;br /&gt;
  print cgi.escape(form.getvalue(&#039;name&#039;))&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import cgi&lt;br /&gt;
&lt;br /&gt;
print &amp;quot;Content-Type: text/html\n\n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
form = cgi.FieldStorage()&lt;br /&gt;
if (form.has_key(&amp;quot;action&amp;quot;) and form.has_key(&amp;quot;name&amp;quot;) \&lt;br /&gt;
        and form.has_key(&amp;quot;age&amp;quot;)):&lt;br /&gt;
    if (form[&amp;quot;action&amp;quot;].value == &amp;quot;display&amp;quot;):&lt;br /&gt;
        print &amp;quot;%s = %s&amp;quot; % (form[&amp;quot;name&amp;quot;].value form[&amp;quot;age&amp;quot;].value)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: cgi helper class also does sessions and cookies.&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* CGI Tutorial | Web Python - http://webpython.codepoint.net/cgi_tutorial&lt;br /&gt;
* Python CGI: An Interactive Instruction - http://www.cs.virginia.edu/~lab2q/&lt;br /&gt;
&lt;br /&gt;
See also:&lt;br /&gt;
* Web Python - http://webpython.codepoint.net/&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
REST Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import os, re&lt;br /&gt;
def get_rest():&lt;br /&gt;
    if not &amp;quot;PATH_INFO&amp;quot; in os.environ:&lt;br /&gt;
        return ()&lt;br /&gt;
    # filter for garbage&lt;br /&gt;
    #print os.environ[&amp;quot;PATH_INFO&amp;quot;]&lt;br /&gt;
    path_info = re.findall(&#039;[/A-Za-z0-9_-]*&#039;, os.environ[&amp;quot;PATH_INFO&amp;quot;])&lt;br /&gt;
    if not path_info:&lt;br /&gt;
        return ()&lt;br /&gt;
    path_info = &#039;&#039;.join(path_info)&lt;br /&gt;
    # collapse empty paths&lt;br /&gt;
    paths = path_info.split(&#039;/&#039;)&lt;br /&gt;
    final_paths = []&lt;br /&gt;
    for path in paths:&lt;br /&gt;
        if path:&lt;br /&gt;
            final_paths.append(path)&lt;br /&gt;
    return tuple(final_paths)&lt;br /&gt;
rest = get_rest();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== mod_python ===&lt;br /&gt;
&lt;br /&gt;
AVOID! AVOID! AVOID! - if you want this simple, just use CGI!&lt;br /&gt;
&lt;br /&gt;
See [[Apache mod_python]]&lt;br /&gt;
&lt;br /&gt;
mod_python - http://docs.python.org/howto/webservers.html#mod-python&lt;br /&gt;
&lt;br /&gt;
Install:&lt;br /&gt;
 yum install mod_python&lt;br /&gt;
&lt;br /&gt;
Config:&lt;br /&gt;
 /etc/httpd/conf.d/python.conf&lt;br /&gt;
&lt;br /&gt;
Simple:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;quot;People coming from PHP often find it hard to grasp how to use Python in the web. Their first thought is mostly mod_python, because they think that this is the equivalent to mod_php. Actually, there are many differences. What mod_python does is embed the interpreter into the Apache process, thus speeding up requests by not having to start a Python interpreter for each request. On the other hand, it is not “Python intermixed with HTML” in the way that PHP is often intermixed with HTML. The Python equivalent of that is a template engine. mod_python itself is much more powerful and provides more access to Apache internals. It can emulate CGI, work in a “Python Server Pages” mode (similar to JSP) which is “HTML intermingled with Python”, and it has a “Publisher” which designates one file to accept all requests and decide what to do with them.&lt;br /&gt;
&lt;br /&gt;
:mod_python does have some problems. Unlike the PHP interpreter, the Python interpreter uses caching when executing files, so changes to a file will require the web server to be restarted. Another problem is the basic concept – Apache starts child processes to handle the requests, and unfortunately every child process needs to load the whole Python interpreter even if it does not use it. This makes the whole web server slower. Another problem is that, because mod_python is linked against a specific version of libpython, it is not possible to switch from an older version to a newer (e.g. 2.4 to 2.5) without recompiling mod_python. mod_python is also bound to the Apache web server, so programs written for mod_python cannot easily run on other web servers.&lt;br /&gt;
&lt;br /&gt;
:These are the reasons why mod_python should be avoided when writing new programs. In some circumstances it still might be a good idea to use mod_python for deployment, but WSGI makes it possible to run WSGI programs under mod_python as well.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== WSGI ===&lt;br /&gt;
&lt;br /&gt;
WSGI - http://docs.python.org/howto/webservers.html#mod-wsgi&lt;br /&gt;
&lt;br /&gt;
: &amp;quot;The Web Server Gateway Interface, or WSGI for short, is defined in PEP 333 and is currently the best way to do Python web programming. While it is great for programmers writing frameworks, a normal web developer does not need to get in direct contact with it. When choosing a framework for web development it is a good idea to choose one which supports WSGI.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
See [[mod_wsgi]]&lt;br /&gt;
&lt;br /&gt;
=== Django ===&lt;br /&gt;
&lt;br /&gt;
See [[Django]]&lt;br /&gt;
&lt;br /&gt;
=== CherryPy ===&lt;br /&gt;
&lt;br /&gt;
See [[CherryPy]]&lt;br /&gt;
&lt;br /&gt;
=== web.py ===&lt;br /&gt;
&lt;br /&gt;
web.py: makes web apps&lt;br /&gt;
&lt;br /&gt;
Think about the ideal way to write a web app. Write the code to make it happen.&lt;br /&gt;
&lt;br /&gt;
web.py : Python Package Index - http://pypi.python.org/pypi/web.py&lt;br /&gt;
&lt;br /&gt;
Home Page: http://webpy.org/&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Django lets you write web apps in Django. TurboGears lets you write web apps in TurboGears. Web.py lets you write web apps in Python.&amp;quot;&lt;br /&gt;
:—  Adam Atlas&lt;br /&gt;
&lt;br /&gt;
NOTE: Can modify source code without having to restart app!  :-)&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
PIP Install:&lt;br /&gt;
 pip install web.py&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
Hello World: [http://webpy.org/]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import web&lt;br /&gt;
        &lt;br /&gt;
urls = (&lt;br /&gt;
    &#039;/(.*)&#039;, &#039;hello&#039;&lt;br /&gt;
)&lt;br /&gt;
app = web.application(urls, globals())&lt;br /&gt;
&lt;br /&gt;
class hello:        &lt;br /&gt;
    def GET(self, name):&lt;br /&gt;
        if not name: &lt;br /&gt;
            name = &#039;World&#039;&lt;br /&gt;
        return &#039;Hello, &#039; + name + &#039;!&#039;&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
    app.run()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: app.py can be renamed.&lt;br /&gt;
&lt;br /&gt;
Running:&lt;br /&gt;
 python app.py&lt;br /&gt;
&lt;br /&gt;
Note: You can add an IP address/port after the &amp;quot;app.py&amp;quot; bit to control where web.py launches the server. You can also tell it to run a fastcgi or scgi server.&lt;br /&gt;
 python app.py 1234&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
Templates&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# templates/hello.html&lt;br /&gt;
$def with (name)&lt;br /&gt;
&lt;br /&gt;
$if name:&lt;br /&gt;
    I just wanted to say &amp;lt;em&amp;gt;hello&amp;lt;/em&amp;gt; to $name.&lt;br /&gt;
$else:&lt;br /&gt;
    &amp;lt;em&amp;gt;Hello&amp;lt;/em&amp;gt;, world!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 app = ...&lt;br /&gt;
 render = web.template.render(&#039;templates/&#039;)&lt;br /&gt;
&lt;br /&gt;
index.GET:&lt;br /&gt;
 name = &#039;Bob&#039;    &lt;br /&gt;
 return render.hello(name)  # render.[TEMPLATE_NAME](vars)&lt;br /&gt;
&lt;br /&gt;
get variable: (/?name=Joe)&lt;br /&gt;
 i = web.input(name=None)&lt;br /&gt;
 return render.hello(i.name)&lt;br /&gt;
&lt;br /&gt;
variable in url:&lt;br /&gt;
 urls = (&#039;/(.*)&#039;, &#039;hello&#039;)&lt;br /&gt;
&lt;br /&gt;
 class index:&lt;br /&gt;
     def GET(self, name):&lt;br /&gt;
        return render.hello(name)&lt;br /&gt;
&lt;br /&gt;
 # visit: /Joe&lt;br /&gt;
&lt;br /&gt;
multiple variables in url:&lt;br /&gt;
 urls = (&#039;/(.*)/(.*)&#039;, &#039;hello&#039;)&lt;br /&gt;
&lt;br /&gt;
  class hello:&lt;br /&gt;
    def GET(self, fname, lname):&lt;br /&gt;
        return render.hello(fname, lname)&lt;br /&gt;
&lt;br /&gt;
 # visit: /Joe/Smith&lt;br /&gt;
&lt;br /&gt;
=== lpthw.web ===&lt;br /&gt;
&lt;br /&gt;
lpthw.web: a fork of web.py for Learn Python The Hard Way&lt;br /&gt;
&lt;br /&gt;
Locks web.py at a specific version and removes some magic. Thanks to Aaron Swartz for making it originally.&lt;br /&gt;
&lt;br /&gt;
lpthw.web: a fork of web.py for Learn Python The Hard Way - http://pypi.python.org/pypi/lpthw.web&lt;br /&gt;
&lt;br /&gt;
Home Page: http://learnpythonthehardway.org/&lt;br /&gt;
&lt;br /&gt;
This conflicts with web.py, so only install one.&lt;br /&gt;
&lt;br /&gt;
=== web ===&lt;br /&gt;
&lt;br /&gt;
web - Web modules for CGI and WSGI web programming&lt;br /&gt;
&lt;br /&gt;
web : Python Package Index - http://pypi.python.org/pypi/web&lt;br /&gt;
&lt;br /&gt;
Warning: This is an alpha release for those who are interested in&lt;br /&gt;
    checking progress. No documentation and not for production use.&lt;br /&gt;
&lt;br /&gt;
Auth, session, mail, form and templating tools for writing CGI scripts or WSGI web applications.&lt;br /&gt;
&lt;br /&gt;
This version incompatible with previous versions becuase large portions of the code have been refactored into separate components.&lt;br /&gt;
&lt;br /&gt;
== Issues ==&lt;br /&gt;
&lt;br /&gt;
=== Hide DeprecationWarning ===&lt;br /&gt;
&lt;br /&gt;
==== Import DeprecationWarning ====&lt;br /&gt;
&lt;br /&gt;
Error:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/opt/xmpppy-0.4.1/xmpp/auth.py:24: DeprecationWarning: the sha module is deprecated; use the hashlib module instead&lt;br /&gt;
  import sha,base64,random,dispatcher,re&lt;br /&gt;
/opt/xmpppy-0.4.1/xmpp/auth.py:26: DeprecationWarning: the md5 module is deprecated; use hashlib instead&lt;br /&gt;
  import md5&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hide deprecation warnings with code: [http://stackoverflow.com/questions/879173/how-to-ignore-deprecation-warnings-in-python]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import warnings&lt;br /&gt;
&lt;br /&gt;
with warnings.catch_warnings():&lt;br /&gt;
    warnings.filterwarnings(&amp;quot;ignore&amp;quot;,category=DeprecationWarning)&lt;br /&gt;
    import md5, sha&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hide with header:&lt;br /&gt;
 #!/usr/bin/env python -W ignore::DeprecationWarning&lt;br /&gt;
&lt;br /&gt;
Hide from command line:&lt;br /&gt;
 python -W ignore::DeprecationWarning script.py&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* How to ignore deprecation warnings in Python - Stack Overflow - http://stackoverflow.com/questions/879173/how-to-ignore-deprecation-warnings-in-python&lt;br /&gt;
&lt;br /&gt;
==== Funciton DeprecationWarning ====&lt;br /&gt;
&lt;br /&gt;
Error:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/opt/xmpppy-0.4.1/xmpp/transports.py:307: DeprecationWarning: socket.ssl() is deprecated.  Use ssl.wrap_socket() instead.&lt;br /&gt;
  tcpsock._sslObj    = socket.ssl(tcpsock._sock, None, None)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hide with header:&lt;br /&gt;
 #!/usr/bin/env python -W ignore::DeprecationWarning&lt;br /&gt;
&lt;br /&gt;
Hide from command line:&lt;br /&gt;
 python -W ignore::DeprecationWarning script.py&lt;br /&gt;
&lt;br /&gt;
==== Ubuntu 24 pip packages ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
error: externally-managed-environment&lt;br /&gt;
&lt;br /&gt;
× This environment is externally managed&lt;br /&gt;
╰─&amp;gt; To install Python packages system-wide, try apt install&lt;br /&gt;
    python3-xyz, where xyz is the package you are trying to&lt;br /&gt;
    install.&lt;br /&gt;
&lt;br /&gt;
    If you wish to install a non-Debian-packaged Python package,&lt;br /&gt;
    create a virtual environment using python3 -m venv path/to/venv.&lt;br /&gt;
    Then use path/to/venv/bin/python and path/to/venv/bin/pip. Make&lt;br /&gt;
    sure you have python3-full installed.&lt;br /&gt;
&lt;br /&gt;
    If you wish to install a non-Debian packaged Python application,&lt;br /&gt;
    it may be easiest to use pipx install xyz, which will manage a&lt;br /&gt;
    virtual environment for you. Make sure you have pipx installed.&lt;br /&gt;
&lt;br /&gt;
    See /usr/share/doc/python3.12/README.venv for more information.&lt;br /&gt;
&lt;br /&gt;
note: If you believe this is a mistake, please contact your Python installation or OS distribution provider. You can override this, at the risk of breaking your Python installation or OS, by passing --break-system-packages.&lt;br /&gt;
hint: See PEP 668 for the detailed specification.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== keywords ==&lt;br /&gt;
&lt;br /&gt;
[[Category:Programming]]&lt;br /&gt;
[[Category:Python]]&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=Python&amp;diff=9871</id>
		<title>Python</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=Python&amp;diff=9871"/>
		<updated>2026-04-27T20:28:29Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: /* Variable Type = */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{subtop}}&lt;br /&gt;
&lt;br /&gt;
== Python ==&lt;br /&gt;
&lt;br /&gt;
Python (programming language) - Wikipedia - http://en.wikipedia.org/wiki/Python_(programming_language)&lt;br /&gt;
: Python is an interpreted, general-purpose high-level programming language whose design philosophy emphasizes code readability. Python aims to combine &amp;quot;remarkable power with very clear syntax&amp;quot;, and its standard library is large and comprehensive. Its use of indentation for block delimiters is unique among popular programming languages.&lt;br /&gt;
: Python supports multiple programming paradigms, primarily but not limited to object-oriented, imperative and, to a lesser extent, functional programming styles. It features a fully dynamic type system and automatic memory management, similar to that of Scheme, Ruby, Perl, and Tcl. Like other dynamic languages, Python is often used as a scripting language, but is also used in a wide range of non-scripting contexts.&lt;br /&gt;
: The reference implementation of Python ([http://en.wikipedia.org/wiki/CPython CPython]) is free and open source software and has a community-based development model, as do all or nearly all of its alternative implementations. CPython is managed by the non-profit Python Software Foundation.&lt;br /&gt;
: Python interpreters are available for many operating systems, and Python programs can be packaged into stand-alone executable code for many systems using various tools.&lt;br /&gt;
&lt;br /&gt;
Author:&lt;br /&gt;
:&amp;quot;Python was conceived in the late 1980s and its implementation was started in December 1989 by &#039;&#039;&#039;[http://www.python.org/~guido/ Guido van Rossum]&#039;&#039;&#039; at CWI in the Netherlands as a successor to the ABC programming language (itself inspired by SETL) capable of exception handling and interfacing with the Amoeba operating system. Van Rossum is Python&#039;s principal author, and his continuing central role in deciding the direction of Python is reflected in the title given to him by the Python community, Benevolent Dictator for Life (BDFL).&amp;quot; [http://en.wikipedia.org/wiki/Python_(programming_language)]&lt;br /&gt;
&lt;br /&gt;
Name:&lt;br /&gt;
:&amp;quot;The language is named after the BBC show “Monty Python’s Flying Circus” and has nothing to do with reptiles. Making references to Monty Python skits in documentation is not only allowed, it is encouraged!&amp;quot; [http://docs.python.org/py3k/tutorial/appetite.html]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
We as people are &amp;quot;Pythonites&amp;quot; [http://raspi.tv/2013/how-to-use-interrupts-with-python-on-the-raspberry-pi-and-rpi-gpio-part-2]&lt;br /&gt;
&lt;br /&gt;
== [http://www.python.org/dev/peps/pep-0020/ The Zen of Python] ==&lt;br /&gt;
&lt;br /&gt;
&amp;quot;The core philosophy of the language is summarized by the document &#039;PEP 20 (The Zen of Python)&#039;&amp;quot; [http://en.wikipedia.org/wiki/Python_%28programming_language%29]&lt;br /&gt;
* PEP 20 -- The Zen of Python - http://www.python.org/dev/peps/pep-0020/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Abstract&lt;br /&gt;
&lt;br /&gt;
    Long time Pythoneer Tim Peters succinctly channels the BDFL&#039;s&lt;br /&gt;
    guiding principles for Python&#039;s design into 20 aphorisms, only 19&lt;br /&gt;
    of which have been written down.&lt;br /&gt;
&lt;br /&gt;
The Zen of Python&lt;br /&gt;
&lt;br /&gt;
    Beautiful is better than ugly.&lt;br /&gt;
    Explicit is better than implicit.&lt;br /&gt;
    Simple is better than complex.&lt;br /&gt;
    Complex is better than complicated.&lt;br /&gt;
    Flat is better than nested.&lt;br /&gt;
    Sparse is better than dense.&lt;br /&gt;
    Readability counts.&lt;br /&gt;
    Special cases aren&#039;t special enough to break the rules.&lt;br /&gt;
    Although practicality beats purity.&lt;br /&gt;
    Errors should never pass silently.&lt;br /&gt;
    Unless explicitly silenced.&lt;br /&gt;
    In the face of ambiguity, refuse the temptation to guess.&lt;br /&gt;
    There should be one-- and preferably only one --obvious way to do it.&lt;br /&gt;
    Although that way may not be obvious at first unless you&#039;re Dutch.&lt;br /&gt;
    Now is better than never.&lt;br /&gt;
    Although never is often better than *right* now.&lt;br /&gt;
    If the implementation is hard to explain, it&#039;s a bad idea.&lt;br /&gt;
    If the implementation is easy to explain, it may be a good idea.&lt;br /&gt;
    Namespaces are one honking great idea -- let&#039;s do more of those!&lt;br /&gt;
&lt;br /&gt;
Easter Egg&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import this&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Other Sources:&lt;br /&gt;
* http://www.python.org/doc/humor/&lt;br /&gt;
* The Zen of Python – as a Poster « CODE POETRY - http://codepoetry.wordpress.com/2010/03/23/the-zen-of-python-as-a-poster/&lt;br /&gt;
** Zen of Python (PDF) http://codepoetry.files.wordpress.com/2010/03/zen-of-python.pdf&lt;br /&gt;
&lt;br /&gt;
== Documentation ==&lt;br /&gt;
&lt;br /&gt;
* Overview — Python v2.7.1 documentation - http://docs.python.org/index.html&lt;br /&gt;
** Download — Python v2.7.1 documentation - http://docs.python.org/download.html&lt;br /&gt;
&lt;br /&gt;
* Overview — Python v3.2 documentation - http://docs.python.org/py3k/&lt;br /&gt;
**  Download — Python v3.2 documentation - http://docs.python.org/py3k/download.html&lt;br /&gt;
&lt;br /&gt;
* PEP 8 -- Style Guide for Python Code - http://www.python.org/dev/peps/pep-0008/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Tutorials ==&lt;br /&gt;
&lt;br /&gt;
* The Python Tutorial — Python v2.7.1 documentation - http://docs.python.org/tutorial/&lt;br /&gt;
&lt;br /&gt;
* Python 101 -- Introduction to Python - http://www.rexx.com/~dkuhlman/python_101/python_101.html&lt;br /&gt;
&lt;br /&gt;
* 4. More Control Flow Tools — Python v2.7.1 documentation - http://docs.python.org/tutorial/controlflow.html&lt;br /&gt;
&lt;br /&gt;
== Linux Installation ==&lt;br /&gt;
&lt;br /&gt;
RHEL Distribution installation:&lt;br /&gt;
 yum -y install python python-setuptools&lt;br /&gt;
&lt;br /&gt;
Ubuntu Distribution installation: [https://help.ubuntu.com/community/Mercurial]&lt;br /&gt;
 # enable &#039;universe&#039; in the sources.list&lt;br /&gt;
 # &amp;quot;Mercurial is included in the Universe repository - activate this repo first&amp;quot;&lt;br /&gt;
 sudo apt-get install mercurial&lt;br /&gt;
&lt;br /&gt;
CentOS 5 Option Recommended Dependencies:&lt;br /&gt;
 yum -y install gcc make sudo readline-devel openssl-devel ncurses-devel zlib-devel gdbm-devel sqlite-devel bzip2-devel tk-devel tcl-devel&lt;br /&gt;
&lt;br /&gt;
 # this leaves: 2.6.6: _bsddb, bsddb185, dl, imageop, sunaudiodev&lt;br /&gt;
 # this leaves: 2.7.1: _bsddb, bsddb185, dl, imageop, sunaudiodev&lt;br /&gt;
 # this leaves: 3.2: none&lt;br /&gt;
&lt;br /&gt;
CentOS 9 Option Recommended Dependencies:&lt;br /&gt;
 # gdbm-devel not found in centos9?&lt;br /&gt;
 yum -y install gcc make sudo readline-devel openssl-devel ncurses-devel zlib-devel sqlite-devel bzip2-devel tk-devel tcl-devel&lt;br /&gt;
&lt;br /&gt;
Ubuntu 12.04 LTS 64bit dependencies:&lt;br /&gt;
 apt-get install gcc make sudo lib64bz2-dev tcl-dev lib64ncurses5-dev libssl-dev libreadline-dev tk-dev libsqlite3-dev libgdbm-dev&lt;br /&gt;
&lt;br /&gt;
 # maybe: lib64readline-dev libsqlite3-dev tk-dev&lt;br /&gt;
&lt;br /&gt;
 # this leaves: 2.7: _bsddb, bsddb185, dl, imageop, sunaudiodev&lt;br /&gt;
&lt;br /&gt;
=== 2.x ===&lt;br /&gt;
&lt;br /&gt;
CentOS dependencies:&lt;br /&gt;
 sudo yum -y install gcc make sudo readline-devel openssl-devel ncurses-devel zlib-devel gdbm-devel sqlite-devel bzip2-devel tk-devel tcl-devel&lt;br /&gt;
&lt;br /&gt;
Ubuntu 12.04 LTS 64bit dependencies:&lt;br /&gt;
 sudo apt-get update&lt;br /&gt;
 sudo apt-get install gcc make sudo lib64bz2-dev tcl-dev lib64ncurses5-dev libssl-dev libreadline-dev tk-dev libsqlite3-dev libgdbm-dev&lt;br /&gt;
&lt;br /&gt;
Ubuntu 24.04 LTS 64bit dependencies:&lt;br /&gt;
 sudo apt-get update&lt;br /&gt;
 sudo apt-get install gcc make sudo libbz2-dev tcl-dev libncurses-dev libssl-dev libreadline-dev tk-dev libsqlite3-dev libgdbm-dev libffi-dev&lt;br /&gt;
 # optional install&lt;br /&gt;
 sudo apt-get install checkinstall&lt;br /&gt;
&lt;br /&gt;
2.7.15:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#  PYVER=2.6.6&lt;br /&gt;
#  PYVER=2.7.5&lt;br /&gt;
#  PYVER=2.7.6&lt;br /&gt;
#  PYVER=2.7.9&lt;br /&gt;
#  PYVER=2.7.10&lt;br /&gt;
#  PYVER=2.7.15&lt;br /&gt;
PYVER=2.7.18&lt;br /&gt;
mkdir -p ~/.src ; cd ~/.src&lt;br /&gt;
wget --no-check-certificate http://www.python.org/ftp/python/$PYVER/Python-$PYVER.tgz&lt;br /&gt;
tar -zvxf Python-$PYVER.tgz&lt;br /&gt;
cd Python-$PYVER&lt;br /&gt;
#  ./configure --prefix=/opt/python-$PYVER&lt;br /&gt;
#  make clean &amp;amp;&amp;amp; make&lt;br /&gt;
./configure --prefix=/opt/python-$PYVER &amp;amp;&amp;amp; make clean &amp;amp;&amp;amp; make&lt;br /&gt;
sudo make install&lt;br /&gt;
&lt;br /&gt;
sudo /opt/python-$PYVER/bin/python -m ensurepip --upgrade&lt;br /&gt;
sudo /opt/python-$PYVER/bin/pip install --upgrade pip&lt;br /&gt;
sudo /opt/python-$PYVER/bin/pip install requests&lt;br /&gt;
&lt;br /&gt;
export PATH=/opt/python-$PYVER/bin:$PATH&lt;br /&gt;
echo -e &amp;quot;\n\nexport PATH=/opt/python-$PYVER/bin:\$PATH\n&amp;quot; &amp;gt;&amp;gt; ~/.bash_profile&lt;br /&gt;
#  echo -e &amp;quot;\n\nexport PATH=/opt/python27/bin:\$PATH\n&amp;quot; &amp;gt;&amp;gt; ~/.bashrc&lt;br /&gt;
&lt;br /&gt;
#  NOTE: remove any old versions from your .bash_profile&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Bootstrapping the pip installer - https://docs.python.org/2/library/ensurepip.html&lt;br /&gt;
&lt;br /&gt;
=== 3.x ===&lt;br /&gt;
&lt;br /&gt;
3.8.16:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#VER=3.7.0&lt;br /&gt;
#VER=3.8.15&lt;br /&gt;
#VER=3.10.9&lt;br /&gt;
VER=3.8.16&lt;br /&gt;
mkdir -p ~/.src ; cd ~/.src&lt;br /&gt;
wget http://www.python.org/ftp/python/${VER}/Python-${VER}.tgz&lt;br /&gt;
tar -zvxf Python-${VER}.tgz&lt;br /&gt;
cd Python-${VER}&lt;br /&gt;
./configure --prefix=/opt/python${VER}&lt;br /&gt;
make&lt;br /&gt;
&lt;br /&gt;
sudo make install&lt;br /&gt;
&lt;br /&gt;
## OPTIONAL alternative install path:&lt;br /&gt;
sudo checkinstall&lt;br /&gt;
## note: &#039;checkinstall&#039; makes a .deb, which you can uninstall with easier, but if you are using --prefix, you do need to&lt;br /&gt;
##       premake the folders&lt;br /&gt;
sudo mkdir -p /opt/python${VER}/bin&lt;br /&gt;
sudo mkdir -p /opt/python${VER}/lib&lt;br /&gt;
shortVER=`echo $VER | cut -d &#039;.&#039; -f 1-2`  # get short version eg. 3.10 from 3.10.9&lt;br /&gt;
sudo mkdir -p /opt/python${VER}/lib/python${shortVER}&lt;br /&gt;
sudo mkdir -p /opt/python${VER}/lib/python${shortVER}/test&lt;br /&gt;
# sudo checkinstall    # hit Y, and enter twice&lt;br /&gt;
## note: older versions have problems with the virtualization of the file system, so do FS Translation = no&lt;br /&gt;
checkinstall --fstrans=no&lt;br /&gt;
&lt;br /&gt;
export PATH=/opt/python${VER}/bin:$PATH&lt;br /&gt;
echo -e &amp;quot;\n\nexport PATH=/opt/python${VER}/bin:\$PATH\n&amp;quot; &amp;gt;&amp;gt; ~/.bash_profile&lt;br /&gt;
&lt;br /&gt;
# have to manually update version&lt;br /&gt;
rm /opt/python${VER}/bin/python&lt;br /&gt;
ln -sfn python3.8 /opt/python${VER}/bin/python&lt;br /&gt;
#cp /opt/python${VER}/bin/python3.8 /opt/python${VER}/bin/python&lt;br /&gt;
&lt;br /&gt;
# DEPENDENCIES&lt;br /&gt;
sudo apt install ...&lt;br /&gt;
yum install libffi-devel openssl-devel&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note, if you want the libraries to be shared (like python-dev):&lt;br /&gt;
 ./configure --enable-shared&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
 VER=3.6.9&lt;br /&gt;
&lt;br /&gt;
 VER=3.6.8&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
3.2.0:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir -p ~/src ; cd ~/src&lt;br /&gt;
wget http://www.python.org/ftp/python/3.2/Python-3.2.tgz&lt;br /&gt;
tar -zvxf Python-3.2.tgz&lt;br /&gt;
cd Python-3.2&lt;br /&gt;
./configure --prefix=/opt/python32&lt;br /&gt;
make&lt;br /&gt;
sudo make install&lt;br /&gt;
&lt;br /&gt;
export PATH=/opt/python32/bin:$PATH&lt;br /&gt;
echo -e &amp;quot;\n\nexport PATH=/opt/python32/bin:\$PATH\n&amp;quot; &amp;gt;&amp;gt; ~/.bash_profile&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3.3.0:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir -p ~/src ; cd ~/src&lt;br /&gt;
wget http://www.python.org/ftp/python/3.3.0/Python-3.3.0.tgz&lt;br /&gt;
tar -zvxf Python-3.3.0.tgz&lt;br /&gt;
cd Python-3.3.0&lt;br /&gt;
./configure --prefix=/opt/python3.3.0&lt;br /&gt;
make&lt;br /&gt;
sudo make install&lt;br /&gt;
&lt;br /&gt;
export PATH=/opt/python3.3.0/bin:$PATH&lt;br /&gt;
echo -e &amp;quot;\n\nexport PATH=/opt/python3.3.0/bin:\$PATH\n&amp;quot; &amp;gt;&amp;gt; ~/.bash_profile&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3.3.4:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir -p ~/.src ; cd ~/.src&lt;br /&gt;
wget http://www.python.org/ftp/python/3.3.4/Python-3.3.4.tgz&lt;br /&gt;
tar -zvxf Python-3.3.4.tgz&lt;br /&gt;
cd Python-3.3.4&lt;br /&gt;
./configure --prefix=/opt/python3.3.4&lt;br /&gt;
make clean&lt;br /&gt;
make&lt;br /&gt;
sudo make install&lt;br /&gt;
&lt;br /&gt;
export PATH=/opt/python3.3.4/bin:$PATH&lt;br /&gt;
echo -e &amp;quot;\n\nexport PATH=/opt/python3.3.4/bin:\$PATH\n&amp;quot; &amp;gt;&amp;gt; ~/.bash_profile&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3.4.0:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir -p ~/.src ; cd ~/.src&lt;br /&gt;
wget http://www.python.org/ftp/python/3.4.0/Python-3.4.0.tgz&lt;br /&gt;
tar -zvxf Python-3.4.0.tgz&lt;br /&gt;
cd Python-3.4.0&lt;br /&gt;
./configure --prefix=/opt/python3.4.0&lt;br /&gt;
make&lt;br /&gt;
sudo make install&lt;br /&gt;
&lt;br /&gt;
export PATH=/opt/python3.4.0/bin:$PATH&lt;br /&gt;
echo -e &amp;quot;\n\nexport PATH=/opt/python3.4.0/bin:\$PATH\n&amp;quot; &amp;gt;&amp;gt; ~/.bash_profile&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== setuptools ===&lt;br /&gt;
&lt;br /&gt;
Purpose: to install pip&lt;br /&gt;
&lt;br /&gt;
Note: required for several &#039;python setup.py install&#039; installations.&lt;br /&gt;
&lt;br /&gt;
Python Package Index : setuptools 0.6c11 - http://pypi.python.org/pypi/setuptools&lt;br /&gt;
&lt;br /&gt;
By Package Manager:&lt;br /&gt;
 yum install python-setuptools&lt;br /&gt;
&lt;br /&gt;
By Source:&lt;br /&gt;
 #VER=2.0.1&lt;br /&gt;
 #VER=2.2&lt;br /&gt;
 VER=3.4.4&lt;br /&gt;
 mkdir -p ~/.src ; cd ~/.src&lt;br /&gt;
 wget --no-check-certificate http://pypi.python.org/packages/source/s/setuptools/setuptools-$VER.tar.gz&lt;br /&gt;
 tar -zvxf setuptools-$VER.tar.gz&lt;br /&gt;
 cd setuptools-$VER&lt;br /&gt;
 # sudo python setup.py install&lt;br /&gt;
 sudo /opt/python-2.7.9/bin/python setup.py install&lt;br /&gt;
&lt;br /&gt;
Fix header:&lt;br /&gt;
 # Only needed on older versions&lt;br /&gt;
 sed -i &#039;s#!/usr/bin/python#!/usr/bin/env python#g&#039; /opt/python279/bin/easy_install&lt;br /&gt;
&lt;br /&gt;
Install pip:&lt;br /&gt;
 sudo /opt/python-2.7.9/bin/easy_install pip&lt;br /&gt;
&lt;br /&gt;
Sample pip usage:&lt;br /&gt;
 sudo /opt/python-2.7.9/bin/pip install paramiko&lt;br /&gt;
&lt;br /&gt;
== IDLE and Interactive Mode ==&lt;br /&gt;
&lt;br /&gt;
Interactive Mode - &amp;quot;When commands are read from a tty, the interpreter is said to be in interactive mode. In this mode it prompts for the next command with the primary prompt, usually three greater-than signs (&amp;gt;&amp;gt;&amp;gt;); for continuation lines it prompts with the secondary prompt, by default three dots (...).&amp;quot; [http://docs.python.org/2/tutorial/interpreter.html#invoking-the-interpreter]&lt;br /&gt;
&lt;br /&gt;
Can use &#039;_&#039; to reference last output:&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; 5 + 6&lt;br /&gt;
 11&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; print _&lt;br /&gt;
 11&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* 2. Using the Python Interpreter — Python v2.7.3 documentation - http://docs.python.org/2/tutorial/interpreter.html&lt;br /&gt;
&lt;br /&gt;
== Python 2.7 EOL ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
DEPRECATION: Python 2.7 will reach the end of its life on January 1st, 2020. Please upgrade your Python as Python 2.7 won&#039;t be maintained after that date. A future version of pip will drop support for Python 2.7.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Show All Python in Path ==&lt;br /&gt;
&lt;br /&gt;
 compgen -c | grep -i &amp;quot;python&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
&lt;br /&gt;
=== Hello World ===&lt;br /&gt;
&lt;br /&gt;
[http://en.wikipedia.org/wiki/Shebang_%28Unix%29 shebang] (also called a hashbang) of Python:&lt;br /&gt;
 #!/usr/bin/env python&lt;br /&gt;
 print &amp;quot;Hello World&amp;quot;&lt;br /&gt;
&lt;br /&gt;
NOTE: can also just use &amp;quot;#!/usr/bin/python&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Standard Script ===&lt;br /&gt;
&lt;br /&gt;
Standard Script:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def main(args):&lt;br /&gt;
  # do logic&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
  sys.exit(main(sys.argv))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Needed for things like pylint&lt;br /&gt;
&lt;br /&gt;
=== White Space ===&lt;br /&gt;
&lt;br /&gt;
Python uses white space to indicate code blocks.  Instead of &#039;&#039;{&#039;&#039; use a &#039;&#039;:&#039;&#039; and indent consistently (4 spaces).&lt;br /&gt;
&lt;br /&gt;
 if a == b:&lt;br /&gt;
     print &#039;equal&#039;&lt;br /&gt;
&lt;br /&gt;
Convert tabs to spaces:&lt;br /&gt;
 sed -i &#039;s/\t/    /g&#039; *.py&lt;br /&gt;
&lt;br /&gt;
Remove trailing whitespace:&lt;br /&gt;
 sed -i &#039;s/\s*$//&#039; *.py&lt;br /&gt;
 sed --in-place &#039;s/[[:space:]]\+$//&#039; fileName&lt;br /&gt;
&lt;br /&gt;
Clean project:&lt;br /&gt;
 # find . -name &amp;quot;*py&amp;quot; -exec dos2unix {} \;&lt;br /&gt;
 # find . -name &amp;quot;*py&amp;quot; -exec sed -i &#039;s/\t/    /g&#039; {} \;&lt;br /&gt;
 # find . -name &amp;quot;*py&amp;quot; -exec sed -i &#039;s/\s*$//&#039; {} \;&lt;br /&gt;
 find . -name &amp;quot;*py&amp;quot; -exec dos2unix {} \; -exec sed -i &#039;s/\t/    /g&#039; {} \; -exec sed -i &#039;s/\s*$//&#039; {} \;&lt;br /&gt;
&lt;br /&gt;
==== Trim Tailing White Space ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sed -e &#039;s/[[:space:]]*$//&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
find . -name &amp;quot;*.py&amp;quot; -exec sed -i -e &#039;s/[[:space:]]*$//&#039; {} \;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ref: [https://stackoverflow.com/questions/369758/how-to-trim-whitespace-from-a-bash-variable]&lt;br /&gt;
&lt;br /&gt;
=== Print ===&lt;br /&gt;
&lt;br /&gt;
print - http://docs.python.org/tutorial/inputoutput.html&lt;br /&gt;
&lt;br /&gt;
Print:  # include new line&lt;br /&gt;
 print(&amp;quot;Hello World&amp;quot;)&lt;br /&gt;
 print &amp;quot;Hello World&amp;quot;   # python 2 only&lt;br /&gt;
&lt;br /&gt;
Suppress new line: [http://stackoverflow.com/questions/493386/how-to-print-in-python-without-newline-or-space]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
print(&#039;#&#039;, end=&#039;&#039;)    # python 3&lt;br /&gt;
print &amp;quot;Hello World&amp;quot;,  # python 2 only (does produce a single separating white space though)&lt;br /&gt;
&lt;br /&gt;
import sys&lt;br /&gt;
sys.stdout.write(&#039;.&#039;)  # no separating white space&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 # flush output&lt;br /&gt;
 # optional, if new line won&#039;t come for some time&lt;br /&gt;
 import sys&lt;br /&gt;
 sys.stdout.flush()&lt;br /&gt;
&lt;br /&gt;
Multiple with separator:&lt;br /&gt;
 print(&amp;quot;hello&amp;quot;, &amp;quot;world&amp;quot;)  # separated by spaces&lt;br /&gt;
 print(&amp;quot;hello&amp;quot;, &amp;quot;world&amp;quot;, sep = &#039;.&#039;)  # separated by period&lt;br /&gt;
&lt;br /&gt;
Formatting:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mystr = &amp;quot;abc&amp;quot;&lt;br /&gt;
myint = 5&lt;br /&gt;
myflt = 3.141592&lt;br /&gt;
print( &amp;quot;%s %d %.3f&amp;quot; % (mystr, myint, myflt) )&lt;br /&gt;
print( &amp;quot;{0} {1} {2}&amp;quot;.format(mystr, myint, myflt) )  # string&#039;s format function (python &amp;gt; 2.7)&lt;br /&gt;
print( &amp;quot;{a} {b} {c}&amp;quot;.format( b = myint, a = mystr, c = myflt) )  # by name&lt;br /&gt;
print( &amp;quot;={a:4s}={b:3d}={c:10.3f}=&amp;quot;.format( b = myint, a = mystr, c = myflt) )  # type and padding&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Padded floating point decimal number: (rounds)&lt;br /&gt;
 print &amp;quot;%06.2f&amp;quot; % 2.319         # &amp;quot;002.32&amp;quot;&lt;br /&gt;
 print &amp;quot;%6.2f&amp;quot; % 2.311          # &amp;quot;  2.31&amp;quot;&lt;br /&gt;
 print &amp;quot;{:06.2f}&amp;quot;.format(2.319) # &amp;quot;002.32&amp;quot;&lt;br /&gt;
 print &amp;quot;{:6.2f}&amp;quot;.format(2.319)  # &amp;quot;  2.32&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 # Python 3 version where var=2.321234&lt;br /&gt;
 print(f&amp;quot;{var:.2f}&amp;quot;)  # &amp;quot;2.32&amp;quot;&lt;br /&gt;
 print(f&amp;quot;{var:6.2f}&amp;quot;)  # &amp;quot;  2.32&amp;quot;&lt;br /&gt;
 print(f&amp;quot;{var:06.2f}&amp;quot;)  # &amp;quot;002.32&amp;quot;&lt;br /&gt;
 print(f&amp;quot;{var:08.2f}&amp;quot;)  # &amp;quot;00002.32&amp;quot;&lt;br /&gt;
 print(f&amp;quot;{var:08.4f}&amp;quot;)  # &amp;quot;002.3212&amp;quot;&lt;br /&gt;
 # Python 3 version where var=2.329 - rounding&lt;br /&gt;
 print(f&amp;quot;{var:06.2f}&amp;quot;)  # &amp;quot;002.33&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Comments ===&lt;br /&gt;
&lt;br /&gt;
 # this is a comment&lt;br /&gt;
 # this is a comment&lt;br /&gt;
 x = y  # this is a comment&lt;br /&gt;
&lt;br /&gt;
Using a non assigned string constant as a comment: (also used for doc strings, not generally recommended)&lt;br /&gt;
 &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
 multi line comment&lt;br /&gt;
 &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;&#039;&lt;br /&gt;
 multi line comment can comment out &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
 &#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This can be used like a C &amp;quot;#if 0&amp;quot; concept to comment out whole sections of code.&lt;br /&gt;
&lt;br /&gt;
Using false block to comment out a block code: (does not ignore bad syntax though)&lt;br /&gt;
 if False:&lt;br /&gt;
    # code in this block is ignored&lt;br /&gt;
&lt;br /&gt;
=== doc strings ===&lt;br /&gt;
&lt;br /&gt;
Using a non assigned string constant as a comment: (also used for doc strings, not generally recommended)&lt;br /&gt;
 &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
 multi line comment&lt;br /&gt;
 &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Variable Type ===&lt;br /&gt;
&lt;br /&gt;
 print( type(myvar).__name__ )&lt;br /&gt;
&lt;br /&gt;
Used to be able to just print the type(myvar), but this doesn&#039;t seem to work anymore :-(&lt;br /&gt;
&lt;br /&gt;
== Variable Directory ===&lt;br /&gt;
&lt;br /&gt;
All of the properties and functions of a variable or object&lt;br /&gt;
&lt;br /&gt;
 print( dir(myvar) )&lt;br /&gt;
&lt;br /&gt;
=== Help ===&lt;br /&gt;
&lt;br /&gt;
dir - list functions and properties of objects:&lt;br /&gt;
 import math&lt;br /&gt;
 dir(math)  # module&lt;br /&gt;
 dir(dir)   # function&lt;br /&gt;
 dir(&amp;quot;&amp;quot;)    # object  - &amp;quot;&amp;quot;, [], {}, etc...&lt;br /&gt;
 dir(__builtins__)  # built in functions&lt;br /&gt;
 dir()      # list imported objects, and dunder methods&lt;br /&gt;
&lt;br /&gt;
Note: dunder (double under) methods determine special functionality (eg. __add__ for +)&lt;br /&gt;
&lt;br /&gt;
help - manual printout: (class doc string, function doc string, data, etc)&lt;br /&gt;
 import math&lt;br /&gt;
 help(math)    # full module info&lt;br /&gt;
 help(len)     # full function info&lt;br /&gt;
 help([&amp;quot;foo&amp;quot;]) # full object info&lt;br /&gt;
&lt;br /&gt;
Pydoc: (command line, same as &#039;import math, help(math)&#039;&lt;br /&gt;
 $ pydoc math&lt;br /&gt;
&lt;br /&gt;
Documentation String: (aka docstring, doc string)&lt;br /&gt;
 print(math.pow.__doc__)  # module doc string&lt;br /&gt;
 print(len.__doc__)       # function doc string&lt;br /&gt;
&lt;br /&gt;
Object or function type:&lt;br /&gt;
 type(x)&lt;br /&gt;
&lt;br /&gt;
 mylist = []&lt;br /&gt;
 isinstance(mylist, list)  # True&lt;br /&gt;
 type(s) is list           # True&lt;br /&gt;
&lt;br /&gt;
Note: isinstance() and type() not equivalent when objects and subclass get involved&lt;br /&gt;
&lt;br /&gt;
IDLE interactive help:&lt;br /&gt;
 help()&lt;br /&gt;
&lt;br /&gt;
=== Variables ===&lt;br /&gt;
&lt;br /&gt;
Basic Data Types&lt;br /&gt;
 str = &amp;quot;string&amp;quot;  # string&lt;br /&gt;
 num = 5         # integer&lt;br /&gt;
 flt = 5.0       # float&lt;br /&gt;
 nothing = None  # None  (not the same as undefined)&lt;br /&gt;
&lt;br /&gt;
Undefined.  Variables start off in an &#039;undefined&#039; state.  It is always better to initially set the variable to None to avoid this state.  To check if undefined: [http://code.activestate.com/recipes/59892-testing-if-a-variable-is-defined/] [http://code.activestate.com/recipes/59892/]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 try:&lt;br /&gt;
   x&lt;br /&gt;
 except NameError:&lt;br /&gt;
   x = None&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Rules: [http://www.python.org/dev/peps/pep-0008/ PEP8 - Method Names and Instance Variables]&lt;br /&gt;
* any length&lt;br /&gt;
* letters, numbers, underscore&lt;br /&gt;
* first character can&#039;t be number&lt;br /&gt;
* case sensitive&lt;br /&gt;
* cannot use keywords&lt;br /&gt;
&lt;br /&gt;
Multiple assignment:&lt;br /&gt;
 x = y = z = 0              # Zero x, y and z&lt;br /&gt;
 x, y, z = 1, &amp;quot;two&amp;quot;, 3.0    # x = 1, y = &amp;quot;two&amp;quot;, z = 3.0&lt;br /&gt;
&lt;br /&gt;
Swap variables: (done in parallel)&lt;br /&gt;
 a, b = b, a&lt;br /&gt;
&lt;br /&gt;
Unpack variables: (requires equal items on each side)&lt;br /&gt;
 a, b, c = [1, 2, 3]&lt;br /&gt;
&lt;br /&gt;
Other Data Types:&lt;br /&gt;
* tuple&lt;br /&gt;
* list&lt;br /&gt;
* dictionary&lt;br /&gt;
* set&lt;br /&gt;
* objects&lt;br /&gt;
&lt;br /&gt;
Everything in Python is an object that has:&lt;br /&gt;
* identity:  id(obj)&lt;br /&gt;
* type:  type(obj)&lt;br /&gt;
* value:  obj&lt;br /&gt;
** mutable - id() stays the same on modification (dictionary, lists, objects)&lt;br /&gt;
** immutable - id() changes on modification as new object is created (string, integer, tuple)&lt;br /&gt;
&lt;br /&gt;
==== Check if Variable Exists ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
try:&lt;br /&gt;
    a # does a exist in the current namespace&lt;br /&gt;
except NameError:&lt;br /&gt;
    a = 10 # nope&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &#039;a&#039; in vars() or &#039;a&#039; in globals()&lt;br /&gt;
 &#039;a&#039; in vars(__builtins__)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if hasattr(a, &#039;property&#039;):&lt;br /&gt;
    doStuff(a.property)&lt;br /&gt;
else:&lt;br /&gt;
    otherStuff()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ref: [https://stackoverflow.com/questions/1592565/determine-if-variable-is-defined-in-python] [https://stackoverflow.com/questions/610883/how-to-know-if-an-object-has-an-attribute-in-python]&lt;br /&gt;
&lt;br /&gt;
=== Numbers ===&lt;br /&gt;
&lt;br /&gt;
 num = 5&lt;br /&gt;
 print &amp;quot;num: %d&amp;quot; % num&lt;br /&gt;
&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; print &amp;quot;Today&#039;s stock price: %f&amp;quot; % 50.4625   1&lt;br /&gt;
 50.462500&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; print &amp;quot;Today&#039;s stock price: %.2f&amp;quot; % 50.4625 2&lt;br /&gt;
 50.46&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; print &amp;quot;Change since yesterday: %+.2f&amp;quot; % 1.5 3&lt;br /&gt;
 +1.50&lt;br /&gt;
&lt;br /&gt;
Arithmetic:&lt;br /&gt;
 + - * /&lt;br /&gt;
 //  # integer division&lt;br /&gt;
 %   # modulus&lt;br /&gt;
 **  # exponent&lt;br /&gt;
&lt;br /&gt;
Compact Arithmetic:&lt;br /&gt;
 i+=1  # Increment - Note, there is no &#039;i++&#039;&lt;br /&gt;
 i*=2  # Multiply&lt;br /&gt;
 i%=2  # modulus&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
Math Functions:&lt;br /&gt;
 import math&lt;br /&gt;
 math.ceil(x)&lt;br /&gt;
 math.floor(x)&lt;br /&gt;
 math.trunc(x)&lt;br /&gt;
 math.pow(x,y)&lt;br /&gt;
&lt;br /&gt;
 abs(x)  # built in&lt;br /&gt;
&lt;br /&gt;
String interpolation:&lt;br /&gt;
 %% % character&lt;br /&gt;
 %d integer&lt;br /&gt;
 %x hex&lt;br /&gt;
 %X hex (upper)&lt;br /&gt;
 %f float&lt;br /&gt;
 %s string&lt;br /&gt;
&lt;br /&gt;
 x = 1/81&lt;br /&gt;
 print(&#039;value: %.2f&#039; % x)  # 0.01&lt;br /&gt;
 print(&#039;value: %.5f&#039; % x)  # 0.012345&lt;br /&gt;
 print(&#039;%d %d %d&#039; % (1, 2, 3))&lt;br /&gt;
&lt;br /&gt;
Type check:&lt;br /&gt;
 if not isinstance(myvar, (int, float)): ...&lt;br /&gt;
&lt;br /&gt;
=== Strings ===&lt;br /&gt;
&lt;br /&gt;
STRINGS ARE IMMUTABLE!  (to modify convert to a list)&lt;br /&gt;
&lt;br /&gt;
Strings: (String Constants)&lt;br /&gt;
 str = &amp;quot;Hello&amp;quot;&lt;br /&gt;
 str = &#039;Hello&#039;&lt;br /&gt;
 str = &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
   Hello&lt;br /&gt;
   World&lt;br /&gt;
 &amp;quot;&amp;quot;&amp;quot;      # can also use &#039;&#039;&#039;...&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
String literals can span multiple lines: (no wrapping when \ used)&lt;br /&gt;
 hello = &amp;quot;hello\&lt;br /&gt;
 world&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Length:&lt;br /&gt;
 len(&amp;quot;str&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Raw string: (back slashes are not escaped)&lt;br /&gt;
 myrawstr = r&amp;quot;hello\nworld\&lt;br /&gt;
 how are you&amp;quot;&lt;br /&gt;
 myrawstr = r&amp;quot;C:\&amp;quot;  # ERROR - limitation of what won&#039;t be escaped&lt;br /&gt;
&lt;br /&gt;
Concatenation:&lt;br /&gt;
 str = &#039;hot&#039; + &#039;dog&#039;&lt;br /&gt;
 print &amp;quot;Hello&amp;quot; &amp;quot;World&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Can&#039;t concat numbers&lt;br /&gt;
 str = 5 + &#039;test&#039;  # error&lt;br /&gt;
 num = 5&lt;br /&gt;
 str = num + &#039;test&#039;  # error&lt;br /&gt;
 str = str(5) + str(num) + &#039;test&#039;  # ok&lt;br /&gt;
&lt;br /&gt;
Repeated Concatenation:&lt;br /&gt;
 str = 10 * &#039;ha&#039;&lt;br /&gt;
 str = &#039;ha&#039; * 10  # same&lt;br /&gt;
 print &#039;-&#039;*60  # --------------------&lt;br /&gt;
&lt;br /&gt;
String Indexing:&lt;br /&gt;
 s = &#039;hello&#039;&lt;br /&gt;
 print( s[0] )    # is &#039;h&#039;&lt;br /&gt;
 print( s[-1] )   # is &#039;o&#039;&lt;br /&gt;
 print( s[len(s) - 1 ] )  # is also &#039;o&#039;&lt;br /&gt;
&lt;br /&gt;
Modify Strings: [http://stackoverflow.com/questions/1228299/change-one-character-in-a-string-in-python]&lt;br /&gt;
 s[1] = &#039;x&#039;  # ERROR!&lt;br /&gt;
 ERROR: can&#039;t modify string by index&lt;br /&gt;
 &lt;br /&gt;
 # solution:&lt;br /&gt;
 s = list(&amp;quot;Hello World&amp;quot;)&lt;br /&gt;
 s[0] = &#039;C&#039;&lt;br /&gt;
 print( &amp;quot;&amp;quot;.join(s) )&lt;br /&gt;
&lt;br /&gt;
String Slicing:&lt;br /&gt;
 s = &#039;hello&#039;&lt;br /&gt;
 print( s[0:3] )  # &#039;hel&#039;&lt;br /&gt;
 i = 1&lt;br /&gt;
 print( s[i:i+1] )  # &#039;e&#039;&lt;br /&gt;
 print( s[:3] )  # 0:3 &#039;hel&#039;&lt;br /&gt;
 print( s[4:] )  # 4:end &#039;o&#039;&lt;br /&gt;
 print( s[:] )  # start:end &#039;hello&#039;&lt;br /&gt;
 print( s[-2:] )  # -2:end &#039;lo&#039;&lt;br /&gt;
&lt;br /&gt;
For loop:&lt;br /&gt;
 s = &#039;hello&#039;&lt;br /&gt;
 for c in s:&lt;br /&gt;
   print c  # c = &#039;h&#039; first time&lt;br /&gt;
&lt;br /&gt;
Escape characters:&lt;br /&gt;
 \\  \&#039;  \&amp;quot;  \n  \r  \t&lt;br /&gt;
&lt;br /&gt;
Alternate loop:&lt;br /&gt;
 s = &#039;hello&#039;&lt;br /&gt;
 for i in range( len(s) ):&lt;br /&gt;
   print s[i]&lt;br /&gt;
&lt;br /&gt;
Ord and Char (ASCII):&lt;br /&gt;
 ord(&#039;a&#039;)  # 97&lt;br /&gt;
 chr(97)   # &#039;a&#039;&lt;br /&gt;
&lt;br /&gt;
 0-9 : 48-57&lt;br /&gt;
 A-Z : 65-90&lt;br /&gt;
 a-z : 97-122&lt;br /&gt;
&lt;br /&gt;
List Functions:  (dir on any string)&lt;br /&gt;
 dir(&#039;&#039;)&lt;br /&gt;
 dir(str)&lt;br /&gt;
&lt;br /&gt;
Help:&lt;br /&gt;
 help(&#039;&#039;)&lt;br /&gt;
 help(str)&lt;br /&gt;
&lt;br /&gt;
Padding:&lt;br /&gt;
 &amp;quot;a&amp;quot;.rjust(2, &#039;0&#039;)  # &#039;0a&#039;&lt;br /&gt;
 &amp;quot;1&amp;quot;.ljust(4, &#039;0&#039;)  # &#039;1000&#039;&lt;br /&gt;
&lt;br /&gt;
String Test Functions:&lt;br /&gt;
 &amp;quot;HELLO&amp;quot;.isupper()   # True&lt;br /&gt;
 &amp;quot;hello&amp;quot;.islower()   # True&lt;br /&gt;
 &amp;quot;hello&amp;quot;.isalpha()   # True&lt;br /&gt;
 &amp;quot;12.22&amp;quot;.isdigit()   # False (because of &#039;.&#039;)&lt;br /&gt;
 &amp;quot;12.22&amp;quot;.isnumeric() # False (because of &#039;.&#039;)&lt;br /&gt;
 &amp;quot;hel2&amp;quot;.isalnum()    # True&lt;br /&gt;
 &amp;quot;e&amp;quot; in &amp;quot;hello&amp;quot;      # True&lt;br /&gt;
 &amp;quot;hello&amp;quot;.startswith(&#039;he&#039;)  # True&lt;br /&gt;
 &amp;quot;hello&amp;quot;.endswith(&#039;lo&#039;)    # True&lt;br /&gt;
&lt;br /&gt;
Note: To check for floats: [http://stackoverflow.com/questions/354038/how-do-i-check-if-a-string-is-a-number-in-python]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def is_number(s):&lt;br /&gt;
    try:&lt;br /&gt;
        float(s)&lt;br /&gt;
        return True&lt;br /&gt;
    except ValueError:&lt;br /&gt;
        return False&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
String Modify Functions: (sort of... Strings are immutable)&lt;br /&gt;
 &amp;quot;HELLO&amp;quot;.lower()           # &#039;hello&#039;&lt;br /&gt;
 &amp;quot;hello&amp;quot;.upper()           # &#039;HELLO&#039;&lt;br /&gt;
 &amp;quot; hello &amp;quot;.strip()         # &#039;hello&#039; remove leading/tailing whitespace&lt;br /&gt;
 &amp;quot; hello &amp;quot;.lstrip()        # &#039;hello &#039; remove left whitespace&lt;br /&gt;
 &amp;quot; hello &amp;quot;.rstrip()        # &#039; hello&#039; remove right whitespace&lt;br /&gt;
 &amp;quot;www.com&amp;quot;.split(&#039;.&#039;)      # [&#039;www&#039;, &#039;com&#039;]   &amp;lt;- list&lt;br /&gt;
 &amp;quot;www.com&amp;quot;.partition(&#039;.&#039;)  # (&#039;www&#039;, &#039;.&#039;, &#039;com&#039;)  &amp;lt;- tuple&lt;br /&gt;
 &amp;quot;&amp;quot;.join( (&#039;a&#039;,&#039;b&#039;,&#039;c&#039;) )  # &amp;quot;abc&amp;quot;  join strings, list or tuple&lt;br /&gt;
 &amp;quot;-&amp;quot;.join( (&#039;a&#039;,&#039;b&#039;,&#039;c&#039;) ) # &amp;quot;a-b-c&amp;quot;  join with separator&lt;br /&gt;
 &amp;quot;23&amp;quot;.zfill(4)             # &amp;quot;0023&amp;quot;&lt;br /&gt;
&lt;br /&gt;
String Search Functions:&lt;br /&gt;
 &amp;quot;hello&amp;quot;.find(&#039;lo&#039;)   # 3  (-1 on fail)&lt;br /&gt;
 &amp;quot;hello&amp;quot;.index(&#039;lo&#039;)  # 3 (exception on fail)&lt;br /&gt;
 &amp;quot;hello&amp;quot;.rfind(&#039;lo&#039;)  # 3 right to left (-1 on fail)&lt;br /&gt;
 &amp;quot;hello&amp;quot;.rindex(&#039;lo&#039;) # 3 right to left (exception on fail)&lt;br /&gt;
&lt;br /&gt;
Formatting: (form of concatenation)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mystr = &amp;quot;abc&amp;quot;&lt;br /&gt;
myint = 5&lt;br /&gt;
myflt = 3.141592&lt;br /&gt;
print( &amp;quot;%s %d %.3f&amp;quot; % (mystr, myint, myflt) )&lt;br /&gt;
print( &amp;quot;{0} {1} {2}&amp;quot;.format(mystr, myint, myflt) )  # pep 3101 style - string&#039;s format function (python &amp;gt; 2.7)&lt;br /&gt;
print( &amp;quot;{a} {b} {c}&amp;quot;.format( b = myint, a = mystr, c = myflt) )  # by name&lt;br /&gt;
print( &amp;quot;={a:4s}={b:3d}={c:10.3f}=&amp;quot;.format( b = myint, a = mystr, c = myflt) )  # type and padding&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Split multi line string:&lt;br /&gt;
 for line in str.split(&#039;\n&#039;):  print(line)&lt;br /&gt;
 lines = str.splitlines()      # returns list&lt;br /&gt;
 lines = str.splitlines(True)  # returns list (each includes new line characters)&lt;br /&gt;
&lt;br /&gt;
Input a string:&lt;br /&gt;
 name = input(&#039;What is your name: &#039;).strip()  # python 3&lt;br /&gt;
 name = raw_input(&#039;What is your name: &#039;).strip()  # python 2&lt;br /&gt;
&lt;br /&gt;
Leet Speak:&lt;br /&gt;
 leet_table = &#039;&#039;.maketrans(&#039;EIOBT&#039;, &#039;31087&#039;)&lt;br /&gt;
 &#039;BE COOL. SPEAK LEET!&#039;.translate(leet_table)&lt;br /&gt;
&lt;br /&gt;
String Functions:&lt;br /&gt;
 newstr = mystr.strip()             # remove white space on both sides&lt;br /&gt;
 newstr = mystr.rstrip()            # remove white space on right side&lt;br /&gt;
 newstr = mystr.lstrip()            # remove white space on left side&lt;br /&gt;
 newstr = mystr.replace(&#039;\n&#039;, &#039; &#039;)  # replace string with another&lt;br /&gt;
 newstr = mystr.replace(&#039;jello&#039;, &#039;hello&#039;)  # replace string with another&lt;br /&gt;
&lt;br /&gt;
==== String Formatting ====&lt;br /&gt;
&lt;br /&gt;
PyFormat: Using % and .format() for great good! - https://pyformat.info/&lt;br /&gt;
&lt;br /&gt;
===== Zero Padding =====&lt;br /&gt;
&lt;br /&gt;
3 zero padding:&lt;br /&gt;
 &amp;quot;{:03}&amp;quot;.format(1)  # 003&lt;br /&gt;
&lt;br /&gt;
3 zero padding, specify position:&lt;br /&gt;
 &amp;quot;{1:03}&amp;quot;.format(1, 2)  # 002&lt;br /&gt;
&lt;br /&gt;
Old method:&lt;br /&gt;
 &amp;quot;%03d&amp;quot; % 2  # 002&lt;br /&gt;
&lt;br /&gt;
=== chr and ord ===&lt;br /&gt;
&lt;br /&gt;
Ord and Char (ASCII):&lt;br /&gt;
 ord(&#039;a&#039;)  # 97&lt;br /&gt;
 chr(97)   # &#039;a&#039;&lt;br /&gt;
&lt;br /&gt;
=== Range ===&lt;br /&gt;
&lt;br /&gt;
Creates a list of numbers.  Remember: range always ends one less than you want!&lt;br /&gt;
&lt;br /&gt;
Count:&lt;br /&gt;
 ten = 10&lt;br /&gt;
 one = 1&lt;br /&gt;
 range(ten)               # [0,1,...,9]   starts with zero by default&lt;br /&gt;
 range(one, ten + 1)      # [1,...,10]    actually get 1 to 10&lt;br /&gt;
 range(ten, one - 1, -1)  # [10,9,...,1]  count down&lt;br /&gt;
 range(2, 10 + 1, 2)      # [2,4,...,10]  even numbers&lt;br /&gt;
&lt;br /&gt;
=== drange ===&lt;br /&gt;
&lt;br /&gt;
Solution for decimal range() step value:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def drange(start, stop, step):&lt;br /&gt;
    r = start&lt;br /&gt;
    while r &amp;lt; stop:&lt;br /&gt;
        yield r&lt;br /&gt;
    r += step&lt;br /&gt;
&lt;br /&gt;
sub_ten = drange(0.0, 1.0, 0.1)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* floating point - Python decimal range() step value - Stack Overflow - http://stackoverflow.com/questions/477486/python-decimal-range-step-value&lt;br /&gt;
&lt;br /&gt;
=== Casting ===&lt;br /&gt;
&lt;br /&gt;
Convert:&lt;br /&gt;
 float(3)&lt;br /&gt;
 str(85)&lt;br /&gt;
 int(8.6)&lt;br /&gt;
 round(5.5)&lt;br /&gt;
&lt;br /&gt;
Check Type:&lt;br /&gt;
 type(5)     # &amp;lt;class &#039;int&#039;&amp;gt;&lt;br /&gt;
 type(5.0)   # &amp;lt;class &#039;float&#039;&amp;gt;&lt;br /&gt;
 type(&#039;5&#039;)   # &amp;lt;class &#039;str&#039;&amp;gt;&lt;br /&gt;
 type(None)  # &amp;lt;class &#039;NoneType&#039;&amp;gt;&lt;br /&gt;
 type(print) # &amp;lt;class &#039;builtin_function_or_method&#039;&amp;gt;&lt;br /&gt;
 type(())    # &amp;lt;class &#039;tuple&#039;&amp;gt;&lt;br /&gt;
 type([])    # &amp;lt;class &#039;list&#039;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 mytype = int&lt;br /&gt;
 if type(1) is mytype: ...&lt;br /&gt;
&lt;br /&gt;
=== Boolean Logic ===&lt;br /&gt;
&lt;br /&gt;
True and False:&lt;br /&gt;
 bol = True&lt;br /&gt;
 bol = False&lt;br /&gt;
&lt;br /&gt;
Boolean Operators: (in order precedence)&lt;br /&gt;
 a == b&lt;br /&gt;
 a != b&lt;br /&gt;
 not a&lt;br /&gt;
 a and b&lt;br /&gt;
 a or b&lt;br /&gt;
&lt;br /&gt;
Note: Short-circuit evaluated - &#039;and&#039; and &#039;or&#039;&lt;br /&gt;
&lt;br /&gt;
Return Boolean:&lt;br /&gt;
 return myint &amp;gt;= 16&lt;br /&gt;
&lt;br /&gt;
Get Boolean from string: [http://stackoverflow.com/questions/715417/converting-from-a-string-to-boolean-in-python]&lt;br /&gt;
 # Note: no built in way to do this&lt;br /&gt;
&lt;br /&gt;
 myString = &amp;quot;false&amp;quot;&lt;br /&gt;
 val = (myString == &amp;quot;true&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
 True if myString==&amp;quot;True&amp;quot; else False&lt;br /&gt;
&lt;br /&gt;
 s in [&#039;true&#039;, &#039;1&#039;, &#039;t&#039;, &#039;y&#039;, &#039;yes&#039;, &#039;yeah&#039;, &#039;yup&#039;, &#039;certainly&#039;, &#039;uh-huh&#039;]&lt;br /&gt;
&lt;br /&gt;
 def str2bool(v):&lt;br /&gt;
   return v.lower() in (&amp;quot;yes&amp;quot;, &amp;quot;true&amp;quot;, &amp;quot;t&amp;quot;, &amp;quot;1&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
=== None ===&lt;br /&gt;
&lt;br /&gt;
None is Python&#039;s version of NULL or NIL.&lt;br /&gt;
&lt;br /&gt;
None is a singleton (Python only has one copy of None in the interpreter).&lt;br /&gt;
&lt;br /&gt;
 if myvar is None:&lt;br /&gt;
     ...&lt;br /&gt;
&lt;br /&gt;
=== If Conditionals ===&lt;br /&gt;
&lt;br /&gt;
Operators:&lt;br /&gt;
 ==, !=, not, and, or, &amp;lt;, &amp;gt;, &amp;lt;&amp;gt;, &amp;lt;=, &amp;gt;=, in, not in, is, is not&lt;br /&gt;
&lt;br /&gt;
If statement:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if a == b:&lt;br /&gt;
  ...&lt;br /&gt;
elif c &amp;lt; age &amp;lt; d:&lt;br /&gt;
  ...&lt;br /&gt;
else:&lt;br /&gt;
  ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Shorthand conditional: (ternary operator)&lt;br /&gt;
 val = True if a == b else False&lt;br /&gt;
&lt;br /&gt;
is - checks for identical objects - same id()&lt;br /&gt;
 # None is a singleton, so this works great for None&lt;br /&gt;
 if myvar is None:&lt;br /&gt;
     ...&lt;br /&gt;
&lt;br /&gt;
Other shorthand:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def mycmp(x, y):&lt;br /&gt;
  if x &amp;gt; y: return True&lt;br /&gt;
  else: return False&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Switch/Case statement:&lt;br /&gt;
* there is no built in switch/case statement, use &amp;quot;if ... elif ... elif ...&amp;quot; sequence instead&lt;br /&gt;
&lt;br /&gt;
=== For Loop ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;for&#039;&#039; is used for iterating over an iterable sequence (eg. lists, dictionaries, tuples). (for each)&lt;br /&gt;
&lt;br /&gt;
# range(start, end + 1, skip)&lt;br /&gt;
&lt;br /&gt;
 for i in range(10):&lt;br /&gt;
   print(i)  # 0 .. 9&lt;br /&gt;
&lt;br /&gt;
 for i in range(5, 10):&lt;br /&gt;
   print(i)  # 5 .. 9&lt;br /&gt;
&lt;br /&gt;
 for i in range(10, 0, -1):&lt;br /&gt;
   print(i)  # 10 .. 1&lt;br /&gt;
&lt;br /&gt;
 for i in [1, 2, 3]:  # iterate over list&lt;br /&gt;
   print(i)  # 1 2 3&lt;br /&gt;
&lt;br /&gt;
Discard variable: [http://bytes.com/topic/python/answers/757444-loop-without-variable]&lt;br /&gt;
 for _ in range(10):  # repeat and discard variable (good for pep8 check)&lt;br /&gt;
   print &amp;quot;hello world&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 for key in my_dict.keys(): ...&lt;br /&gt;
 for value in my_dict.values(): ...&lt;br /&gt;
 for key, value in my_dict.items(): ...&lt;br /&gt;
&lt;br /&gt;
Compact version:&lt;br /&gt;
 for i in range(10): print(i)    # 0 .. 9&lt;br /&gt;
&lt;br /&gt;
Access index: [http://stackoverflow.com/questions/522563/accessing-the-index-in-python-for-loops]&lt;br /&gt;
 # using enumeration&lt;br /&gt;
 for idx, val in enumerate(mylist):&lt;br /&gt;
   print idx, val&lt;br /&gt;
&lt;br /&gt;
 # using range&lt;br /&gt;
 for ix in range(len(mylist)):&lt;br /&gt;
   print mylist[ix]&lt;br /&gt;
&lt;br /&gt;
 # list comprehension&lt;br /&gt;
 [ (ix, mylist[ix]) for ix in range(len(mylist))]&lt;br /&gt;
&lt;br /&gt;
=== While Loop ===&lt;br /&gt;
&lt;br /&gt;
 i = 0&lt;br /&gt;
 while i &amp;lt; 10:&lt;br /&gt;
   i = i + 1&lt;br /&gt;
&lt;br /&gt;
 while True:&lt;br /&gt;
   ...  # infinite loop&lt;br /&gt;
&lt;br /&gt;
=== Breaking Loops ===&lt;br /&gt;
&lt;br /&gt;
break statement:&lt;br /&gt;
 while True:&lt;br /&gt;
   if s == &#039;done&#039;:&lt;br /&gt;
     break  # jump out of the loop&lt;br /&gt;
   ...&lt;br /&gt;
&lt;br /&gt;
continue statement: (works with while too)&lt;br /&gt;
  for i in range(10):&lt;br /&gt;
    if i == 2:&lt;br /&gt;
      continue  # skip 2&lt;br /&gt;
    ...&lt;br /&gt;
&lt;br /&gt;
=== Functions ===&lt;br /&gt;
&lt;br /&gt;
No return value:  (None)&lt;br /&gt;
 x = print(&#039;&#039;)&lt;br /&gt;
 # x is &#039;None&#039;&lt;br /&gt;
&lt;br /&gt;
Note: specifying no return value is the same as this:&lt;br /&gt;
 return None&lt;br /&gt;
&lt;br /&gt;
No Operation - &#039;pass&#039;:&lt;br /&gt;
 def noop():&lt;br /&gt;
   pass&lt;br /&gt;
&lt;br /&gt;
Function:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def area(radius):&lt;br /&gt;
  &amp;quot;&amp;quot;&amp;quot; This is a doc string &amp;quot;&amp;quot;&amp;quot;   # can be &amp;quot; ... &amp;quot; also...&lt;br /&gt;
  import math&lt;br /&gt;
  return math.pi * radius ** 2&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Function Doc string:&lt;br /&gt;
 print(area.__doc__)&lt;br /&gt;
 foo.func_doc&lt;br /&gt;
&lt;br /&gt;
Function name:&lt;br /&gt;
  foo.func_name&lt;br /&gt;
&lt;br /&gt;
Local variable:&lt;br /&gt;
 name = &amp;quot;old&amp;quot;&lt;br /&gt;
 def cname():&lt;br /&gt;
   name = &amp;quot;new&amp;quot;&lt;br /&gt;
 print(name)  # is still &#039;old&#039;&lt;br /&gt;
&lt;br /&gt;
Global variable:&lt;br /&gt;
 name = &amp;quot;old&amp;quot;&lt;br /&gt;
 def cname():&lt;br /&gt;
   global name&lt;br /&gt;
   name = &amp;quot;new&amp;quot;&lt;br /&gt;
 cname()&lt;br /&gt;
 print(name)  # is now &#039;new&#039;&lt;br /&gt;
&lt;br /&gt;
By convention starting point is: (not required)&lt;br /&gt;
 def main():&lt;br /&gt;
&lt;br /&gt;
Parameters: (with default)&lt;br /&gt;
 def foo(x, y, z = &amp;quot;default&amp;quot;):&lt;br /&gt;
&lt;br /&gt;
Note: don&#039;t use mutable for defaults, as the object is remembered across runs! (unless that is what you want)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# each call to t() will increase list&lt;br /&gt;
def t(foo=[]):&lt;br /&gt;
   foo.append(&#039;1&#039;)&lt;br /&gt;
   print(foo)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# fix mutable issue&lt;br /&gt;
def named_param(a, foo=None):&lt;br /&gt;
  foo = foo or []&lt;br /&gt;
  if not foo:&lt;br /&gt;
    foo.append(a)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Parameters by keyword:&lt;br /&gt;
 def foo(x = &#039;1&#039;, y = &#039;2&#039;, z = &#039;3&#039;):&lt;br /&gt;
   ...&lt;br /&gt;
 foo(y = &#039;a&#039;, x = &#039;b&#039;)   # order is not important with keywords&lt;br /&gt;
&lt;br /&gt;
Trick for optional parameter:&lt;br /&gt;
 def do(x = None):&lt;br /&gt;
   if x == None:&lt;br /&gt;
&lt;br /&gt;
Function tests - functions are callable&lt;br /&gt;
 callable(myfunc)&lt;br /&gt;
&lt;br /&gt;
=== Type Hints ===&lt;br /&gt;
&lt;br /&gt;
: &amp;quot;Note The Python runtime does not enforce function and variable type annotations. They can be used by third party tools such as type checkers, IDEs, linters, etc.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 def surface_area_of_cube(edge_length: float) -&amp;gt; str:&lt;br /&gt;
     return f&amp;quot;The surface area of the cube is {6 * edge_length ** 2}.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Without the hints:&lt;br /&gt;
 def surface_area_of_cube(edge_length):&lt;br /&gt;
     ...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ref: https://docs.python.org/3/library/typing.html&lt;br /&gt;
&lt;br /&gt;
=== Pass ===&lt;br /&gt;
&lt;br /&gt;
Pass is a null operation (noop):&lt;br /&gt;
&lt;br /&gt;
Do nothing, noop, take no action:&lt;br /&gt;
 pass&lt;br /&gt;
&lt;br /&gt;
Great for creating minimal classes:&lt;br /&gt;
 class MyEmptyClass:&lt;br /&gt;
   pass&lt;br /&gt;
&lt;br /&gt;
Greate for making stub functions/methods:&lt;br /&gt;
 def initlog(*args):&lt;br /&gt;
   pass  # remember to implement this!&lt;br /&gt;
&lt;br /&gt;
=== Slice ===&lt;br /&gt;
&lt;br /&gt;
Take take a slice of strings, lists, tuples, etc...&lt;br /&gt;
 a = [0,1,2,3,4,5]&lt;br /&gt;
 a[0]    # 0 - not a slice&lt;br /&gt;
 a[-1]   # 5 - not a slice&lt;br /&gt;
 a[0:1]  # [0]&lt;br /&gt;
 a[1:3]  # [1, 2]&lt;br /&gt;
 a[:2]   # [0, 1]&lt;br /&gt;
 a[:-1]  # [0, 1, 2, 3, 4] - all but last&lt;br /&gt;
 a[2:]   # [2, 3, 4, 5]&lt;br /&gt;
 a[::2]  # [0, 2, 4] - stride&lt;br /&gt;
 a[::-1] # [5, 4, 3, 2, 1, 0] - reverse&lt;br /&gt;
 range(0,10)[::2]  # [0, 2, 4, 6, 8] - stride&lt;br /&gt;
&lt;br /&gt;
 a = &#039;012345&#039;&lt;br /&gt;
 a[1:3]  # &#039;12&#039;&lt;br /&gt;
 a[::2]  # &#039;024&#039;&lt;br /&gt;
&lt;br /&gt;
=== [http://docs.python.org/reference/compound_stmts.html Compound Statements] ===&lt;br /&gt;
&lt;br /&gt;
Compound statements: (generally discouraged)&lt;br /&gt;
 fun1(); fun2(); fun3()&lt;br /&gt;
&lt;br /&gt;
Compound with statements: [http://docs.python.org/reference/compound_stmts.html#the-with-statement]&lt;br /&gt;
 with A() as a, B() as b: ...&lt;br /&gt;
&lt;br /&gt;
 #is equivalent to&lt;br /&gt;
 with A() as a:&lt;br /&gt;
     with B() as b:&lt;br /&gt;
         ...&lt;br /&gt;
&lt;br /&gt;
[http://www.python.org/dev/peps/pep-0343 PEP 0343] - The “with” statement&lt;br /&gt;
&lt;br /&gt;
 f = open(&#039;file&#039;)&lt;br /&gt;
 with f: ...&lt;br /&gt;
&lt;br /&gt;
Try: (quick ignore all exceptions, very dangerous)&lt;br /&gt;
 try: my_broken_function()&lt;br /&gt;
 except: pass&lt;br /&gt;
&lt;br /&gt;
=== Passing Command Line Arguments ===&lt;br /&gt;
&lt;br /&gt;
Parameters are stored in the &#039;sys.argv&#039; variable:&lt;br /&gt;
 import sys&lt;br /&gt;
 print( sys.argv[0] )  # name of script&lt;br /&gt;
 print( sys.argv[1] )  # first argument&lt;br /&gt;
 for arg in sys.argv: print( arg )  # list all arguments&lt;br /&gt;
&lt;br /&gt;
Print script name:&lt;br /&gt;
 os.path.basename(sys.argv[0])&lt;br /&gt;
&lt;br /&gt;
Print path to script:&lt;br /&gt;
 print sys.path[0]&lt;br /&gt;
&lt;br /&gt;
Paths: [http://code.activestate.com/recipes/474083-get-the-path-of-the-currently-executing-python-scr/]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import os,sys&lt;br /&gt;
print &amp;quot;CWD: &amp;quot;,os.getcwd()&lt;br /&gt;
print &amp;quot;Script: &amp;quot;,sys.argv[0]&lt;br /&gt;
print &amp;quot;.EXE: &amp;quot;,os.path.dirname(sys.executable)&lt;br /&gt;
print &amp;quot;Script dir: &amp;quot;, os.path.realpath(os.path.dirname(sys.argv[0]))&lt;br /&gt;
pathname, scriptname = os.path.split(sys.argv[0])&lt;br /&gt;
print &amp;quot;Relative script dir: &amp;quot;,pathname&lt;br /&gt;
print &amp;quot;Script dir: &amp;quot;, os.path.abspath(pathname)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 os.path.realpath(__file__)&lt;br /&gt;
&lt;br /&gt;
 print &#039;sys.argv[0] =&#039;, sys.argv[0]             &lt;br /&gt;
 pathname = os.path.dirname(sys.argv[0])        &lt;br /&gt;
 print &#039;path =&#039;, pathname&lt;br /&gt;
 print &#039;full path =&#039;, os.path.abspath(pathname)&lt;br /&gt;
&lt;br /&gt;
=== Environment Variables ===&lt;br /&gt;
&lt;br /&gt;
 import os&lt;br /&gt;
 a = os.environ.get(&#039;MYVAR&#039;)               # get environment var&lt;br /&gt;
 a = os.environ.get(&#039;MYVAR&#039;,&#039;default&#039;)     # get environment var&lt;br /&gt;
 a = os.environ[&#039;MYVAR&#039;]                   # get environment var&lt;br /&gt;
 os.environ[&#039;MYVAR&#039;] = &#039;something&#039;         # set environment var&lt;br /&gt;
 os.environ.update({&#039;MYVAR&#039;:&#039;something&#039;})  # set environment var&lt;br /&gt;
&lt;br /&gt;
 for env in os.environ:&lt;br /&gt;
   print &amp;quot;%s = %s&amp;quot; % (env, os.environ[env])&lt;br /&gt;
&lt;br /&gt;
 with open(&amp;quot;environment.txt&amp;quot;, &amp;quot;w&amp;quot;) as f:&lt;br /&gt;
   for env in os.environ:&lt;br /&gt;
      f.write(&amp;quot;%s = %s\n&amp;quot; % (env, os.environ[env]))&lt;br /&gt;
&lt;br /&gt;
=== PYTHONPATH ===&lt;br /&gt;
&lt;br /&gt;
Environment Search path:&lt;br /&gt;
 PYTHONPATH=...&lt;br /&gt;
&lt;br /&gt;
From Code:&lt;br /&gt;
 sys.path.append(&#039;...&#039;)&lt;br /&gt;
&lt;br /&gt;
Get site-package directory from shell: [http://stackoverflow.com/questions/122327/how-do-i-find-the-location-of-my-python-site-packages-directory]&lt;br /&gt;
 python -c &amp;quot;from distutils.sysconfig import get_python_lib; print(get_python_lib())&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Import and Modules ===&lt;br /&gt;
&lt;br /&gt;
Import and Modules - http://docs.python.org/tutorial/modules.html&lt;br /&gt;
&lt;br /&gt;
Import module:&lt;br /&gt;
 import package            # standard import&lt;br /&gt;
 import package.code       # nested name space&lt;br /&gt;
 from package import code  # import specifics from module&lt;br /&gt;
 import module             # standard import&lt;br /&gt;
 from math import sin      # import specifics from module&lt;br /&gt;
 from module import myfunc as fun1  # alias function/object&lt;br /&gt;
 import math as other_math # alias module&lt;br /&gt;
 import longname as ln     # alias module&lt;br /&gt;
 from module import *      # BAD BAD BAD!&lt;br /&gt;
&lt;br /&gt;
 import math&lt;br /&gt;
 math.pow(x,y)&lt;br /&gt;
&lt;br /&gt;
Group and organize by:&lt;br /&gt;
* stdlib libraries&lt;br /&gt;
* local libraries&lt;br /&gt;
* 3rd party libraries&lt;br /&gt;
&lt;br /&gt;
Remove import:&lt;br /&gt;
 del math&lt;br /&gt;
&lt;br /&gt;
 from math import *&lt;br /&gt;
 pow(x,y)&lt;br /&gt;
&lt;br /&gt;
 from math import pow&lt;br /&gt;
 pow(x,y)&lt;br /&gt;
&lt;br /&gt;
 import math as math_lib   # rename&lt;br /&gt;
 math_lib.pow(x,y)&lt;br /&gt;
&lt;br /&gt;
List functions in module:&lt;br /&gt;
 import math&lt;br /&gt;
 dir(math)&lt;br /&gt;
&lt;br /&gt;
List all built in functions:&lt;br /&gt;
 dir(__builtins__)&lt;br /&gt;
&lt;br /&gt;
Note: Modules have the extension .py&lt;br /&gt;
&lt;br /&gt;
Simply module Example:&lt;br /&gt;
&lt;br /&gt;
 # mymod.py:&lt;br /&gt;
 def hello():&lt;br /&gt;
   &amp;quot;&amp;quot;&amp;quot; this is a doc string &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
   print &amp;quot;Hello World&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 # Use the module:&lt;br /&gt;
 import mymod&lt;br /&gt;
 mymod.hello():&lt;br /&gt;
&lt;br /&gt;
 # Use everything in the the module, except for names beginning with &#039;_&#039;:  (bad practice!)&lt;br /&gt;
 from mymod import *&lt;br /&gt;
 hello()&lt;br /&gt;
&lt;br /&gt;
 # Use specific functions in the module:&lt;br /&gt;
 from mymod import hello, hi&lt;br /&gt;
 hello()&lt;br /&gt;
&lt;br /&gt;
 # Function assignment:&lt;br /&gt;
 h = mymod.hello&lt;br /&gt;
 h()&lt;br /&gt;
&lt;br /&gt;
 # module name&lt;br /&gt;
 mymod.__name__   # mymod&lt;br /&gt;
 __name__         # used inside of module will print current module or &amp;quot;__main__&amp;quot; if directly called&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Note: careful when building own modules, as the import literally imports and executes the code, so any code not in functions is executed!&lt;br /&gt;
&lt;br /&gt;
Check if being called directly or indirectly:&lt;br /&gt;
 if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
   # execute tests...&lt;br /&gt;
&lt;br /&gt;
Standard Script Setup:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def main(args):&lt;br /&gt;
  # do logic&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
  sys.exit(main(sys.argv))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Easter egg:&lt;br /&gt;
 # The Zen of Python&lt;br /&gt;
 import this&lt;br /&gt;
&lt;br /&gt;
Search path:&lt;br /&gt;
* environment variable &#039;PYTHONPATH&#039;   (on Unix, this is usually .:/usr/local/lib/python)&lt;br /&gt;
* sys.path  (list of paths, initialized to PYTHONPATH)&lt;br /&gt;
** sys.path.append(&#039;path&#039;)&lt;br /&gt;
&lt;br /&gt;
Module folder: [http://stackoverflow.com/questions/391879/organising-my-python-project] [http://stackoverflow.com/questions/279237/python-import-a-module-from-a-folder] [http://stackoverflow.com/questions/72852/how-to-do-relative-imports-in-python]&lt;br /&gt;
 /kenlib/kenmod.py&lt;br /&gt;
 # so you can do &amp;quot;import kenlib.kenmod&amp;quot;&lt;br /&gt;
 # create file &#039;__init__.py&#039; in kenlib/&lt;br /&gt;
&lt;br /&gt;
Check if package exists:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
try:&lt;br /&gt;
    import argparse&lt;br /&gt;
except ImportError:&lt;br /&gt;
    print &amp;gt;&amp;gt; sys.stderr, &amp;quot;Please install argparse from http://code.google.com/p/&lt;br /&gt;
argparse.&amp;quot;&lt;br /&gt;
    exit(1)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== ifmain ===&lt;br /&gt;
&lt;br /&gt;
 if __name__ == &#039;__main__&#039;:&lt;br /&gt;
     sys.exit(main(sys.argv))&lt;br /&gt;
&lt;br /&gt;
 if __name__ == &#039;__main__&#039;:&lt;br /&gt;
     sys.exit(main(sys.argv[1:]) or 0)&lt;br /&gt;
&lt;br /&gt;
=== Lists ===&lt;br /&gt;
&lt;br /&gt;
* Lists can be modified (mutable)&lt;br /&gt;
* Tuples are constant (immutable)&lt;br /&gt;
&lt;br /&gt;
List: (mutable or modifiable)&lt;br /&gt;
 x = []  # empty list&lt;br /&gt;
 x = [5] # singleton list&lt;br /&gt;
&lt;br /&gt;
 s = list(&amp;quot;Hello World&amp;quot;)&lt;br /&gt;
 print(s)  # s = [&#039;H&#039;, &#039;e&#039;, &#039;l&#039;, &#039;l&#039;, &#039;o&#039;, &#039; &#039;, &#039;W&#039;, &#039;o&#039;, &#039;r&#039;, &#039;l&#039;, &#039;d&#039;]&lt;br /&gt;
 s[0] = &#039;X&#039;&lt;br /&gt;
&lt;br /&gt;
 s.append(x)     # append x&lt;br /&gt;
 s.insert(i, x)  # insert x at i&lt;br /&gt;
 del(s[i])       # delete item at i&lt;br /&gt;
 s.sort()        # sort (modify in place!)&lt;br /&gt;
 s.reverse()     # reverse&lt;br /&gt;
 s.index(x)      # index of x in s&lt;br /&gt;
 new = old[:]    # create copy of list&lt;br /&gt;
 new = list(old) # create copy of list&lt;br /&gt;
&lt;br /&gt;
Check if item in list:&lt;br /&gt;
 if x in s: ...&lt;br /&gt;
&lt;br /&gt;
Filter list of strings based on contents: [https://stackoverflow.com/questions/2152898/filtering-a-list-of-strings-based-on-contents]&lt;br /&gt;
 res = [k for k in lst if &#039;ab&#039; in k]&lt;br /&gt;
&lt;br /&gt;
List comprehension&lt;br /&gt;
 [n * n for n in range(1, 11)]   # squares of numbers 1 to 10&lt;br /&gt;
 [c for c in &#039;pizza&#039;]            # list of string &#039;pizza&#039;&lt;br /&gt;
 [c.upper() for c in &#039;pizza&#039;]    # list of string &#039;pizza&#039; uppercase&lt;br /&gt;
 [n for n in nums if n &amp;gt; 0]      # filters out only positive numbers in nums list&lt;br /&gt;
 [fname for fname in os.listdir(path)  # on multiple lines&lt;br /&gt;
    if os.path.isfile(fname)&lt;br /&gt;
    if fname.endswith(&#039;.py&#039;)]&lt;br /&gt;
&lt;br /&gt;
Enumeration&lt;br /&gt;
 for index, value in enumerate(mylist):  print index, value&lt;br /&gt;
&lt;br /&gt;
Length:&lt;br /&gt;
 len(x)&lt;br /&gt;
&lt;br /&gt;
Concatenation:&lt;br /&gt;
 x + s&lt;br /&gt;
 x * 2&lt;br /&gt;
&lt;br /&gt;
Convert list to string:&lt;br /&gt;
 &amp;quot;&amp;quot;.join(mylist)  # no separator&lt;br /&gt;
 &amp;quot; &amp;quot;.join(mylist) # space separator&lt;br /&gt;
 &amp;quot;,&amp;quot;.join(mylist) # comma separator&lt;br /&gt;
&lt;br /&gt;
Test Membership&lt;br /&gt;
 x in s&lt;br /&gt;
&lt;br /&gt;
Multi dimensional list:&lt;br /&gt;
 mylist = [ [0,&amp;quot;hi&amp;quot;], [1,&amp;quot;bye&amp;quot;] ]&lt;br /&gt;
 print( mylist[0][1] )&lt;br /&gt;
&lt;br /&gt;
Sorting: (see lambda)&lt;br /&gt;
 data.sort()  # alpha numerica sort&lt;br /&gt;
 data.reverse()  # alpha numerica sort&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# custom sort&lt;br /&gt;
data = [1, 5, 3, 9]&lt;br /&gt;
def mylistcmp(x, y):&lt;br /&gt;
  if x == y: return 0&lt;br /&gt;
  if x &amp;lt; y:&lt;br /&gt;
    return -1&lt;br /&gt;
  else:  # swap 1 and -1 here to reverse&lt;br /&gt;
    return 1&lt;br /&gt;
&lt;br /&gt;
data.sort(cmp=mylistcmp)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Slices:&lt;br /&gt;
 lst = [&#039;1a&#039;, &#039;2b&#039;, &#039;3c&#039;, &#039;4d&#039;, &#039;5e&#039;, &#039;6f&#039;]&lt;br /&gt;
 lst[0]     # &#039;1a&#039;&lt;br /&gt;
 lst[-1]    # &#039;6f&#039; last item&lt;br /&gt;
 lst[0:2]   # [&#039;1a&#039;, &#039;2b&#039;]&lt;br /&gt;
 lst[0:2] = [&#039;11&#039;, &#039;22&#039;]   # lst = [&#039;11&#039;, &#039;22&#039;, &#039;3c&#039;, &#039;4d&#039;, &#039;5e&#039;, &#039;6f&#039;] - assignment to slice&lt;br /&gt;
 lst[0:2] = []   # remove items&lt;br /&gt;
 lst[0:0] = [&#039;1a&#039;, &#039;2b&#039;]   # insert items (at beginning)&lt;br /&gt;
 lst[-1:-1] = [&#039;7g&#039;, &#039;8h&#039;]   # insert items (at item BEFORE last), not really what you want, use append()&lt;br /&gt;
 lst[-1:] = [&#039;7g&#039;, &#039;8h&#039;]   # replace last item&lt;br /&gt;
 lst[:] = []   # clear entire list&lt;br /&gt;
 del(lst[0:2])  # delete slice items&lt;br /&gt;
&lt;br /&gt;
Note: it is not safe to modify a sequence while being iterated over.  Create a copy first:&lt;br /&gt;
 for x in mylst[:]:  # make a slice copy of the entire list&lt;br /&gt;
   if len(x) &amp;gt; 6: a.insert(0,x)&lt;br /&gt;
&lt;br /&gt;
Make list from tuple:&lt;br /&gt;
 list( range(10) )&lt;br /&gt;
&lt;br /&gt;
Merge multiple lists: [http://www.testingreflections.com/node/view/4930]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def merge(seq):&lt;br /&gt;
    merged = []&lt;br /&gt;
    for s in seq:&lt;br /&gt;
        for x in s:&lt;br /&gt;
            merged.append(x)&lt;br /&gt;
    return merged&lt;br /&gt;
&lt;br /&gt;
# sample usage:&lt;br /&gt;
foo = [[&#039;a&#039;, &#039;b&#039;],[&#039;c&#039;],[&#039;d&#039;, &#039;e&#039;, &#039;f&#039;]]&lt;br /&gt;
print merge(foo)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt;[&#039;a&#039;, &#039;b&#039;, &#039;c&#039;, &#039;d&#039;, &#039;e&#039;, &#039;f&#039;]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Tuple ===&lt;br /&gt;
&lt;br /&gt;
Tuple: (immutable or constant)&lt;br /&gt;
 x = ()    # empty tuple&lt;br /&gt;
 x = (5,)  # singleton tuple&lt;br /&gt;
 x = (5)   # NOTE: integer with parenthesis, not tuple&lt;br /&gt;
 &lt;br /&gt;
 s = tuple(&amp;quot;Hello World&amp;quot;)&lt;br /&gt;
 print(s)  # s = (&#039;H&#039;, &#039;e&#039;, &#039;l&#039;, &#039;l&#039;, &#039;o&#039;, &#039; &#039;, &#039;W&#039;, &#039;o&#039;, &#039;r&#039;, &#039;l&#039;, &#039;d&#039;)&lt;br /&gt;
 # ERROR: s[0] = &#039;X&#039;&lt;br /&gt;
&lt;br /&gt;
Make list from tuple:&lt;br /&gt;
 list( range(10) )&lt;br /&gt;
&lt;br /&gt;
Use in conditionals:&lt;br /&gt;
 if answer in (&#039;y&#039;, &#039;ye&#039;, &#039;yes&#039;): ...&lt;br /&gt;
&lt;br /&gt;
Convert tuple string to tuple: [http://stackoverflow.com/questions/3945856/converting-string-to-tuple-and-adding-to-tuple]&lt;br /&gt;
 x = &amp;quot;(1,2,3)&amp;quot;&lt;br /&gt;
 t = tuple(int(v) for v in re.findall(&amp;quot;[0-9]+&amp;quot;, x))&lt;br /&gt;
&lt;br /&gt;
Another Convert tuple string to tuple: [http://stackoverflow.com/questions/3945856/converting-string-to-tuple-and-adding-to-tuple]&lt;br /&gt;
 import ast&lt;br /&gt;
 ast.literal_eval(&amp;quot;(1,2,3,4)&amp;quot;) # (1,2,3,4)&lt;br /&gt;
&lt;br /&gt;
=== Named Tuple ===&lt;br /&gt;
&lt;br /&gt;
What are &amp;quot;named tuples&amp;quot; in Python? - Stack Overflow - http://stackoverflow.com/questions/2970608/what-are-named-tuples-in-python&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from collections import namedtuple&lt;br /&gt;
Point = namedtuple(&#039;Point&#039;, &#039;x y&#039;)&lt;br /&gt;
pt1 = Point(1.0, 5.0)&lt;br /&gt;
pt2 = Point(2.5, 1.5)&lt;br /&gt;
print p1     # point(x=1, y=5)&lt;br /&gt;
print p1.x   # 1.0&lt;br /&gt;
print p1[0]  # 1.0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Dictionary ===&lt;br /&gt;
&lt;br /&gt;
NOTE: Dictionaries are also known as associative arrays, maps or hash tables.&lt;br /&gt;
&lt;br /&gt;
Dictionary: (mutable or modifiable)&lt;br /&gt;
&lt;br /&gt;
 color = {}                      # empty dictionary&lt;br /&gt;
 color = {&#039;red&#039; : 1, &#039;blue&#039;, 2}&lt;br /&gt;
 print( color[&#039;red&#039;] )           # 1&lt;br /&gt;
 print( color.get(&#039;red&#039;) )       # 1&lt;br /&gt;
 print( color.get(&#039;red&#039;, &#039;default&#039;) )       # red if found, or return &#039;default&#039;&lt;br /&gt;
 color[&#039;green&#039;] = 3              # able to add new item on the fly!&lt;br /&gt;
 &#039;red&#039; in color                  # True - check if index exists&lt;br /&gt;
 del(color[&amp;quot;red&amp;quot;])               # delete item&lt;br /&gt;
 len(color)                      # 2 - count of items&lt;br /&gt;
&lt;br /&gt;
List in dictionary&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
d.setdefault(key,[]).append(member)  # tricky!&lt;br /&gt;
&lt;br /&gt;
# more tricky: set default type as list&lt;br /&gt;
from from collections import defaultdict&lt;br /&gt;
d = defaultdict(list)&lt;br /&gt;
d[key].append(member)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Enumeration:&lt;br /&gt;
 for index, key in enumerate(mylist):  print index, key&lt;br /&gt;
&lt;br /&gt;
functions:&lt;br /&gt;
 d.clear()&lt;br /&gt;
 d.copy()&lt;br /&gt;
 d.get(key)&lt;br /&gt;
 d.get(key, default_val)&lt;br /&gt;
 d.update(e)   # update with (key, value) pairs in e&lt;br /&gt;
 d.setdefault(key, value)  # only update if not exist, and return set value&lt;br /&gt;
&lt;br /&gt;
Views: (adjust on the fly as dictionary changes)&lt;br /&gt;
 d.items()  (key, values)&lt;br /&gt;
 for k, v in d.items(): print(k, v)&lt;br /&gt;
 &lt;br /&gt;
 d.keys()&lt;br /&gt;
 for k in d.keys(): print(k)&lt;br /&gt;
 &lt;br /&gt;
 d.values()&lt;br /&gt;
 for v in d.values(): print(v)&lt;br /&gt;
&lt;br /&gt;
Sorting: (see also lambda)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# custom sort of dictionaries in list&lt;br /&gt;
data = [dict(number=x) for x in &#039;036149&#039;]  # create list of dictionaries&lt;br /&gt;
def mydictcmp(x, y):&lt;br /&gt;
  if x[&#039;number&#039;] == y[&#039;number&#039;]: return 0&lt;br /&gt;
  if x[&#039;number&#039;] &amp;lt; y[&#039;number&#039;]:&lt;br /&gt;
    return -1&lt;br /&gt;
  else:  # swap 1 and -1 here to reverse&lt;br /&gt;
    return 1&lt;br /&gt;
&lt;br /&gt;
# data.sort(cmp=mydictcmp)  # modifies data&lt;br /&gt;
&lt;br /&gt;
new_data = sorted(data, cmp=mydictcmp)  # better solution&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sorting:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
my_dict = {&#039;a&#039;:1, &#039;b&#039;:4, &#039;c&#039;:3, &#039;d&#039;:9}&lt;br /&gt;
my_dict_keys = my_dict.keys()&lt;br /&gt;
&lt;br /&gt;
def my_dict_sort(x, y):&lt;br /&gt;
    if my_dict[x] == my_dict[y]: return 0&lt;br /&gt;
    if my_dict[x] &amp;lt; my_dict[y]: return -1&lt;br /&gt;
    if my_dict[x] &amp;gt; my_dict[y]: return 1&lt;br /&gt;
&lt;br /&gt;
#sorted_my_dict = sorted(my_dict_keys, cmp=my_dict_sort, reverse=True)&lt;br /&gt;
sorted_tuple = sorted(my_dict_keys, cmp=my_dict_sort)&lt;br /&gt;
print &amp;quot;Sorted Dictionary:&amp;quot;&lt;br /&gt;
for key in sorted_tuple:&lt;br /&gt;
    print &amp;quot;%s: %d&amp;quot; % (key, my_dict[key])&lt;br /&gt;
&lt;br /&gt;
# a: 1, c: 3, b: 4, d: 9,&lt;br /&gt;
# reverse: d: 9, b: 4, c: 3, a: 1,&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sort and keys:&lt;br /&gt;
 keys = sorted(mydict.keys())&lt;br /&gt;
&lt;br /&gt;
Sort by value: [http://stackoverflow.com/questions/613183/python-sort-a-dictionary-by-value]&lt;br /&gt;
 import operator&lt;br /&gt;
 x = {1: 2, 3: 4, 4:3, 2:1, 0:0}&lt;br /&gt;
 sorted_x = sorted(x.iteritems(), key=operator.itemgetter(1))&lt;br /&gt;
&lt;br /&gt;
Sort options:&lt;br /&gt;
 # LIST.sort(cmp=None, key=None, reverse=False) -- stable sort *IN PLACE*;&lt;br /&gt;
 # sorted(iterable, cmp=None, key=None, reverse=False)&lt;br /&gt;
&lt;br /&gt;
Another: (works well!)&lt;br /&gt;
 sorted(my_dict.items(), key=lambda x: x[1])&lt;br /&gt;
&lt;br /&gt;
See: http://wiki.python.org/moin/HowTo/Sorting/&lt;br /&gt;
&lt;br /&gt;
=== Sets ===&lt;br /&gt;
&lt;br /&gt;
Sets are special lists with unique values (good for removing duplicates)&lt;br /&gt;
 lst = [1, 1, 6, 8, 1, 5]&lt;br /&gt;
 s = set(lst)&lt;br /&gt;
 print(s)  # set([8, 1, 5, 6])&lt;br /&gt;
 s.add(item)&lt;br /&gt;
 item in s  # true&lt;br /&gt;
 s.remove(item)&lt;br /&gt;
&lt;br /&gt;
Union (return combination of all):&lt;br /&gt;
 s.union(t)&lt;br /&gt;
&lt;br /&gt;
Intersection (return matching):&lt;br /&gt;
 s.intersection(t)&lt;br /&gt;
&lt;br /&gt;
Symmetric Difference (return only items not matching either, inverse of intersection):&lt;br /&gt;
 s.symmetric_difference(t)&lt;br /&gt;
 list( set(mylist).symmetric_difference(set(mylist2)) )&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Operation		   Equivalent	Result&lt;br /&gt;
len(s) 	  				cardinality of set s&lt;br /&gt;
x in s 	  				test x for membership in s&lt;br /&gt;
x not in s 	  			test x for non-membership in s&lt;br /&gt;
s.issubset(t) 		   s &amp;lt;= t       test whether every element in s is in t&lt;br /&gt;
s.issuperset(t) 	   s &amp;gt;= t 	test whether every element in t is in s&lt;br /&gt;
s.union(t) 		   s | t 	new set with elements from both s and t&lt;br /&gt;
s.intersection(t)	   s &amp;amp; t 	new set with elements common to s and t&lt;br /&gt;
s.difference(t) 	   s - t	new set with elements in s but not in t&lt;br /&gt;
s.symmetric_difference(t)  s ^ t 	new set with elements in either s or t but not both&lt;br /&gt;
s.copy() 	  			new set with a shallow copy of s&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* sets — Unordered collections of unique elements - http://docs.python.org/library/sets.html&lt;br /&gt;
&lt;br /&gt;
=== Files ===&lt;br /&gt;
&lt;br /&gt;
Open file, get file descriptor:&lt;br /&gt;
 fd = open(&#039;/dev/null&#039;)&lt;br /&gt;
&lt;br /&gt;
File Modes:&lt;br /&gt;
 &#039;r&#039; read (default)&lt;br /&gt;
 &#039;w&#039; write (truncate and create if needed)&lt;br /&gt;
 &#039;a&#039; append (create if needed)&lt;br /&gt;
 &lt;br /&gt;
 &#039;b&#039; binary&lt;br /&gt;
 &#039;t&#039; text (default)&lt;br /&gt;
 &lt;br /&gt;
 &#039;+&#039; read and write&lt;br /&gt;
&lt;br /&gt;
Common Functions: (fd)&lt;br /&gt;
&lt;br /&gt;
 f.read()       # read whole file to string&lt;br /&gt;
 f.read(n)      # read n bytes from file to string&lt;br /&gt;
 f.readline()   # read single line as string (while loop)&lt;br /&gt;
 f.readlines()  # read all lines to list&lt;br /&gt;
&lt;br /&gt;
 f.write(str)   # write string to file (does not auto include new line)&lt;br /&gt;
 f.writelines(list)  # write list to file (does not auto include new lines)&lt;br /&gt;
&lt;br /&gt;
 f.seek(0)      # seek to start of file&lt;br /&gt;
 f.seek(pos)    # seek to position&lt;br /&gt;
 f.truncate()   # truncate file&lt;br /&gt;
&lt;br /&gt;
 f.close()      # close file (fd)&lt;br /&gt;
 f.closed       # True/False flag that reports if file is closed&lt;br /&gt;
&lt;br /&gt;
Help:&lt;br /&gt;
 help(open(&#039;/dev/null&#039;))&lt;br /&gt;
 pydoc file&lt;br /&gt;
&lt;br /&gt;
Read Text File Line by Line&lt;br /&gt;
 f = open(fname, &#039;r&#039;)  # (&#039;r&#039; optional)&lt;br /&gt;
 for line in f:  # or f.readlines()&lt;br /&gt;
   print(line)&lt;br /&gt;
 f.close()  # optional&lt;br /&gt;
&lt;br /&gt;
Write list to file (with new lines):&lt;br /&gt;
 f.writelines(&#039;\n&#039;.join(mylist))&lt;br /&gt;
&lt;br /&gt;
One liner read whole file:&lt;br /&gt;
 print( open( fname, &#039;r&#039; ).read() )&lt;br /&gt;
&lt;br /&gt;
Write text file:&lt;br /&gt;
 # f = open(fname, &#039;a&#039;)  # append text file&lt;br /&gt;
 f = open(fname, &#039;w&#039;)&lt;br /&gt;
 f.write(&amp;quot;Hello\n&amp;quot;)&lt;br /&gt;
 f.write( str(10) )  # convert numbers to strings first&lt;br /&gt;
 f.writelines([&amp;quot;line one\n&amp;quot;, &amp;quot;line two\n&amp;quot;])&lt;br /&gt;
 f.close&lt;br /&gt;
&lt;br /&gt;
Read binary file:&lt;br /&gt;
 def is_gif(fname):&lt;br /&gt;
   f = open(fname, &#039;br&#039;)  # not sure &#039;b&#039; is correct&lt;br /&gt;
   first4 = tuple(f.read(4))&lt;br /&gt;
   return first4 == (0x47, 0x49, 0x46, 0x38)&lt;br /&gt;
&lt;br /&gt;
Read all characters of file:&lt;br /&gt;
 c = f.read(1)&lt;br /&gt;
 while c:&lt;br /&gt;
   # if c == ... logic&lt;br /&gt;
   c = f.read(1)&lt;br /&gt;
&lt;br /&gt;
Reading file in while loop: [http://ubuntuforums.org/showthread.php?t=1092300]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
f=open(&amp;quot;file&amp;quot;)&lt;br /&gt;
while True:&lt;br /&gt;
  line=f.readline()&lt;br /&gt;
  if not line: break&lt;br /&gt;
  print line  &lt;br /&gt;
f.close()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
with - implicit close - [http://www.python.org/dev/peps/pep-0343/ PEP 343 -- The &amp;quot;with&amp;quot; Statement]: [http://docs.python.org/reference/compound_stmts.html#the-with-statement] (python &amp;gt;= 2.5)&lt;br /&gt;
 with open(&amp;quot;/etc/passwd&amp;quot;) as f:&lt;br /&gt;
   # ..., f.read(), etc&lt;br /&gt;
&lt;br /&gt;
With statement: (promptly close open handle at end of block)&lt;br /&gt;
 with open(fname, &#039;r&#039;) as f:&lt;br /&gt;
   for ...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# eqivalent to:&lt;br /&gt;
f = open(&amp;quot;/etc/passwd&amp;quot;)&lt;br /&gt;
f.__enter__()&lt;br /&gt;
try:&lt;br /&gt;
  ...&lt;br /&gt;
finally:&lt;br /&gt;
  f.__exit__()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
cat: (for grabbing a configuration line)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def cat(filename):&lt;br /&gt;
    with open(filename) as f:&lt;br /&gt;
        return f.readline().strip()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== With ===&lt;br /&gt;
&lt;br /&gt;
PEP 343 -- The &amp;quot;with&amp;quot; Statement - http://www.python.org/dev/peps/pep-0343/&lt;br /&gt;
&lt;br /&gt;
&#039;with&#039; structure:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
with EXPR as VAR:&lt;br /&gt;
  BLOCK&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
translates to:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
VAR = EXPR&lt;br /&gt;
VAR.__enter__()&lt;br /&gt;
try:&lt;br /&gt;
  BLOCK&lt;br /&gt;
finally:&lt;br /&gt;
  VAR.__exit__()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: The &amp;quot;as VAR&amp;quot; part is optional.  Good for locking:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
with locking(myLock):&lt;br /&gt;
  BLOCK&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
with - implicit close - [http://www.python.org/dev/peps/pep-0343/ PEP 343 -- The &amp;quot;with&amp;quot; Statement]: [http://docs.python.org/reference/compound_stmts.html#the-with-statement] (python &amp;gt;= 2.5)&lt;br /&gt;
 with open(&amp;quot;/etc/passwd&amp;quot;) as f:&lt;br /&gt;
   ...&lt;br /&gt;
&lt;br /&gt;
With statement: (promptly close open handle at end of block)&lt;br /&gt;
 with open(fname, &#039;r&#039;) as f:&lt;br /&gt;
   for ...&lt;br /&gt;
&lt;br /&gt;
See also [[#Files]]&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* PEP 343 -- The &amp;quot;with&amp;quot; Statement - http://www.python.org/dev/peps/pep-0343/&lt;br /&gt;
* PEP 340 -- Anonymous Block Statements - http://www.python.org/dev/peps/pep-0340/&lt;br /&gt;
&lt;br /&gt;
=== Try Exception Handling ===&lt;br /&gt;
&lt;br /&gt;
Exception Handling - http://docs.python.org/release/2.6.6/tutorial/errors.html&lt;br /&gt;
&lt;br /&gt;
throw execption:&lt;br /&gt;
 raise [EXCEPTION]&lt;br /&gt;
 raise IOError(&amp;quot;This is a test!&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Catch exceptions:&lt;br /&gt;
 try:&lt;br /&gt;
 except ( [EXCEPTION], [EXCEPTION] ):&lt;br /&gt;
 except [EXCEPTION]:&lt;br /&gt;
 except [EXCEPTION] as err:  # use &amp;quot;[EXCEPTION], err&amp;quot; in python &amp;lt; 2.6&lt;br /&gt;
   print(&amp;quot;Error: {}&amp;quot;.format(err))&lt;br /&gt;
 except:&lt;br /&gt;
   raise   # reraise caught error that is not handled&lt;br /&gt;
 else:     # if no exception caught&lt;br /&gt;
 finally:  # always executed&lt;br /&gt;
&lt;br /&gt;
Note: Usually a good idea to re-raise exception if you don&#039;t handle it (just &#039;raise&#039;)&lt;br /&gt;
&lt;br /&gt;
General Exception: (all exceptions inherit from Exception)&lt;br /&gt;
 try:&lt;br /&gt;
   raise Exception(&#039;spam&#039;, &#039;eggs&#039;)&lt;br /&gt;
 except Exception as e:&lt;br /&gt;
   pass&lt;br /&gt;
&lt;br /&gt;
Custom Exception Class:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class MyError(Exception):&lt;br /&gt;
  &amp;quot;&amp;quot;&amp;quot;My Error Exception&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
class MyException(Exception):&lt;br /&gt;
    pass&lt;br /&gt;
&lt;br /&gt;
rasie MyError(&amp;quot;My Error&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class ValidationError(Exception):&lt;br /&gt;
    def __init__(self, message, Errors):&lt;br /&gt;
&lt;br /&gt;
        # Call the base class constructor with the parameters it needs&lt;br /&gt;
        Exception.__init__(self, message)&lt;br /&gt;
&lt;br /&gt;
        # Now for your custom code...&lt;br /&gt;
        self.Errors = Errors&lt;br /&gt;
    def __str__(self):&lt;br /&gt;
        return &amp;quot;MyErrors - %s&amp;quot; % self.Errors&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Rename standard exception:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Failure(StandardError):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;Exception for unexpected failures.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: a good place to hide the exception classes in the __init__.py file.&lt;br /&gt;
&lt;br /&gt;
==== exception line number ====&lt;br /&gt;
&lt;br /&gt;
Python When I catch an exception, how do I get the type, file, and line number? - Stack Overflow [http://stackoverflow.com/questions/1278705/python-when-i-catch-an-exception-how-do-i-get-the-type-file-and-line-number]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import sys, os&lt;br /&gt;
&lt;br /&gt;
try:&lt;br /&gt;
    raise NotImplementedError(&amp;quot;No error&amp;quot;)&lt;br /&gt;
except Exception as e:&lt;br /&gt;
    exc_type, exc_obj, exc_tb = sys.exc_info()&lt;br /&gt;
    fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]&lt;br /&gt;
    print(exc_type, fname, exc_tb.tb_lineno)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== traceback ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import traceback&lt;br /&gt;
    try:&lt;br /&gt;
    ...&lt;br /&gt;
    except Exception as E:&lt;br /&gt;
        ...&lt;br /&gt;
        print &#039;Traceback: %s&#039;, traceback.format_exc()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Catching multiple exceptions and getting properties from the exception:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import traceback&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
class MyError(Exception):&lt;br /&gt;
  &amp;quot;&amp;quot;&amp;quot;My Error Exception&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
try:&lt;br /&gt;
  #raise ValueError(&amp;quot;a value error&amp;quot;)  # &amp;lt;type &#039;exceptions.ValueError&#039;&amp;gt;&lt;br /&gt;
  raise MyError(&amp;quot;a my error&amp;quot;)         # &amp;lt;class &#039;__main__.MyError&#039;&amp;gt;&lt;br /&gt;
  raise Exception(&amp;quot;won&#039;t be caught&amp;quot;)  # &amp;lt;type &#039;exceptions.Exception&#039;&amp;gt;&lt;br /&gt;
except (ValueError, MyError) as e:&lt;br /&gt;
  print type(e)       # &amp;lt;class &#039;__main__.MyError&#039;&amp;gt;&lt;br /&gt;
  print e             # __str__() = a my error&lt;br /&gt;
  msg = str(e)        # msg = &#039;a my error&#039;&lt;br /&gt;
  print e.__doc__     # My Error Exception&lt;br /&gt;
  print e.__str__()   # a my error&lt;br /&gt;
  print e.__repr__()  # MyError(&#039;a my error&#039;,)&lt;br /&gt;
  print e.args        # (&#039;a my error&#039;,)&lt;br /&gt;
  x = e               # __getitem__() allows args to be unpacked directly&lt;br /&gt;
  # x, y = e          # if two args were passed, use len(e.args) to see count&lt;br /&gt;
&lt;br /&gt;
  # manually print stack trace (import traceback, sys)&lt;br /&gt;
  print &amp;quot;Exception in user code:&amp;quot;&lt;br /&gt;
  print &#039;-&#039;*60&lt;br /&gt;
  traceback.print_exc(file=sys.stdout)&lt;br /&gt;
  # stack_trace = traceback.format_exc()&lt;br /&gt;
  print &#039;-&#039;*60&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Object Oriented Programming ===&lt;br /&gt;
&lt;br /&gt;
Terms:&lt;br /&gt;
* encapsulates&lt;br /&gt;
* inheritance&lt;br /&gt;
* polymorphism&lt;br /&gt;
* method overriding&lt;br /&gt;
&lt;br /&gt;
==== class ====&lt;br /&gt;
&lt;br /&gt;
class animal.py:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Animal(object):  # default &amp;quot;(object)&amp;quot; not required&lt;br /&gt;
  &amp;quot; Animal class &amp;quot;&lt;br /&gt;
  def __init__(self, name):&lt;br /&gt;
    self.name = name       # name is private variable&lt;br /&gt;
    self.__iam = &amp;quot;animal&amp;quot;  # __iam is private variable&lt;br /&gt;
  def __str__(self):       # string representation&lt;br /&gt;
    return &amp;quot;name = &#039;%s&#039;&amp;quot; % (self.name)&lt;br /&gt;
  def __repr__(self):      # object representation (just typing instance in IDLE, or repr())&lt;br /&gt;
    return &#039;Animal(%s)&#039; % str(self)  # returns __str__&lt;br /&gt;
  def speak(self, msg=&#039;Nothing to say&#039;):&lt;br /&gt;
    print(msg)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: if no __str__ defined, but __repr__ is, then:  __str__ = __repr__&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from animal import Animal&lt;br /&gt;
a = Animal(&#039;good&#039;)&lt;br /&gt;
print(a.__doc__)  # Animal class&lt;br /&gt;
print(a)          # name = &#039;good&#039;&lt;br /&gt;
a                 # Animal(name = &#039;good&#039;)&lt;br /&gt;
print(a.name)     # good&lt;br /&gt;
a.speak(&#039;hi&#039;)     # hi&lt;br /&gt;
print(a._Animal__iam)  # animal - access to private variable (shouldn&#039;t do)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
subclass dog.py:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from animal import Animal&lt;br /&gt;
class Dog(Animal):&lt;br /&gt;
  &amp;quot; Dog class &amp;quot;&lt;br /&gt;
  def __init__(self, name):&lt;br /&gt;
    self.name = name      # name is private variable&lt;br /&gt;
    self.__iam = &amp;quot;dog&amp;quot;    # __iam is private variable&lt;br /&gt;
  # NOTICE: no __str__, inherited from super class&lt;br /&gt;
  def __repr__(self):     # override to reflect &amp;quot;dog&amp;quot;&lt;br /&gt;
    return &#039;Dog(%s)&#039; % str(self)  # returns __str__&lt;br /&gt;
  def speak(self, msg=&#039;Nothing to say&#039;):   # override method&lt;br /&gt;
    super(Dog, self).speak(&#039;Dog says: &#039; + msg)     # call super class method&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Subclass usage:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from dog import Dog&lt;br /&gt;
d = Dog(&#039;bad&#039;)&lt;br /&gt;
print(d.__doc__)    # Dog class&lt;br /&gt;
print(d)            # name = &#039;bad&#039;&lt;br /&gt;
d                   # Dog(name = &#039;bad&#039;)&lt;br /&gt;
print(d.name)       # bad&lt;br /&gt;
d.speak(&#039;hi&#039;)       # Dog says: hi&lt;br /&gt;
print(d._Dog__iam)  # dog - access to private variable (shouldn&#039;t do)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Super: [http://stackoverflow.com/questions/576169/understanding-python-super-with-init-methods]&lt;br /&gt;
 # python 3.0&lt;br /&gt;
 super().__init__()&lt;br /&gt;
&lt;br /&gt;
 # python 2.7&lt;br /&gt;
 super(self.__class__, self).__init__()&lt;br /&gt;
 super([CLASSNAME], self).__init__()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Rectangle(Polygon):&lt;br /&gt;
    def __init__(self, id, width, height):&lt;br /&gt;
        #  super(Rectangle, self).__init__(id)&lt;br /&gt;
        super(self.__class__, self).__init__(id)&lt;br /&gt;
        self.shape = (width, height)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Get class name:&lt;br /&gt;
 self.__class__.__name__&lt;br /&gt;
 obj.__class__.__name__&lt;br /&gt;
&lt;br /&gt;
Full name:&lt;br /&gt;
 obj.__module__ + &amp;quot;.&amp;quot; + obj.__class__.__name__&lt;br /&gt;
&lt;br /&gt;
Private variables: (uses name mangling)&lt;br /&gt;
  self.__age&lt;br /&gt;
  # direct access:  _classname__varname  (eg. p._Person__age = 44)&lt;br /&gt;
&lt;br /&gt;
Tests:&lt;br /&gt;
 isinstance(myobj, myclass)  # check if myobj is a class or subclass of myclass &lt;br /&gt;
 issubclass(A, B)  # check if A is subclass of B&lt;br /&gt;
 issubclass(Exception, BaseException)  # True&lt;br /&gt;
&lt;br /&gt;
Multiple Inheritance:  (methods searched in order)&lt;br /&gt;
 class DerviedClass(Base1, Base2, Base3):&lt;br /&gt;
   pass&lt;br /&gt;
&lt;br /&gt;
Standard startup script:&lt;br /&gt;
 class MyClass():&lt;br /&gt;
     ...&lt;br /&gt;
     @classmethod&lt;br /&gt;
     def main(cls, argv=None):&lt;br /&gt;
         ...&lt;br /&gt;
         # return cls() # creator&lt;br /&gt;
 if __name__ == &amp;quot;__main__&amp;quot;;&lt;br /&gt;
     sys.exit(MyClass.main(sys.argv))&lt;br /&gt;
&lt;br /&gt;
Raise an error if a method is not overridden (not implemented)&lt;br /&gt;
    def _get_dist(self):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Find linux disto. Implemented in subclasses.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        raise NotImplementedError&lt;br /&gt;
&lt;br /&gt;
==== Multiple Constructors ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Animal(object):&lt;br /&gt;
&lt;br /&gt;
  def __init__(self, name):&lt;br /&gt;
    self.name = name&lt;br /&gt;
&lt;br /&gt;
  @classmethod&lt;br /&gt;
  def create_fido(cls):&lt;br /&gt;
    return cls(&amp;quot;fido&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Descriptor Classes ====&lt;br /&gt;
&lt;br /&gt;
&amp;quot;In general, a descriptor is an object attribute with “binding behavior”, one whose attribute access has been overridden by methods in the descriptor protocol: __get__(), __set__(), and __delete__(). If any of those methods are defined for an object, it is said to be a descriptor.&amp;quot; [http://docs.python.org/2/reference/datamodel.html#implementing-descriptors]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
object.__get__(self, instance, owner)&lt;br /&gt;
&lt;br /&gt;
    Called to get the attribute of the owner class (class attribute access) or of an instance of that&lt;br /&gt;
    class (instance attribute access). owner is always the owner class, while instance is the instance&lt;br /&gt;
    that the attribute was accessed through, or None when the attribute is accessed through the owner.&lt;br /&gt;
    This method should return the (computed) attribute value or raise an AttributeError exception.&lt;br /&gt;
&lt;br /&gt;
object.__set__(self, instance, value)&lt;br /&gt;
&lt;br /&gt;
    Called to set the attribute on an instance instance of the owner class to a new value, value.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example: [http://stackoverflow.com/questions/3798835/understanding-get-and-set-and-python-descriptors]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Celsius(object):&lt;br /&gt;
    def __init__(self, value=0.0):&lt;br /&gt;
        self.value = float(value)&lt;br /&gt;
    def __get__(self, instance, owner):&lt;br /&gt;
        return self.value&lt;br /&gt;
    def __set__(self, instance, value):&lt;br /&gt;
        self.value = float(value)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
class Temperature(object):&lt;br /&gt;
    celsius = Celsius()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
t = Temperature()&lt;br /&gt;
t.celsius = 5    # calls Celsius.__set__&lt;br /&gt;
print t.celsius  # calls Celsius.__get__&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: Also appears in &#039;pydoc&#039; under &amp;quot;Data descriptors defined here&amp;quot; with object&#039;s docstring.  Trick: the __doc__ can be overridden in the __init__ method, which makes for dynamic docstrings!&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* Descriptor HowTo Guide — Python v2.7.5 documentation - http://docs.python.org/2/howto/descriptor.html&lt;br /&gt;
* 3.4.2.2. Implementing Descriptors¶ - 3. Data model — Python v2.7.5 documentation - http://docs.python.org/2/reference/datamodel.html#implementing-descriptors&lt;br /&gt;
&lt;br /&gt;
=== [http://docs.python.org/reference/simple_stmts.html#the-exec-statement exec code] ===&lt;br /&gt;
&lt;br /&gt;
DANGEROUS!&lt;br /&gt;
&lt;br /&gt;
Execute code in string:&lt;br /&gt;
 exec( &#039;print(&amp;quot;hi&amp;quot;)&#039; )&lt;br /&gt;
&lt;br /&gt;
Example of executing a startup script for IDLE:&lt;br /&gt;
 if os.path.isfile(&#039;.pythonrc.py&#039;): exec(open(&#039;.pythonrc.py&#039;).read())&lt;br /&gt;
&lt;br /&gt;
 import os&lt;br /&gt;
 filename = os.environ.get(&#039;PYTHONSTARTUP&#039;)&lt;br /&gt;
 if filename and os.path.isfile(filename):&lt;br /&gt;
   exec(open(filename).read())&lt;br /&gt;
&lt;br /&gt;
=== eval ===&lt;br /&gt;
&lt;br /&gt;
VERY DANGEROUS&lt;br /&gt;
&lt;br /&gt;
Will execute a string as though it were pure python code!&lt;br /&gt;
&lt;br /&gt;
 eval(&amp;quot;print &#039;hello&#039;&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
=== Common Header Format ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
__author__ = &amp;quot;software team&amp;quot;&lt;br /&gt;
__date__ =&amp;quot;$Feb 15, 2011 1:42:17 PM$&amp;quot;&lt;br /&gt;
__version__ = &amp;quot;1.1.0.441 bandelier@66d9fe1edf3e&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Next should be authorship information. This information should follow this format:&lt;br /&gt;
&lt;br /&gt;
__author__ = &amp;quot;Rob Knight, Gavin Huttley, and Peter Maxwell&amp;quot;&lt;br /&gt;
__copyright__ = &amp;quot;Copyright 2007, The Cogent Project&amp;quot;&lt;br /&gt;
__credits__ = [&amp;quot;Rob Knight&amp;quot;, &amp;quot;Peter Maxwell&amp;quot;, &amp;quot;Gavin Huttley&amp;quot;,&lt;br /&gt;
                    &amp;quot;Matthew Wakefield&amp;quot;]&lt;br /&gt;
__license__ = &amp;quot;GPL&amp;quot;&lt;br /&gt;
__version__ = &amp;quot;1.0.1&amp;quot;&lt;br /&gt;
__maintainer__ = &amp;quot;Rob Knight&amp;quot;&lt;br /&gt;
__email__ = &amp;quot;rob@spot.colorado.edu&amp;quot;&lt;br /&gt;
__status__ = &amp;quot;Production&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Source: Python Coding Guidelines - http://bayes.colorado.edu/PythonGuidelines.html&lt;br /&gt;
&lt;br /&gt;
These will show up in the help() like such:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Help on module test:&lt;br /&gt;
&lt;br /&gt;
NAME&lt;br /&gt;
    test&lt;br /&gt;
&lt;br /&gt;
FILE&lt;br /&gt;
    /home/kenneth/test.py&lt;br /&gt;
&lt;br /&gt;
FUNCTIONS&lt;br /&gt;
    test()&lt;br /&gt;
&lt;br /&gt;
DATA&lt;br /&gt;
    __author__ = &#039;test author&#039;&lt;br /&gt;
    __version__ = &#039;1.0&#039;&lt;br /&gt;
&lt;br /&gt;
VERSION&lt;br /&gt;
    1.0&lt;br /&gt;
&lt;br /&gt;
AUTHOR&lt;br /&gt;
    test author&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* Python: What is the common header format? - Stack Overflow - http://stackoverflow.com/questions/1523427/python-what-is-the-common-header-format&lt;br /&gt;
&lt;br /&gt;
=== Common Environment Variables ===&lt;br /&gt;
&lt;br /&gt;
 Command line and environment — Python v2.7.2 documentation - http://docs.python.org/using/cmdline.htm&lt;br /&gt;
&lt;br /&gt;
PYTHONUNBUFFERED&lt;br /&gt;
: If this is set to a non-empty string it is equivalent to specifying the -u option. [http://docs.python.org/using/cmdline.html#envvar-PYTHONUNBUFFERED]&lt;br /&gt;
: -u - Force stdin, stdout and stderr to be totally unbuffered. On systems where it matters, also put stdin, stdout and stderr in binary mode.&lt;br /&gt;
* See also stdout - Python output buffering - Stack Overflow - http://stackoverflow.com/questions/107705/python-output-buffering&lt;br /&gt;
 export PYTHONUNBUFFERED=1&lt;br /&gt;
 set PYTHONUNBUFFERED=1&lt;br /&gt;
&lt;br /&gt;
PYTHONVERBOSE&lt;br /&gt;
:If this is set to a non-empty string it is equivalent to specifying the -v option. If set to an integer, it is equivalent to specifying -v multiple times.&lt;br /&gt;
: -v - Print a message each time a module is initialized, showing the place (filename or built-in module) from which it is loaded.&lt;br /&gt;
 export PYTHONVERBOSE=1&lt;br /&gt;
 set PYTHONVERBOSE=1&lt;br /&gt;
&lt;br /&gt;
PYTHONPATH&lt;br /&gt;
: Augment the default search path for module files. The format is the same as the shell’s PATH: one or more directory pathnames separated by os.pathsep (e.g. colons on Unix or semicolons on Windows). Non-existent directories are silently ignored. [http://docs.python.org/using/cmdline.html#envvar-PYTHONPATH]&lt;br /&gt;
 export PYTHONPATH=/path1/:path2/&lt;br /&gt;
 set PYTHONPATH=C:\path1\;C:\path2\&lt;br /&gt;
&lt;br /&gt;
=== Queue ===&lt;br /&gt;
&lt;br /&gt;
Good for threading.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;The Queue module implements multi-producer, multi-consumer queues. It is especially useful in threaded programming when information must be exchanged safely between multiple threads. The Queue class in this module implements all the required locking semantics.&amp;quot; [http://docs.python.org/2/library/queue.html]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import Queue&lt;br /&gt;
&lt;br /&gt;
bucket = Queue.Queue()&lt;br /&gt;
bucket.put(&amp;quot;something&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
while True:&lt;br /&gt;
    try:&lt;br /&gt;
        item = bucket.get(block=False)&lt;br /&gt;
    except Queue.Empty:&lt;br /&gt;
        pass&lt;br /&gt;
    else:&lt;br /&gt;
        # do stuff with queue&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Important methods:&lt;br /&gt;
  Queue.qsize()&lt;br /&gt;
  Queue.empty()&lt;br /&gt;
  Queue.put(item[, block[, timeout]])&lt;br /&gt;
  Queue.get([block[, timeout]])&lt;br /&gt;
&lt;br /&gt;
-&lt;br /&gt;
&lt;br /&gt;
Example: http://docs.python.org/2/library/queue.html&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def worker():&lt;br /&gt;
    while True:&lt;br /&gt;
        item = q.get()&lt;br /&gt;
        do_work(item)&lt;br /&gt;
        q.task_done()&lt;br /&gt;
&lt;br /&gt;
q = Queue()&lt;br /&gt;
for i in range(num_worker_threads):&lt;br /&gt;
     t = Thread(target=worker)&lt;br /&gt;
     t.daemon = True&lt;br /&gt;
     t.start()&lt;br /&gt;
&lt;br /&gt;
for item in source():&lt;br /&gt;
    q.put(item)&lt;br /&gt;
&lt;br /&gt;
q.join()       # block until all tasks are done&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
-&lt;br /&gt;
&lt;br /&gt;
&amp;quot;The module implements three types of queue, which differ only in the order in which the entries are retrieved. In a FIFO queue, the first tasks added are the first retrieved. In a LIFO queue, the most recently added entry is the first retrieved (operating like a stack). With a priority queue, the entries are kept sorted (using the heapq module) and the lowest valued entry is retrieved first.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Queue Types:&lt;br /&gt;
  class Queue.Queue(maxsize=0)          # FIFO Queue&lt;br /&gt;
  class Queue.LifoQueue(maxsize=0)      # LIFO Queue&lt;br /&gt;
  class Queue.PriorityQueue(maxsize=0)  # Priority Queue&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* 8.10. Queue — A synchronized queue class — Python v2.7.5 documentation - http://docs.python.org/2/library/queue.html&lt;br /&gt;
&lt;br /&gt;
== Recipes ==&lt;br /&gt;
&lt;br /&gt;
=== Remove Numbers from String ===&lt;br /&gt;
&lt;br /&gt;
Using list comprehension: [http://stackoverflow.com/questions/12851791/removing-numbers-from-string]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
result = &#039;&#039;.join([i for i in s if not i.isdigit()])&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Using pattern matching:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; re.compile(r&#039;\D+&#039;).findall(&amp;quot;test 1234 test 1234&amp;quot;)&lt;br /&gt;
[&#039;test &#039;, &#039; test &#039;]&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; re.compile(r&amp;quot;\d&amp;quot;).sub(&amp;quot;&amp;quot;, &amp;quot;test 1234 test 1234&amp;quot;)&lt;br /&gt;
&#039;test  test &#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Retry Wrapper ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import functool&lt;br /&gt;
class SomethingRetry:&lt;br /&gt;
&lt;br /&gt;
    def retry_with_backoff(retries: int, base_delay: float, exceptions: tuple[type[Exception], ...] = (Exception,)) -&amp;gt; callable:&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Retries a function with exponential backoff, doubling on each attempt.&lt;br /&gt;
        Arguments:&lt;br /&gt;
            retries: Number of retry attempts.&lt;br /&gt;
            base_delay: Initial delay between retries in seconds.&lt;br /&gt;
            exceptions: Tuple of exceptions to catch and retry.&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
        def decorator(func):&lt;br /&gt;
            @functools.wraps(func)&lt;br /&gt;
            def wrapper(*args, **kwargs):&lt;br /&gt;
                for attempt in range(1, retries + 1):&lt;br /&gt;
                    try:&lt;br /&gt;
                        return func(*args, **kwargs)&lt;br /&gt;
                    except exceptions as e:&lt;br /&gt;
                        print(f&amp;quot;Warning: Attempt {attempt} failed with error: {e}&amp;quot;)&lt;br /&gt;
                        if attempt == retries:&lt;br /&gt;
                            print(&amp;quot;Error: All retry attempts failed.&amp;quot;)&lt;br /&gt;
                            raise&lt;br /&gt;
                        sleep_time = base_delay * (2 ** (attempt - 1))&lt;br /&gt;
                        print(f&amp;quot;Notice: Retrying in {sleep_time} seconds...&amp;quot;)&lt;br /&gt;
                        time.sleep(sleep_time)&lt;br /&gt;
            return wrapper&lt;br /&gt;
        return decorator&lt;br /&gt;
&lt;br /&gt;
    @retry_with_backoff(retries=6, base_delay=10, exceptions=(Exception,))&lt;br /&gt;
    def do_something(self, sample_param: str):&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Standard Libraries ==&lt;br /&gt;
&lt;br /&gt;
=== user input ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
line = raw_input()  # Python 2&lt;br /&gt;
# line = input()    # Python 2&lt;br /&gt;
line = input(&#039;What is your name: &#039;)&lt;br /&gt;
print(&amp;quot;: &amp;quot; + line.strip() + &amp;quot; :&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== sys - stdout stderr stdin ===&lt;br /&gt;
&lt;br /&gt;
STDOUT:&lt;br /&gt;
 import sys&lt;br /&gt;
 sys.stdout.write(&amp;quot;Hello &amp;quot;)  # does not write new line&lt;br /&gt;
 sys.stdout.write(&amp;quot;World\n&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
STDERR:&lt;br /&gt;
 import sys&lt;br /&gt;
 sys.stderr.write(&amp;quot;ERROR!\n&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
STDIN:&lt;br /&gt;
 import sys&lt;br /&gt;
 line = sys.stdin.readline()&lt;br /&gt;
&lt;br /&gt;
 line = input()   # use raw_input() in Python 2&lt;br /&gt;
 line = input(&#039;What is your name: &#039;)&lt;br /&gt;
 print(&amp;quot;: &amp;quot; + line.strip() + &amp;quot; :&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Read piped stdin line by line: [http://stackoverflow.com/questions/1450393/how-do-you-read-from-stdin-in-python]&lt;br /&gt;
 # cat /etc/passwd | ./readlines.py     # linux&lt;br /&gt;
 # type file.txt | python readlines.py  # windows&lt;br /&gt;
&lt;br /&gt;
 # fileinput.input() - returns fileinput object which is iterative&lt;br /&gt;
 import fileinput&lt;br /&gt;
 for line in fileinput.input():&lt;br /&gt;
     print(&amp;quot;: &amp;quot; + line + &amp;quot; :&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
 # sys.stdin.readlines() - returns list of strings&lt;br /&gt;
 import sys&lt;br /&gt;
 for line in sys.stdin.readlines():&lt;br /&gt;
     print(&amp;quot;: &amp;quot; + line + &amp;quot; :&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
 # sys.stdin - returns object which is iterative&lt;br /&gt;
 import sys&lt;br /&gt;
 for line in sys.stdin:&lt;br /&gt;
     print(&amp;quot;: &amp;quot; + line + &amp;quot; :&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
 # ugly while loop: [http://ubuntuforums.org/showthread.php?t=1092300]&lt;br /&gt;
 while True:&lt;br /&gt;
     try:&lt;br /&gt;
         s = raw_input(&amp;quot;Say something &amp;quot;)&lt;br /&gt;
     except EOFError:&lt;br /&gt;
         break&lt;br /&gt;
     print &amp;quot;: %s&amp;quot; % s&lt;br /&gt;
&lt;br /&gt;
Check if stdin has any waiting data: [http://stackoverflow.com/questions/3762881/how-do-i-check-if-stdin-has-some-data]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import sys&lt;br /&gt;
import select&lt;br /&gt;
&lt;br /&gt;
# if select.select([sys.stdin,],[],[],0.0)[0]:  # alternative old method&lt;br /&gt;
&lt;br /&gt;
if not sys.stdin.isatty():&lt;br /&gt;
    print &amp;quot;Have data!&amp;quot;&lt;br /&gt;
    print sys.stdin.readlines()&lt;br /&gt;
else:&lt;br /&gt;
    print &amp;quot;No data&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if len(sys.argv) &amp;gt; 1:&lt;br /&gt;
    message = &#039; &#039;.join(sys.argv[1:])&lt;br /&gt;
elif not sys.stdin.isatty():&lt;br /&gt;
    # read from pipe in&lt;br /&gt;
    message = sys.stdin.readline()&lt;br /&gt;
else:&lt;br /&gt;
    # read from user&lt;br /&gt;
    sys.stdout.write(&amp;quot;Message: &amp;quot;)&lt;br /&gt;
    message = raw_input().strip()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [http://docs.python.org/library/re.html Regular Expressions] ===&lt;br /&gt;
&lt;br /&gt;
Import:&lt;br /&gt;
 import re  # user regular expressions&lt;br /&gt;
&lt;br /&gt;
Match vs Search:&lt;br /&gt;
 re.match(&amp;quot;cde&amp;quot;, &amp;quot;abcdef&amp;quot;)  # no match (match searches beginning of string, first match)&lt;br /&gt;
 re.match(&amp;quot;abc&amp;quot;, &amp;quot;abcdef&amp;quot;)  # match (match searches beginning of string, first match)&lt;br /&gt;
 re.search(&amp;quot;cd&amp;quot;, &amp;quot;abcdef&amp;quot;)  # match (matches any location, first match)&lt;br /&gt;
&lt;br /&gt;
Both re.match() and re.search() return objects that are not intuitive to use.  You can check the object&#039;s group() method for what matched, but I prefer re.findall().&lt;br /&gt;
&lt;br /&gt;
Match:&lt;br /&gt;
 s = &#039;done&#039;&lt;br /&gt;
 if re.match(&#039;done|quit&#039;, s) != None  # True&lt;br /&gt;
&lt;br /&gt;
Search:&lt;br /&gt;
 s = &#039;done&#039;&lt;br /&gt;
 if re.search(&#039;do&#039;, s) != None  # True&lt;br /&gt;
&lt;br /&gt;
Replace:&lt;br /&gt;
 msg = &#039;jello world&#039;&lt;br /&gt;
 msg = re.sub(&#039;jello&#039;, &#039;hello&#039;, msg)&lt;br /&gt;
&lt;br /&gt;
For case intensive searches append 3rd parameter &amp;quot;re.I&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Find all:&lt;br /&gt;
 re.findall(&amp;quot;[a-z]+&amp;quot;, &amp;quot;aaa111bbb222&amp;quot;)       # [&#039;aaa&#039;, &#039;bbb&#039;]&lt;br /&gt;
 re.findall(&amp;quot;111([a-z]+)&amp;quot;, &amp;quot;aaa111bbb222&amp;quot;)  # [&#039;bbb&#039;]&lt;br /&gt;
 re.findall(&amp;quot;hello&amp;quot;, &amp;quot;HELLO&amp;quot;, re.I)         # [&#039;HELLO&#039;] - Case Insensitive&lt;br /&gt;
&lt;br /&gt;
Split:&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; re.split(&#039;[a-z]+&#039;,&#039;111aaa222bbb&#039;)&lt;br /&gt;
 [&#039;111&#039;, &#039;222&#039;, &#039;&#039;]&lt;br /&gt;
&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; re.split(&#039;([a-z]+)&#039;,&#039;111aaa222bbb&#039;)  # parenthesis cause return of all&lt;br /&gt;
 [&#039;111&#039;, &#039;aaa&#039;, &#039;222&#039;, &#039;bbb&#039;, &#039;&#039;]&lt;br /&gt;
&lt;br /&gt;
Replacement Substitution:&lt;br /&gt;
 # re.sub(pattern, repl, string[, count, flags])&lt;br /&gt;
 re.sub(r&#039;\\&#039;, r&#039;/&#039;, r&#039;\\data\files&#039;)&lt;br /&gt;
&lt;br /&gt;
Compiled regular express for repeated use: (performance)&lt;br /&gt;
 valid = re.compile(r&amp;quot;[0-9]+&amp;quot;)&lt;br /&gt;
 valid.match(&amp;quot;aaa111bbb&amp;quot;)               # not valid&lt;br /&gt;
 match = valid.search(&amp;quot;aaa111bbb222&amp;quot;)   # valid&lt;br /&gt;
 print(match.group())                   # what matched: &#039;111&#039;&lt;br /&gt;
&lt;br /&gt;
=== Date and Time ===&lt;br /&gt;
&lt;br /&gt;
Sleep in seconds:&lt;br /&gt;
 import time&lt;br /&gt;
 time.sleep(seconds)&lt;br /&gt;
&lt;br /&gt;
Use the following functions to convert between time representations:&lt;br /&gt;
&amp;lt;table border=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;From&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;To&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Use&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;seconds since the epoch&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;struct_time in UTC&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;gmtime()&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;seconds since the epoch&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;struct_time in local time&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;localtime()&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;struct_time in UTC&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;seconds since the epoch&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;calendar.timegm()&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;struct_time in local time&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;seconds since the epoch&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;mktime()&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Date formats:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; time.strftime(&amp;quot;%Y-%m-%d %H:%M:%S&amp;quot;, time.localtime())&lt;br /&gt;
&#039;2014-04-04 12:22:43&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; time.time()&lt;br /&gt;
1396635763.0581281&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; datetime.datetime.now()&lt;br /&gt;
datetime.datetime(2014, 4, 4, 12, 22, 43, 58456)&lt;br /&gt;
# datetime(year, month, day, hour, minute, second, microsecond)&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; time.localtime()&lt;br /&gt;
time.struct_time(tm_year=2014, tm_mon=4, tm_mday=4, tm_hour=12, tm_min=22, tm_sec=43, tm_wday=4, tm_yday=94, tm_isdst=1)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Current epoch time:&lt;br /&gt;
 int(time.time())&lt;br /&gt;
&lt;br /&gt;
Time zone offset:&lt;br /&gt;
 standard_tz_offset = - time.timezone / 3600  # 7&lt;br /&gt;
 daylight_tz_offset = - time.altzone / 3600  # 6&lt;br /&gt;
&lt;br /&gt;
Is daylight saving time: [http://stackoverflow.com/questions/2881025/python-daylight-savings-time]&lt;br /&gt;
 import time&lt;br /&gt;
 time.localtime()&lt;br /&gt;
 _.tm_isdst  # 0 or 1&lt;br /&gt;
&lt;br /&gt;
 mst_epoch_time = time.time()  # server in MST/MDT&lt;br /&gt;
 if time.localtime().tm_isdst:  # are we in daylight saving time?&lt;br /&gt;
   utc_epoch_time = mst_epoch_time + time.altzone&lt;br /&gt;
 else:&lt;br /&gt;
   utc_epoch_time = mst_epoch_time + time.timezone&lt;br /&gt;
&lt;br /&gt;
Format current time: [http://docs.python.org/2/library/time.html#time.strftime]&lt;br /&gt;
 time.strftime(&#039;%d%b%y&#039;)  # &#039;12May11&#039;&lt;br /&gt;
 time.strftime(&#039;%Y.%m.%d %H:%M:%S&#039;)  # &#039;2013.08.09 14:01:28&#039;&lt;br /&gt;
&lt;br /&gt;
Time conversions:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# epoch to str&lt;br /&gt;
epoch_time = time.time()    # 1375992088.7867229&lt;br /&gt;
dt = datetime.datetime.fromtimestamp( epoch_time )    # datetime.datetime(2013, 8, 8, 14, 1, 28, 786723)&lt;br /&gt;
date_str = dt.strftime(&amp;quot;%Y-%m-%d %H:%M:%S&amp;quot;)    # &#039;2013-08-08 14:01:28&#039;&lt;br /&gt;
tz_offset = - time.altzone / 3600&lt;br /&gt;
if tz_offset &amp;lt; 0:&lt;br /&gt;
  tz_offset_str = &amp;quot;-%02d00&amp;quot; % abs(tz_offset)&lt;br /&gt;
else:&lt;br /&gt;
  tz_offset_str = &amp;quot;+%02d00&amp;quot; % abs(tz_offset)&lt;br /&gt;
print date_str + &amp;quot; &amp;quot; + tz_offset_str  # &#039;2013-08-08 14:01:28 -0600&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# UTC epoch to str&lt;br /&gt;
gm_epoch_time = calendar.timegm(time.gmtime())    # 1375992114&lt;br /&gt;
dt = datetime.utcfromtimestamp( gm_epoch_time )    # datetime.datetime(2013, 8, 8, 20, 1, 54)&lt;br /&gt;
dt.strftime(&amp;quot;%Y-%m-%d %H:%M:%S +0000&amp;quot;)    # &#039;2013-08-08 20:01:54 +0000&#039;&lt;br /&gt;
dt.strftime(&amp;quot;%Y-%m-%dT%H:%M:%SZ&amp;quot;)    # &#039;2013-08-08 20:01:54 +0000&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Local time str to epoch&lt;br /&gt;
iso_string=&#039;2013-08-08T14:01:28&#039;&lt;br /&gt;
epoch_time = time.mktime( time.strptime( iso_string, &#039;%Y-%m-%dT%H:%M:%S&#039; ) )    # 1375992088.0&lt;br /&gt;
&lt;br /&gt;
iso_string=&#039;2013-08-08T14:01:28 MDT&#039;&lt;br /&gt;
epoch_time = time.mktime( time.strptime( iso_string, &#039;%Y-%m-%dT%H:%M:%S %Z&#039; ) )    # 1375992088.0&lt;br /&gt;
&lt;br /&gt;
# not sure how to specify numerical time zone and pull it in!&lt;br /&gt;
&lt;br /&gt;
# UTC (Zulu) str to epoch, and back again&lt;br /&gt;
iso_string = &#039;2013-08-08T20:01:54Z&#039;&lt;br /&gt;
epoch_time = calendar.timegm( time.strptime( iso_string.replace(&#039;Z&#039;, &#039;GMT&#039;), &#039;%Y-%m-%dT%H:%M:%S%Z&#039; ) )&lt;br /&gt;
print epoch_time    # 1375992114&lt;br /&gt;
print &amp;quot;%sZ&amp;quot; % datetime.utcfromtimestamp(timestamp).isoformat()  # 2013-08-08T20:01:54Z&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Convert epoch from Local to UTC&lt;br /&gt;
epoch_time = 1375992114&lt;br /&gt;
tz_offset = - time.altzone / 3600&lt;br /&gt;
gm_epoch_time = epoch_time - tz_offset * 3600    # 1376013714&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Convert epoch from UTC to Local&lt;br /&gt;
gm_epoch_time = 1376013714&lt;br /&gt;
tz_offset = - time.altzone / 3600&lt;br /&gt;
epoch_time = gm_epoch_time + tz_offset * 3600    # 1375992114&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
struct_time:&lt;br /&gt;
 time.localtime()  # local zime zone&lt;br /&gt;
 time.gmtime()     # UTC time&lt;br /&gt;
&lt;br /&gt;
 today = time.localtime()&lt;br /&gt;
 today_year = today.tm_year&lt;br /&gt;
 today_month = today.tm_mon&lt;br /&gt;
 today_day = today.tm_mday&lt;br /&gt;
&lt;br /&gt;
 time.strftime(&amp;quot;%a, %d %b %Y %H:%M:%S +0000&amp;quot;, time.gmtime())&lt;br /&gt;
&lt;br /&gt;
Zulu time to epoch time: [http://stackoverflow.com/questions/127803/how-to-parse-iso-formatted-date-in-python]&lt;br /&gt;
 s = &#039;2008-09-03T20:56:35.450686Z&#039;&lt;br /&gt;
 event_time_struct = time.strptime(s.split(&#039;.&#039;)[0]+ &amp;quot;UTC&amp;quot;, &amp;quot;%Y-%m-%dT%H:%M:%S%Z&amp;quot;)&lt;br /&gt;
 epoch_time = calendar.timegm(event_time_struct)&lt;br /&gt;
&lt;br /&gt;
Parse string to time.struct_time (like gmtime()): [http://docs.python.org/2/library/time.html#time.strptime]&lt;br /&gt;
 time.strptime(time.ctime())  # current time - default format is ctime format: &amp;quot;%a %b %d %H:%M:%S %Y&amp;quot;&lt;br /&gt;
 time.strptime(time.ctime(time.time()))  # default format is ctime format: &amp;quot;%a %b %d %H:%M:%S %Y&amp;quot;&lt;br /&gt;
 time.strptime(&amp;quot;30 Nov 00&amp;quot;, &amp;quot;%d %b %y&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Build from ticks: [http://www.tutorialspoint.com/python/python_date_time.htm]&lt;br /&gt;
 localtime = time.localtime( time.time() )  # build time.struct_time from ticks&lt;br /&gt;
 print time.asctime( localtime )  # Tue Jan 13 10:17:09 2009&lt;br /&gt;
&lt;br /&gt;
 dt = datetime.datetime.fromtimestamp( time.time() )  # build datetime.datetime struct from ticks&lt;br /&gt;
 dt.strftime(&amp;quot;%Y-%m-%d  %H:%M:%S&amp;quot;)  # &#039;2013-07-31  23:07:48&#039;&lt;br /&gt;
 time.strptime( time.time(), &amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from datetime import date&lt;br /&gt;
now = date.today()    # now = datetime.date(2003, 12,2)&lt;br /&gt;
now.strftime(&amp;quot;%m-%d-%y&amp;quot;)   # &#039;12-02-03&#039;&lt;br /&gt;
# dates support calendar arthimetic&lt;br /&gt;
birthday = date(1964, 7, 31)&lt;br /&gt;
age = now - birthday&lt;br /&gt;
age.days  # 14368&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 ts = (datetime.datetime.now().strftime(&amp;quot;%Y%m%d%H%M&amp;quot;))         # 201105191118&lt;br /&gt;
 tstxt = (datetime.datetime.now().strftime(&amp;quot;%m-%d-%Y %H:%M&amp;quot;))  # 05-19-2011 11:18&lt;br /&gt;
&lt;br /&gt;
Seconds since epoch:&lt;br /&gt;
 int(time.time())    # 1305842304&lt;br /&gt;
&lt;br /&gt;
Zulu and back again: ([http://aboutsimon.com/2013/06/05/datetime-hell-time-zone-aware-to-unix-timestamp/ Datetime hell])&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import time&lt;br /&gt;
from calendar import timegm&lt;br /&gt;
from datetime import datetime&lt;br /&gt;
 &lt;br /&gt;
if __name__ == &#039;__main__&#039;:&lt;br /&gt;
    iso_string = &#039;2013-06-05T15:19:10Z&#039;&lt;br /&gt;
 &lt;br /&gt;
    timestamp = timegm(&lt;br /&gt;
        time.strptime(&lt;br /&gt;
            iso_string.replace(&#039;Z&#039;, &#039;GMT&#039;),&lt;br /&gt;
            &#039;%Y-%m-%dT%H:%M:%S%Z&#039;&lt;br /&gt;
        )&lt;br /&gt;
    )&lt;br /&gt;
 &lt;br /&gt;
    print iso_string&lt;br /&gt;
    print timestamp&lt;br /&gt;
    print &#039;-&amp;gt; %sZ&#039; % datetime.utcfromtimestamp(timestamp).isoformat()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
http://wiki.python.org/moin/TimeTransitionsImage?action=AttachFile&amp;amp;do=get&amp;amp;target=v1.png  [http://wiki.python.org/moin/WorkingWithTime]&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* WorkingWithTime - PythonInfo Wiki - http://wiki.python.org/moin/WorkingWithTime&lt;br /&gt;
* Datetime hell. Time zone aware to UNIX timestamp. | About me and the things I do - http://aboutsimon.com/2013/06/05/datetime-hell-time-zone-aware-to-unix-timestamp/&lt;br /&gt;
* WorkingWithTime - Python Wiki - http://wiki.python.org/moin/WorkingWithTime&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
Something I cooked up...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def utc_time(self, years_offset=60):&lt;br /&gt;
        mst_epoch_time = time.time()  # server is in MST&lt;br /&gt;
        if time.localtime().tm_isdst: # are we daylight saving time?&lt;br /&gt;
            utc_epoch_time = mst_epoch_time + time.altzone&lt;br /&gt;
        else:&lt;br /&gt;
            utc_epoch_time = mst_epoch_time + time.timezone&lt;br /&gt;
        return utc_epoch_time&lt;br /&gt;
&lt;br /&gt;
    def tz_time(self, tz_offset, daylight_adjust=True):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot; return the future time based on timezone offset&lt;br /&gt;
            @tz_offset is timezone offset, eg -7 for MST&lt;br /&gt;
            @daylight_adjust is flag to auto adjust for daylight time&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        if daylight_adjust:&lt;br /&gt;
            if time.localtime().tm_isdst: # are we daylight saving time?&lt;br /&gt;
                _tz_offset = tz_offset - 1&lt;br /&gt;
            else:&lt;br /&gt;
                _tz_offset = tz_offset&lt;br /&gt;
            _utc_epoch_time = self.utc_time()&lt;br /&gt;
            _adj_time = _utc_epoch_time + _tz_offset * 60 * 60&lt;br /&gt;
            return _adj_time&lt;br /&gt;
&lt;br /&gt;
    def future_time(self, tz_offset=-7, daylight_adjust=True, years_offset=60):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot; Calculate some future year &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        _tz_time = self.tz_time(tz_offset)&lt;br /&gt;
        future_utc_epoch_time = _tz_time + years_offset * 365 * 24 * 60 * 60&lt;br /&gt;
        # account for leap years&lt;br /&gt;
        cur_year = datetime.datetime.now().year&lt;br /&gt;
        cur_year_leap = cur_year / 4&lt;br /&gt;
        future_year = cur_year + years_offset&lt;br /&gt;
        future_year_leap = future_year / 4&lt;br /&gt;
        leap_days = future_year_leap - cur_year_leap&lt;br /&gt;
        future_utc_epoch_time += leap_days * 24 * 60 * 60&lt;br /&gt;
        return future_utc_epoch_time&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Math ===&lt;br /&gt;
&lt;br /&gt;
Math Functions:&lt;br /&gt;
 import math&lt;br /&gt;
 math.ceil(x)&lt;br /&gt;
 math.floor(x)&lt;br /&gt;
 math.trunc(x)&lt;br /&gt;
 math.pow(x,y)&lt;br /&gt;
&lt;br /&gt;
 abs(x)  # built in&lt;br /&gt;
&lt;br /&gt;
=== Random ===&lt;br /&gt;
&lt;br /&gt;
 import random&lt;br /&gt;
 random.choice([&#039;a&#039;, &#039;b&#039;, &#039;c&#039;])&lt;br /&gt;
 random.sample(range(100), 10)&lt;br /&gt;
 random.random()  # random float 0 &amp;lt; x &amp;lt; 1&lt;br /&gt;
 random.randrange(3)     # integer in [0, 1, 2]&lt;br /&gt;
 random.randrange(1, 3)  # integer in [1, 2]&lt;br /&gt;
 random.randint(1, 3)    # integer in [1, 2, 3]&lt;br /&gt;
&lt;br /&gt;
=== Operating System Operations ===&lt;br /&gt;
&lt;br /&gt;
Import OS Library:&lt;br /&gt;
 import os&lt;br /&gt;
&lt;br /&gt;
Common Functions:&lt;br /&gt;
 # directory functions&lt;br /&gt;
 os.getcwd()       # get current directory&lt;br /&gt;
 os.listdir(p)     # get list of directory contents&lt;br /&gt;
 os.chdir(p)       # change directory&lt;br /&gt;
 os.mkdir(p)       # make directory&lt;br /&gt;
 os.makedirs(p)    # make directory and all intermediate&lt;br /&gt;
 os.rmdir(p)       # remove empty directory, see shutil.rmtree()&lt;br /&gt;
 os.removedirs(p)  # remove empty directories, see shutil.rmtree()&lt;br /&gt;
 os.path.exists(p) # does file/directory exist?&lt;br /&gt;
 os.path.isdir(p)  # does directory exist&lt;br /&gt;
 os.path.join(folder1, folder2, file, etc)  # portable path join&lt;br /&gt;
&lt;br /&gt;
 # file functions&lt;br /&gt;
 os.remove(p)      # remove file&lt;br /&gt;
 os.unlink(p)      # same as os.remove()&lt;br /&gt;
 os.path.exists(p) # does file/directory exist?&lt;br /&gt;
 os.path.isfile(p) # does file exist&lt;br /&gt;
 os.stat(fname)    # get file stats&lt;br /&gt;
 os.stat(fname).st_size  # file size&lt;br /&gt;
 os.link(src, dst) # create hard link&lt;br /&gt;
 os.readlink(p)    # read symbolic link&lt;br /&gt;
 os.rename(old, new) # rename/move file or directory&lt;br /&gt;
 os.tempnam(p)     # temporary unique name for target path&lt;br /&gt;
 os.tmpfile()      # create temporary file&lt;br /&gt;
 os.tmpnam()       # temporary file name&lt;br /&gt;
 os.path.getsize(filename)  # get file size&lt;br /&gt;
&lt;br /&gt;
 # system functions&lt;br /&gt;
 os.fork()         # fork process&lt;br /&gt;
 os.getpid()       # get process id&lt;br /&gt;
 os.getppid()      # get parent&#039;s process id&lt;br /&gt;
 os.kill(pid, sig) # kill a process&lt;br /&gt;
 os.getlogin()     # get user&#039;s login name&lt;br /&gt;
&lt;br /&gt;
 # execution&lt;br /&gt;
 os.system(cmd)    # output to stdout, return exit_status&lt;br /&gt;
 os.popen(cmd)     # returns a pipe to command&lt;br /&gt;
&lt;br /&gt;
Note: to get path to script:&lt;br /&gt;
 sys.path[0]&lt;br /&gt;
&lt;br /&gt;
Get directory and file names:&lt;br /&gt;
 os.path.dirname(path)  # &#039;/root/test.txt&#039; -&amp;gt; &#039;/root&#039;&lt;br /&gt;
 os.path.basename(path) # &#039;/root/test.txt&#039; -&amp;gt; &#039;test.txt&#039;&lt;br /&gt;
 os.path.splitext(path) # &#039;/root/test.test.txt&#039; -&amp;gt; (&#039;/root/test.test&#039;, &#039;.txt&#039;) - extract extention&lt;br /&gt;
 filename.split(&amp;quot;.&amp;quot;)[-1] # &#039;/root/test.test.txt&#039; -&amp;gt; &#039;txt&#039; - extract extention&lt;br /&gt;
&lt;br /&gt;
Normalize path, eliminating double slashes, etc.&lt;br /&gt;
 os.path.normpath(path)  # &#039;/root/..&#039; -&amp;gt; &#039;/&#039; or &#039;test/..&#039; -&amp;gt; &#039;.&#039;&lt;br /&gt;
 os.path.abspath(path)   # &#039;/root/..&#039; -&amp;gt; &#039;/&#039; or &#039;test/..&#039; -&amp;gt; &#039;/root/test&#039;&lt;br /&gt;
&lt;br /&gt;
List dir: (returns list)&lt;br /&gt;
 os.listdir( os.getcwd() )&lt;br /&gt;
&lt;br /&gt;
List of files:&lt;br /&gt;
 [p for p in os.listdir(os.getcwd())&lt;br /&gt;
    if os.path.isfile(p)]&lt;br /&gt;
&lt;br /&gt;
List of folders:&lt;br /&gt;
 [p for p in os.listdir(os.getcwd())&lt;br /&gt;
    if os.path.isdir(p)]&lt;br /&gt;
&lt;br /&gt;
Build path for local OS: (using appropriate slash)&lt;br /&gt;
 pathstr = os.path.join(&amp;quot;folder&amp;quot;, &amp;quot;folder&amp;quot;, &amp;quot;file_or_folder&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
File and directory management with shutil&lt;br /&gt;
 import shutil&lt;br /&gt;
 shutil.copyfile(&#039;file1&#039;, &#039;file2&#039;)&lt;br /&gt;
 shutil.move(&#039;file1&#039;, &#039;folder2/file1&#039;)&lt;br /&gt;
&lt;br /&gt;
File Wildcards:&lt;br /&gt;
 import glob&lt;br /&gt;
 glob.glob(&#039;*.py&#039;)  # return list of files&lt;br /&gt;
&lt;br /&gt;
Walk directory tree: [http://stackoverflow.com/questions/120656/directory-listing-in-python]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import os&lt;br /&gt;
for dirname, dirnames, filenames in os.walk(&#039;.&#039;):&lt;br /&gt;
    for subdirname in dirnames:&lt;br /&gt;
        print os.path.join(dirname, subdirname)&lt;br /&gt;
    for filename in filenames:&lt;br /&gt;
        print os.path.join(dirname, filename)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ugly &#039;deltree&#039; (by kenneth)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import os&lt;br /&gt;
def deltree(path):&lt;br /&gt;
    files = os.listdir(path)&lt;br /&gt;
    for file in files:&lt;br /&gt;
        file_path = os.path.join(path, file)&lt;br /&gt;
        if os.path.isdir(file_path):&lt;br /&gt;
            deltree(file_path)&lt;br /&gt;
            os.rmdir(file_path)&lt;br /&gt;
        else:&lt;br /&gt;
            os.remove(file_path)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cleaner &#039;deltree&#039; (by Kep)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import shutil&lt;br /&gt;
# Blow away (if needed), and reclone to proper version&lt;br /&gt;
if os.path.isdir(&amp;quot;xxx&amp;quot;):&lt;br /&gt;
    shutil.rmtree(&amp;quot;xxx&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== System Platform ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import platform&lt;br /&gt;
&lt;br /&gt;
if platform.system() == &amp;quot;Linux&amp;quot;:&lt;br /&gt;
 # ...&lt;br /&gt;
if platform.system() == &amp;quot;Windows&amp;quot;:&lt;br /&gt;
 # ...&lt;br /&gt;
else:&lt;br /&gt;
 # ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Temp Files ===&lt;br /&gt;
&lt;br /&gt;
 import tempfile&lt;br /&gt;
 filename = tempfile.mktemp()&lt;br /&gt;
 f = open(filename, &#039;w&#039;)&lt;br /&gt;
 ...&lt;br /&gt;
 f.close()&lt;br /&gt;
 &lt;br /&gt;
 import os&lt;br /&gt;
 os.remove(filename)  # delete temp file&lt;br /&gt;
&lt;br /&gt;
=== Pickling ===&lt;br /&gt;
&lt;br /&gt;
Pickling (serializing, making objects persistent):&lt;br /&gt;
 import pickle&lt;br /&gt;
 grades = {&#039;bob&#039; : [4, 5, 6],&lt;br /&gt;
           &#039;sue&#039; : [3, None, 7, 7]}&lt;br /&gt;
 outfile = open(fname, &#039;wb&#039;)&lt;br /&gt;
 pickle.dump(grades, outfile)&lt;br /&gt;
&lt;br /&gt;
 infile = open(fname, &#039;rb&#039;)&lt;br /&gt;
 grades = pickle.load(infile)&lt;br /&gt;
&lt;br /&gt;
=== [http://docs.python.org/library/logging.html Logging] ===&lt;br /&gt;
&lt;br /&gt;
* logging — Logging facility for Python — Python 3 documentation - https://docs.python.org/3/library/logging.html&lt;br /&gt;
* Logging HOWTO — Python Dev Version documentation - http://docs.python.org/dev/howto/logging.html&lt;br /&gt;
* Logging Cookbook — Python Dev Version documentation - http://docs.python.org/dev/howto/logging-cookbook.html&lt;br /&gt;
&lt;br /&gt;
Setup logger:&lt;br /&gt;
 import logging&lt;br /&gt;
 logging.basicConfig(level=logging.DEBUG,format=&#039;[%(asctime)s.%(msecs)03d] %(levelname)s %(filename)s(line:%(lineno)d): %(message)s&#039;)&lt;br /&gt;
&lt;br /&gt;
Log Levels:&lt;br /&gt;
 import logging&lt;br /&gt;
 msg = &amp;quot;i broke&amp;quot;&lt;br /&gt;
 logging.debug(msg)&lt;br /&gt;
 logging.info(msg)&lt;br /&gt;
 logging.warning(msg)   # WARNING:root:i broke&lt;br /&gt;
 logging.error(msg)     # ERROR:root:i broke&lt;br /&gt;
 logging.critical(msg)  # CRITICAL:root:i broke&lt;br /&gt;
&lt;br /&gt;
 log.setLevel(level)  # debug, info, warn/warning, error, critical&lt;br /&gt;
 log.setLevel(logging.DEBUG)&lt;br /&gt;
&lt;br /&gt;
A good convention to use when naming loggers is to use a module-level logger, in each module which uses logging, named as follows: [http://docs.python.org/dev/howto/logging.html]&lt;br /&gt;
 logger = logging.getLogger(__name__)&lt;br /&gt;
&lt;br /&gt;
Simple example: [http://stackoverflow.com/questions/345991/python-no-handlers-could-be-found-for-logger-opengl-error]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
log_format=&#039;%(asctime)s | %(levelname)s | %(message)s&#039;&lt;br /&gt;
log_date_format=&#039;%Y-%m-%d %H:%M:%S&#039;&lt;br /&gt;
logging.basicConfig(format=log_format, datefmt=log_date_format)&lt;br /&gt;
log = logging.getLogger(__name__)&lt;br /&gt;
log.setLevel(logging.INFO)&lt;br /&gt;
&lt;br /&gt;
log.info(&#039;hi&#039;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Formatter function:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def makeFormatter(format_str=&amp;quot;&amp;quot;, date_format=&amp;quot;%Y-%m-%d %H:%M:%S&amp;quot;):&lt;br /&gt;
    if not format_str:&lt;br /&gt;
        format_str = &amp;quot;%(asctime)s | %(levelname)s | %(filename)s:%(lineno)d:%(funcName)s | %(message)s&amp;quot;&lt;br /&gt;
    return logging.Formatter(fmt=format_str, datefmt=date_format)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Medium example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Create logger&lt;br /&gt;
log_format=&#039;%(asctime)s | %(levelname)s | %(message)s&#039;&lt;br /&gt;
log_date_format=&#039;%Y-%m-%d %H:%M:%S&#039;&lt;br /&gt;
log_formatter = logging.Formatter(fmt=log_format, datefmt=log_date_format)&lt;br /&gt;
log = logging.getLogger(__name__)&lt;br /&gt;
log.setLevel(logging.DEBUG)&lt;br /&gt;
&lt;br /&gt;
# Log to console&lt;br /&gt;
ch = logging.StreamHandler()&lt;br /&gt;
ch.setLevel(logging.INFO)&lt;br /&gt;
ch.setFormatter(log_formatter)&lt;br /&gt;
log.addHandler(ch)&lt;br /&gt;
&lt;br /&gt;
# Log to file&lt;br /&gt;
fh = logging.FileHandler(&#039;my_logger.log&#039;)&lt;br /&gt;
fh.setLevel(logging.DEBUG)&lt;br /&gt;
fh.setFormatter(log_formatter)&lt;br /&gt;
log.addHandler(fh)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Log all loggers to file - attach to root logger&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import logging&lt;br /&gt;
&lt;br /&gt;
logger = logging.getLogger(__name__)&lt;br /&gt;
&lt;br /&gt;
# Configure Logger&lt;br /&gt;
log_format=&#039;%(asctime)s | %(name)s | %(levelname)s | %(message)s&#039;&lt;br /&gt;
log_date_format=&#039;%Y-%m-%d %H:%M:%S&#039;&lt;br /&gt;
log_formatter = logging.Formatter(fmt=log_format, datefmt=log_date_format)&lt;br /&gt;
logging.basicConfig(level=logging.DEBUG, format=log_format, datefmt=log_date_format)&lt;br /&gt;
&lt;br /&gt;
# Setup Log to File handler, and attach to root logger&lt;br /&gt;
root_logger = logging.getLogger()  # Calling getLogger() without a name returns the root logger&lt;br /&gt;
fh = logging.FileHandler(&#039;logger.txt&#039;)&lt;br /&gt;
fh.setLevel(logging.DEBUG)&lt;br /&gt;
fh.setFormatter(log_formatter)&lt;br /&gt;
root_logger.addHandler(fh)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Application Setup (not basic log configuration carries across imported modules):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import logging&lt;br /&gt;
def main():&lt;br /&gt;
    logging.basicConfig(filename=&#039;myapp.log&#039;, level=logging.INFO)&lt;br /&gt;
    logging.info(&#039;Started&#039;)&lt;br /&gt;
    ...&lt;br /&gt;
    logging.info(&#039;Finished&#039;)&lt;br /&gt;
&lt;br /&gt;
if __name__ == &#039;__main__&#039;:&lt;br /&gt;
    main()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Log multiple lines:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
for line in output.splitlines():&lt;br /&gt;
    log.debug(line)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Set log level:  (warning is default)&lt;br /&gt;
 logging.basicConfig(level=logging.DEBUG)&lt;br /&gt;
&lt;br /&gt;
Set log level from string value: [http://docs.python.org/dev/howto/logging.html]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# assuming loglevel is bound to the string value obtained from the&lt;br /&gt;
# command line argument. Convert to upper case to allow the user to&lt;br /&gt;
# specify --log=DEBUG or --log=debug&lt;br /&gt;
numeric_level = getattr(logging, loglevel.upper(), None)&lt;br /&gt;
if not isinstance(numeric_level, int):&lt;br /&gt;
    raise ValueError(&#039;Invalid log level: %s&#039; % loglevel)&lt;br /&gt;
logging.basicConfig(level=numeric_level, ...)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Log to file:&lt;br /&gt;
 logging.basicConfig(filename=&#039;example.log&#039;,level=logging.DEBUG)&lt;br /&gt;
 logging.basicConfig(filename=&#039;example.log&#039;, filemode=&#039;w&#039;, level=logging.DEBUG)  # do not append&lt;br /&gt;
&lt;br /&gt;
Format output: (once set, can&#039;t be changed?)&lt;br /&gt;
 # WARNING:MESSAGE&lt;br /&gt;
 logging.basicConfig(format=&#039;%(levelname)s:%(message)s&#039;, level=logging.DEBUG)&lt;br /&gt;
&lt;br /&gt;
 # 05/23/2011 12:50:02 PM MESSAGE&lt;br /&gt;
 logging.basicConfig(format=&#039;%(asctime)s %(message)s&#039;, datefmt=&#039;%m/%d/%Y %I:%M:%S %p&#039;)&lt;br /&gt;
&lt;br /&gt;
 # 05/23/2011 12:55:28 PM : WARNING : MESSAGE&lt;br /&gt;
 logging.basicConfig(format=&#039;%(asctime)s : %(levelname)s : %(message)s&#039;, datefmt=&#039;%m/%d/%Y %I:%M:%S %p&#039;)&lt;br /&gt;
&lt;br /&gt;
 # 2011-05-23 13:05:30 : WARNING : MESSAGE&lt;br /&gt;
 logging.basicConfig(format=&#039;%(asctime)s : %(levelname)s : %(message)s&#039;, datefmt=&#039;%Y-%m-%d %H:%M:%S&#039;)&lt;br /&gt;
&lt;br /&gt;
 # 2011-05-23 13:05:30 | WARNING | FILE:FUNC | MESSAGE&lt;br /&gt;
 logging.basicConfig(format=&#039;%(asctime)s | %(levelname)s | %(filename)s:%(funcName)s | %(message)s&#039;, datefmt=&#039;%Y-%m-%d %H:%M:%S&#039;)&lt;br /&gt;
&lt;br /&gt;
Log record attributes - http://docs.python.org/library/logging.html#logrecord-attributes&lt;br /&gt;
&lt;br /&gt;
Format Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FORMAT = &#039;%(asctime)-15s %(clientip)s %(user)-8s %(message)s&#039;  # doesn&#039;t work!&lt;br /&gt;
logging.basicConfig(format=FORMAT)&lt;br /&gt;
d = { &#039;clientip&#039; : &#039;192.168.0.1&#039;, &#039;user&#039; : &#039;fbloggs&#039; }&lt;br /&gt;
logger = logging.getLogger(&#039;tcpserver&#039;)&lt;br /&gt;
logger.warning(&#039;Protocol problem: %s&#039;, &#039;connection reset&#039;, extra=d)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import logging&lt;br /&gt;
&lt;br /&gt;
# create logger with &#039;spam_application&#039;&lt;br /&gt;
logger = logging.getLogger(&#039;spam_application&#039;)&lt;br /&gt;
logger.setLevel(logging.DEBUG)&lt;br /&gt;
&lt;br /&gt;
# create file handler which logs even debug messages&lt;br /&gt;
fh = logging.FileHandler(&#039;spam.log&#039;)&lt;br /&gt;
fh.setLevel(logging.DEBUG)&lt;br /&gt;
&lt;br /&gt;
# create console handler with a higher log level&lt;br /&gt;
ch = logging.StreamHandler()&lt;br /&gt;
ch.setLevel(logging.ERROR)&lt;br /&gt;
&lt;br /&gt;
# create formatter and add it to the handlers&lt;br /&gt;
formatter = logging.Formatter(&#039;%(asctime)s - %(name)s - %(levelname)s - %(message)s&#039;)&lt;br /&gt;
fh.setFormatter(formatter)&lt;br /&gt;
ch.setFormatter(formatter)&lt;br /&gt;
&lt;br /&gt;
# add the handlers to the logger&lt;br /&gt;
logger.addHandler(fh)&lt;br /&gt;
logger.addHandler(ch)&lt;br /&gt;
&lt;br /&gt;
logger.info(&#039;Message to loggers and handlers&#039;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Templating ===&lt;br /&gt;
&lt;br /&gt;
 from string import Template&lt;br /&gt;
 t = Template(&#039;${name}&#039;s fav dish is $food&#039;)&lt;br /&gt;
 t.substitute(name = &#039;ken&#039;, food = &#039;beans&#039;) # throws exception if missing one, but can have more&lt;br /&gt;
 t.safe_substitute(name = &#039;ken&#039;)  # will fill in what it can&lt;br /&gt;
&lt;br /&gt;
Change delimiter:&lt;br /&gt;
 class MYT(Template):&lt;br /&gt;
   delimiter = &#039;%&#039;&lt;br /&gt;
 minput = input(&amp;quot;File name format (%d - date, %s - size): &amp;quot;)&lt;br /&gt;
 myt = MYT(minput)&lt;br /&gt;
 myt.substitute(%d=date, %s=size)&lt;br /&gt;
&lt;br /&gt;
=== [http://docs.python.org/library/threading.html Threading] ===&lt;br /&gt;
&lt;br /&gt;
Basic thread: [http://softwareramblings.com/2008/06/running-functions-as-threads-in-python.html]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import thread&lt;br /&gt;
 &lt;br /&gt;
def someFunc():&lt;br /&gt;
    print &amp;quot;someFunc was called&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
thread.start_new_thread(someFunc, ())&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
More complete basic thread:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import thread&lt;br /&gt;
import threading&lt;br /&gt;
import time&lt;br /&gt;
&lt;br /&gt;
def run_thread (threadname, sleeptime):&lt;br /&gt;
 print &amp;quot;Thread start: &amp;quot; + threadname&lt;br /&gt;
 time.sleep(sleeptime)&lt;br /&gt;
 print &amp;quot;Thread end: &amp;quot; + threadname&lt;br /&gt;
 thread.interrupt_main()   # throw keyboard interrupt to kill main program&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
 thread.start_new_thread(run_thread, (&amp;quot;Thread1&amp;quot;, 3))&lt;br /&gt;
 try:&lt;br /&gt;
     while 1:&lt;br /&gt;
         pass&lt;br /&gt;
 except:&lt;br /&gt;
     print &amp;quot;Thread1 exited....&amp;quot; &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Can use a global counter instead of exception to track number of threads:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import thread&lt;br /&gt;
import threading&lt;br /&gt;
import time&lt;br /&gt;
&lt;br /&gt;
threadcount = 3&lt;br /&gt;
&lt;br /&gt;
def run_thread (threadname, sleeptime):&lt;br /&gt;
  global threadcount&lt;br /&gt;
  print &amp;quot;Thread start: &amp;quot; + threadname&lt;br /&gt;
  time.sleep(sleeptime)&lt;br /&gt;
  print &amp;quot;Thread end: &amp;quot; + threadname&lt;br /&gt;
  threadcount -= 1&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
  thread.start_new_thread(run_thread, (&amp;quot;Thread1&amp;quot;, 3))&lt;br /&gt;
  thread.start_new_thread(run_thread, (&amp;quot;Thread2&amp;quot;, 4))&lt;br /&gt;
  thread.start_new_thread(run_thread, (&amp;quot;Thread3&amp;quot;, 2))&lt;br /&gt;
  while 1:&lt;br /&gt;
    if threadcount == 0:&lt;br /&gt;
      break&lt;br /&gt;
    else:&lt;br /&gt;
      pass&lt;br /&gt;
  print &amp;quot;completed&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
Thread object: [http://softwareramblings.com/2008/06/running-functions-as-threads-in-python.html]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import threading&lt;br /&gt;
 &lt;br /&gt;
t1 = threading.Thread(target=someFunc)&lt;br /&gt;
#  with parameters: Thread(target=myfunction, args=(&#039;MyStringHere&#039;,1)).start()&lt;br /&gt;
t1.start()&lt;br /&gt;
t1.join()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Basic threading with parameters:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import threading&lt;br /&gt;
t = threading.Thread(None, someFunc, None, (param1, param2))&lt;br /&gt;
t.start()&lt;br /&gt;
t.join()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
t = threading.Thread(target=client_recv, args=(s, name))&lt;br /&gt;
while True:&lt;br /&gt;
  t.join(timeout=2)&lt;br /&gt;
  if t.isAlive():&lt;br /&gt;
    print &amp;quot;Thread is dead...&amp;quot;&lt;br /&gt;
    break&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Threading as a class: [http://softwareramblings.com/2008/06/running-functions-as-threads-in-python.html]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import threading&lt;br /&gt;
 &lt;br /&gt;
class FuncThread(threading.Thread):&lt;br /&gt;
    def __init__(self, target, *args):&lt;br /&gt;
        self._target = target&lt;br /&gt;
        self._args = args&lt;br /&gt;
        threading.Thread.__init__(self)&lt;br /&gt;
 &lt;br /&gt;
    def run(self):&lt;br /&gt;
        self._target(*self._args)&lt;br /&gt;
 &lt;br /&gt;
# Example usage&lt;br /&gt;
def someOtherFunc(data, key):&lt;br /&gt;
    print &amp;quot;someOtherFunc was called : data=%s; key=%s&amp;quot; % (str(data), str(key))&lt;br /&gt;
 &lt;br /&gt;
t1 = FuncThread(someOtherFunc, [1,2], 6)&lt;br /&gt;
t1.start()&lt;br /&gt;
t1.join()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Threading as a class #2:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import threading&lt;br /&gt;
import time&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
class MyT(threading.Thread):&lt;br /&gt;
  def __init__(self, name, time):&lt;br /&gt;
    threading.Thread.__init__(self)&lt;br /&gt;
    self.name = name&lt;br /&gt;
    self.time = time&lt;br /&gt;
  def run(self):&lt;br /&gt;
    print(&amp;quot;Thread Start: &amp;quot; + self.name)&lt;br /&gt;
    for i in range(self.time):&lt;br /&gt;
      print(&amp;quot;[&amp;quot; + self.name + &amp;quot;]&amp;quot;, end=&#039;&#039;)&lt;br /&gt;
      sys.stdout.flush()&lt;br /&gt;
      time.sleep(1)&lt;br /&gt;
    print(&amp;quot;Thread Stop: &amp;quot; + self.name)&lt;br /&gt;
&lt;br /&gt;
myt1 = MyT(&#039;1&#039;, 10)&lt;br /&gt;
myt1.start()&lt;br /&gt;
&lt;br /&gt;
myt2 = MyT(&#039;2&#039;, 15)&lt;br /&gt;
myt2.start()&lt;br /&gt;
&lt;br /&gt;
myt3 = MyT(&#039;3&#039;, 5)&lt;br /&gt;
myt3.start()&lt;br /&gt;
&lt;br /&gt;
myt4 = MyT(&#039;4&#039;, 10)&lt;br /&gt;
myt4.start()&lt;br /&gt;
&lt;br /&gt;
myt1.join()&lt;br /&gt;
myt2.join()&lt;br /&gt;
myt3.join()&lt;br /&gt;
myt4.join()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Locking:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
lock=thread.allocate_lock()&lt;br /&gt;
&lt;br /&gt;
# pass lock to thread, and use in thread as such:&lt;br /&gt;
lock.acquire()&lt;br /&gt;
#some operation&lt;br /&gt;
lock.release()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Returning data from a thread (using a [http://docs.python.org/library/queue.html queue]): [http://stackoverflow.com/questions/1886090/return-value-from-thread] [http://stackoverflow.com/questions/2829329/catch-a-threads-exception-in-the-caller-thread-in-python]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Pass exception back to parent&lt;br /&gt;
import sys&lt;br /&gt;
import threading&lt;br /&gt;
import Queue&lt;br /&gt;
&lt;br /&gt;
class ExcThread(threading.Thread):&lt;br /&gt;
    def __init__(self, bucket):&lt;br /&gt;
        threading.Thread.__init__(self)&lt;br /&gt;
        self.bucket = bucket&lt;br /&gt;
    def run(self):&lt;br /&gt;
        try:&lt;br /&gt;
            raise Exception(&#039;An error occured here.&#039;)&lt;br /&gt;
        except Exception:&lt;br /&gt;
            self.bucket.put(sys.exc_info())&lt;br /&gt;
&lt;br /&gt;
def main():&lt;br /&gt;
    bucket = Queue.Queue()&lt;br /&gt;
    thread_obj = ExcThread(bucket)&lt;br /&gt;
    thread_obj.start()&lt;br /&gt;
    while True:&lt;br /&gt;
        try:&lt;br /&gt;
            exc = bucket.get(block=False)&lt;br /&gt;
        except Queue.Empty:&lt;br /&gt;
            pass&lt;br /&gt;
        else:&lt;br /&gt;
            exc_type, exc_obj, exc_trace = exc&lt;br /&gt;
            # deal with the exception&lt;br /&gt;
            print &amp;quot;Exception Caught:&amp;quot;, exc_type, exc_obj&lt;br /&gt;
            print &amp;quot;Exception Trace:&amp;quot;, exc_trace&lt;br /&gt;
        thread_obj.join(0.1)&lt;br /&gt;
        if thread_obj.isAlive():&lt;br /&gt;
            continue&lt;br /&gt;
        else:&lt;br /&gt;
            break&lt;br /&gt;
&lt;br /&gt;
if __name__ == &#039;__main__&#039;:&lt;br /&gt;
    main()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Exception Caught: &amp;lt;type &#039;exceptions.Exception&#039;&amp;gt; An error occured here.&lt;br /&gt;
Exception Trace: &amp;lt;traceback object at 0x2b2230a285f0&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Another Exception catching queue example: (kenneth&#039;s example)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# thread function&lt;br /&gt;
def run_thread(queue, item):&lt;br /&gt;
  ...&lt;br /&gt;
  queue.put( Exception(&amp;quot;Failure on item:&amp;quot; + item) )&lt;br /&gt;
&lt;br /&gt;
threads = []&lt;br /&gt;
queue = Queue.Queue()&lt;br /&gt;
&lt;br /&gt;
# start threads&lt;br /&gt;
for item in items:&lt;br /&gt;
  t = Thread(None, run_thread, None, (queue, item))&lt;br /&gt;
  t.start()&lt;br /&gt;
  threads.append(t)&lt;br /&gt;
&lt;br /&gt;
# wait for threads&lt;br /&gt;
for t in threads:&lt;br /&gt;
  t.join()&lt;br /&gt;
&lt;br /&gt;
# catch and reraise exceptions&lt;br /&gt;
while not queue.empty():&lt;br /&gt;
  raise(queue.get())&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Returning data from a thread (using a callback function): [http://stackoverflow.com/questions/1886090/return-value-from-thread]&lt;br /&gt;
:&amp;quot;Another approach is to pass a callback function to the thread. This gives a simple, safe and flexible way to return a value to the parent, anytime from the new thread.&amp;quot;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import threading&lt;br /&gt;
import time&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
class MyThread(threading.Thread):&lt;br /&gt;
    def __init__(self, cb):&lt;br /&gt;
        threading.Thread.__init__(self)&lt;br /&gt;
        self.callback = cb&lt;br /&gt;
    def run(self):&lt;br /&gt;
        for i in range(10):&lt;br /&gt;
            self.callback(i)&lt;br /&gt;
            time.sleep(1)&lt;br /&gt;
&lt;br /&gt;
def count(x):&lt;br /&gt;
    print x&lt;br /&gt;
    sys.stdout.flush()&lt;br /&gt;
&lt;br /&gt;
t = MyThread(count)&lt;br /&gt;
t.start()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* 16.2. threading — Higher-level threading interface — Python v2.7.1 documentation - http://docs.python.org/library/threading.html&lt;br /&gt;
* An Introduction to Thread Programming - http://www.prasannatech.net/2008/08/introduction-to-thread-programming.html&lt;br /&gt;
* Python - Multithreaded Programming - http://www.tutorialspoint.com/python/python_multithreading.htm&lt;br /&gt;
* Running Functions as Threads in Python « Software Ramblings - http://softwareramblings.com/2008/06/running-functions-as-threads-in-python.html&lt;br /&gt;
* Understanding Threading in Python LG #107 - http://linuxgazette.net/107/pai.html&lt;br /&gt;
* multithreading - Simple threading in Python 2.6 using thread.start_new_thread() - Stack Overflow - http://stackoverflow.com/questions/849674/simple-threading-in-python-2-6-using-thread-start-new-thread&lt;br /&gt;
* python - Return value from thread - Stack Overflow - http://stackoverflow.com/questions/1886090/return-value-from-thread&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
Interrupt main thread:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# source: http://stackoverflow.com/questions/4591917/python-how-to-quit-cli-when-stuck-in-blocking-raw-input&lt;br /&gt;
&lt;br /&gt;
import thread&lt;br /&gt;
import time&lt;br /&gt;
&lt;br /&gt;
def main():&lt;br /&gt;
    try:&lt;br /&gt;
        m = thread.start_new_thread(killable_input, tuple())&lt;br /&gt;
        while 1:&lt;br /&gt;
            time.sleep(0.1) &lt;br /&gt;
    except KeyboardInterrupt:&lt;br /&gt;
        print &amp;quot;exception&amp;quot; &lt;br /&gt;
&lt;br /&gt;
def killable_input():&lt;br /&gt;
    w = thread.start_new_thread(normal_input, tuple())&lt;br /&gt;
    i = thread.start_new_thread(wait_sometime, tuple())&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def normal_input():&lt;br /&gt;
    s = raw_input(&amp;quot;input:&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def wait_sometime():&lt;br /&gt;
    time.sleep(4) # or any other condition to kill the thread&lt;br /&gt;
    print &amp;quot;too slow, killing imput&amp;quot;&lt;br /&gt;
    thread.interrupt_main()&lt;br /&gt;
&lt;br /&gt;
if __name__ == &#039;__main__&#039;:&lt;br /&gt;
    main()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== urllib ===&lt;br /&gt;
&lt;br /&gt;
See [[Python/urllib]]&lt;br /&gt;
&lt;br /&gt;
=== Command line arguments ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import sys&lt;br /&gt;
for x in sys.argv:&lt;br /&gt;
    print x&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Execute other python script ===&lt;br /&gt;
&lt;br /&gt;
 import sys&lt;br /&gt;
 sys.argv = [&#039;&#039;, &#039;my&#039;, &#039;args&#039;, &#039;here&#039;]&lt;br /&gt;
 execfile(&#039;myscript.py&#039;)  # does not support arguments directly&lt;br /&gt;
&lt;br /&gt;
=== Exit Code ===&lt;br /&gt;
&lt;br /&gt;
sys.exit(n) http://docs.python.org/library/sys.html:&lt;br /&gt;
 import sys&lt;br /&gt;
 sys.exit(1)  # exit code of 1 (default is 0)&lt;br /&gt;
 sys.exit(&amp;quot;some error&amp;quot;)  # exit code of 1, and message displayed&lt;br /&gt;
&lt;br /&gt;
=== [http://docs.python.org/library/syslog.html syslog] ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import syslog&lt;br /&gt;
syslog.openlog(&#039;[WATER]&#039;)&lt;br /&gt;
syslog.syslog(&#039;Processing started&#039;)&lt;br /&gt;
if error:&lt;br /&gt;
    syslog.syslog(syslog.LOG_ERR, &#039;Processing started&#039;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import syslog&lt;br /&gt;
syslog.openlog(&#039;[WATER]&#039;)&lt;br /&gt;
def log(msg):&lt;br /&gt;
    syslog.syslog(str(msg))&lt;br /&gt;
log(&amp;quot;Starting...&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Subprocess ===&lt;br /&gt;
&lt;br /&gt;
Subprocess - http://docs.python.org/library/subprocess.html&lt;br /&gt;
&lt;br /&gt;
Methods of subprocess (or external command execution):&lt;br /&gt;
* subprocess (only method to rule/replace all others)&lt;br /&gt;
* os.system&lt;br /&gt;
* os.spawn*&lt;br /&gt;
* os.popen*&lt;br /&gt;
* popen2.*&lt;br /&gt;
* commands.*&lt;br /&gt;
&lt;br /&gt;
My New Favorite:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import subprocess&lt;br /&gt;
class Run(object):&lt;br /&gt;
    class RC(int):&lt;br /&gt;
        pass&lt;br /&gt;
    def __new__(cls, cmd, *args, **kwargs):&lt;br /&gt;
        p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)&lt;br /&gt;
        rc = cls.RC(p.wait())&lt;br /&gt;
        rc.output = &amp;quot;\n&amp;quot;.join(p.stdout.readlines())&lt;br /&gt;
        rc.error = &amp;quot;\n&amp;quot;.join(p.stderr.readlines())&lt;br /&gt;
        return rc&lt;br /&gt;
&lt;br /&gt;
if Run(&amp;quot;some command&amp;quot;): print &amp;quot;do something&amp;quot;  # on rc of not 0 (negative or positive)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
My Favorite:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def exe(cmd):&lt;br /&gt;
    p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)&lt;br /&gt;
    #output = &amp;quot; | &amp;quot;.join(p.stdout.readlines())&lt;br /&gt;
    output = &amp;quot;\n&amp;quot;.join(p.stdout.readlines())&lt;br /&gt;
    rc = p.wait()&lt;br /&gt;
    return (rc, output)&lt;br /&gt;
&lt;br /&gt;
def exe_checked(cmd, checked=True):&lt;br /&gt;
    p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)&lt;br /&gt;
    #output = &amp;quot; | &amp;quot;.join(p.stdout.readlines())&lt;br /&gt;
    output = &amp;quot;\n&amp;quot;.join(p.stdout.readlines())&lt;br /&gt;
    rc = p.wait()&lt;br /&gt;
    if rc and checked:&lt;br /&gt;
        raise Exception(&amp;quot;Command returned non zero [{0}]: {1}&amp;quot;.format(rc, cmd)&lt;br /&gt;
    return (rc, output)&lt;br /&gt;
&lt;br /&gt;
def exe_with_stderr(cmd):&lt;br /&gt;
    p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subproc&lt;br /&gt;
ess.PIPE)&lt;br /&gt;
    output = &amp;quot; | &amp;quot;.join(p.stdout.readlines())&lt;br /&gt;
    outputerr = &amp;quot; | &amp;quot;.join(p.stderr.readlines())&lt;br /&gt;
    rc = p.wait()&lt;br /&gt;
    return (rc, output, outputerr)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def exec_program(cmd):&lt;br /&gt;
    s = subprocess.Popen(cmd.split(), stdout=subprocess.PIPE, stderr=subprocess.PIPE)&lt;br /&gt;
    stdout, stderr = s.communicate()&lt;br /&gt;
    result = s.wait()&lt;br /&gt;
    return stdout, stderr, result&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pass along output and return true error code:&lt;br /&gt;
 import subprocess&lt;br /&gt;
 retcode = subprocess.call([&amp;quot;ls&amp;quot;, &amp;quot;-l&amp;quot;])  # true return code, output sent to STDOUT&lt;br /&gt;
&lt;br /&gt;
 retcode = subprocess.call([&amp;quot;foo.sh&amp;quot;,&amp;quot;args&amp;quot;],shell=True)  # Execute in shell, with shell processing&lt;br /&gt;
 retcode = subprocess.call([&#039;C:\\Temp\\a b c\\Notepad.exe&#039;])&lt;br /&gt;
 retcode = subprocess.call([&amp;quot;D:/Python24/Python.exe&amp;quot;, &amp;quot;Skripta.py&amp;quot;, &amp;quot;arg1&amp;quot;, &amp;quot;arg2&amp;quot;])&lt;br /&gt;
&lt;br /&gt;
Note: shell=True is equivalent to: subprocess.Popen([&#039;/bin/sh&#039;, &#039;-c&#039;, args[0], args[1], ...])&lt;br /&gt;
&lt;br /&gt;
Process STDOUT and STDERR and get return code:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
import subprocess&lt;br /&gt;
import string&lt;br /&gt;
&lt;br /&gt;
cmd = &amp;quot;cat /etc/passwd | grep ken&amp;quot;&lt;br /&gt;
p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) # stderr=subprocess.STDOUT to combine&lt;br /&gt;
&lt;br /&gt;
out = string.join(p.stdout.readlines())&lt;br /&gt;
outerr = string.join(p.stderr.readlines())&lt;br /&gt;
retcode = str(p.wait())&lt;br /&gt;
&lt;br /&gt;
print(&amp;quot;STDOUT: &amp;quot; + out)&lt;br /&gt;
print(&amp;quot;STDERR: &amp;quot; + outerr)&lt;br /&gt;
print(&amp;quot;RETCODE: &amp;quot; + retcode)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Above with stderr redirected to stdout (combined):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import subprocess&lt;br /&gt;
p = subprocess.Popen(&#039;ls&#039;, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)&lt;br /&gt;
for line in p.stdout.readlines():&lt;br /&gt;
    print line,&lt;br /&gt;
retval = p.wait()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Replacing shell backtick: [http://docs.python.org/library/subprocess.html]&lt;br /&gt;
 # shell code:&lt;br /&gt;
 # OUTPUT=`mycmd myarg`&lt;br /&gt;
 from subprocess import Popen&lt;br /&gt;
 output = Popen([&amp;quot;mycmd&amp;quot;, &amp;quot;myarg&amp;quot;], stdout=PIPE).communicate()[0]&lt;br /&gt;
&lt;br /&gt;
Replacing shell pipeline  [http://docs.python.org/library/subprocess.html]&lt;br /&gt;
 # shell code:&lt;br /&gt;
 # OUTPUT=`dmesg | grep hda`&lt;br /&gt;
 from subprocess import Popen&lt;br /&gt;
 p1 = Popen([&amp;quot;dmesg&amp;quot;], stdout=PIPE)&lt;br /&gt;
 p2 = Popen([&amp;quot;grep&amp;quot;, &amp;quot;hda&amp;quot;], stdin=p1.stdout, stdout=PIPE)&lt;br /&gt;
 p1.stdout.close()  # Allow p1 to receive a SIGPIPE if p2 exits.&lt;br /&gt;
 output = p2.communicate()[0]&lt;br /&gt;
&lt;br /&gt;
Replacing os.system(): [http://docs.python.org/library/subprocess.html]&lt;br /&gt;
 # old:&lt;br /&gt;
 sts = os.system(&amp;quot;mycmd&amp;quot; + &amp;quot; myarg&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
 # new:&lt;br /&gt;
 p = Popen(&amp;quot;mycmd&amp;quot; + &amp;quot; myarg&amp;quot;, shell=True)&lt;br /&gt;
 sts = os.waitpid(p.pid, 0)[1]&lt;br /&gt;
&lt;br /&gt;
Control an executed process:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cmd = &amp;quot;/usr/bin/java -Xms256M -Xmx1024M -jar minecraft_server.jar nogui&amp;quot;&lt;br /&gt;
&lt;br /&gt;
p = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE,&lt;br /&gt;
        stdout=subprocess.PIPE, stderr=subprocess.STDOUT)&lt;br /&gt;
&lt;br /&gt;
# cycle while process continues alive&lt;br /&gt;
while p.poll() == None:&lt;br /&gt;
&lt;br /&gt;
  # check if input&lt;br /&gt;
  if select.select([p.stdout.fileno()], [], [], 1)[0]:&lt;br /&gt;
    while select.select([p.stdout.fileno()], [], [], .1)[0]:&lt;br /&gt;
        line = p.stdout.readline()&lt;br /&gt;
        # ... process&lt;br /&gt;
&lt;br /&gt;
  # write something to process&lt;br /&gt;
  p.stdin.write(&amp;quot;tp %s %s\n&amp;quot; % (user1, user2))&lt;br /&gt;
&lt;br /&gt;
  ...&lt;br /&gt;
&lt;br /&gt;
  # time to force a quit: (choose which you need)&lt;br /&gt;
  p.kill()  # SIGKILL&lt;br /&gt;
  p.terminate()  # SIGTERM&lt;br /&gt;
  os.kill(p.pid, signal.SIGTERM)  # same as first, but not as clean&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Other Command Execution ====&lt;br /&gt;
&lt;br /&gt;
Old method with os.system(): [http://docs.python.org/library/os.html]&lt;br /&gt;
 import os&lt;br /&gt;
 encoded_wait_code = os.system(&amp;quot;some command&amp;quot;)  # output sent to STDOUT&lt;br /&gt;
 # Note: returns code of 0 if command returns 0, but wait() encoded value for all other values&lt;br /&gt;
&lt;br /&gt;
Quick and dirty old method (prints stderr, captures stdout)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import os&lt;br /&gt;
out = string.join( os.popen(cmd).readlines() )&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Quick and dirty old method (prints stderr, captures stdout, captures ugly wait() encoded return code)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import os&lt;br /&gt;
p = os.popen(cmd)&lt;br /&gt;
stdout = &amp;quot;&amp;quot;.join( p.readlines() )&lt;br /&gt;
encoded_wait_code = p.close()  # None if 0&lt;br /&gt;
rcode = os.WEXITSTATUS(ugly_rcode) # fix ugly wait() encoded rcode&lt;br /&gt;
print(stdout)&lt;br /&gt;
print(rcode)&lt;br /&gt;
&lt;br /&gt;
if os.popen(cmd).close():&lt;br /&gt;
  print &amp;quot;error with cmd: %s&amp;quot; % cmd&lt;br /&gt;
  sys.exit(1)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
???:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
os.spawnvp(os.P_WAIT,&amp;quot;/usr/bin/mplayer&amp;quot;,[&amp;quot;&amp;quot;,&amp;quot;-ao&amp;quot;,&amp;quot;pcm&amp;quot;,file])&lt;br /&gt;
# or &lt;br /&gt;
os.spawnvp(os.P_NOWAIT,&amp;quot;/usr/bin/mplayer&amp;quot;,[&amp;quot;&amp;quot;,&amp;quot;-ao&amp;quot;,&amp;quot;pcm&amp;quot;,file])&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Replacing os.system(): [http://docs.python.org/library/subprocess.html]&lt;br /&gt;
 # old:&lt;br /&gt;
 sts = os.system(&amp;quot;mycmd&amp;quot; + &amp;quot; myarg&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
 # new:&lt;br /&gt;
 p = Popen(&amp;quot;mycmd&amp;quot; + &amp;quot; myarg&amp;quot;, shell=True)&lt;br /&gt;
 sts = os.waitpid(p.pid, 0)[1]&lt;br /&gt;
&lt;br /&gt;
More realistic example replacing os.system(): [http://docs.python.org/library/subprocess.html]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
try:&lt;br /&gt;
    retcode = call(&amp;quot;mycmd&amp;quot; + &amp;quot; myarg&amp;quot;, shell=True)&lt;br /&gt;
    if retcode &amp;lt; 0:&lt;br /&gt;
        print &amp;gt;&amp;gt;sys.stderr, &amp;quot;Child was terminated by signal&amp;quot;, -retcode&lt;br /&gt;
    else:&lt;br /&gt;
        print &amp;gt;&amp;gt;sys.stderr, &amp;quot;Child returned&amp;quot;, retcode&lt;br /&gt;
except OSError, e:&lt;br /&gt;
    print &amp;gt;&amp;gt;sys.stderr, &amp;quot;Execution failed:&amp;quot;, e&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== select ====&lt;br /&gt;
&lt;br /&gt;
Select:&lt;br /&gt;
&lt;br /&gt;
select.select(rlist, wlist, xlist[, timeout])&lt;br /&gt;
: This is a straightforward interface to the Unix select() system call. The first three arguments are sequences of ‘waitable objects’: either integers representing file descriptors or objects with a parameterless method named fileno() returning such an integer&lt;br /&gt;
: The optional timeout argument specifies a time-out as a floating point number in seconds. When the timeout argument is omitted the function blocks until at least one file descriptor is ready. A time-out value of zero specifies a poll and never blocks.&lt;br /&gt;
&lt;br /&gt;
 if select.select([sys.stdin.fileno()], [], [], .1)[0]:&lt;br /&gt;
     line = p.stdout.readline()&lt;br /&gt;
&lt;br /&gt;
==== full wrapped execution ====&lt;br /&gt;
&lt;br /&gt;
Process timeout (by Kenneth):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import subprocess&lt;br /&gt;
import time&lt;br /&gt;
import os&lt;br /&gt;
import signal&lt;br /&gt;
&lt;br /&gt;
def cmd(cmd, timeout=300, retry=0):&lt;br /&gt;
    # Execute command, time progress, and kill on timeout&lt;br /&gt;
&lt;br /&gt;
    # (status, output) = commands.getstatusoutput(cmd)&lt;br /&gt;
    start_time = None&lt;br /&gt;
    status = None&lt;br /&gt;
    output = None&lt;br /&gt;
    for retry_count in range(retry+1):&lt;br /&gt;
        if retry_count &amp;gt; 0:&lt;br /&gt;
            print(&amp;quot;RETRY: &amp;quot; + str(retry_count) + &amp;quot; &amp;quot; + cmd)&lt;br /&gt;
        start_time = time.time()&lt;br /&gt;
        p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE,&lt;br /&gt;
                stderr=subprocess.STDOUT)&lt;br /&gt;
        timeout_fail = False&lt;br /&gt;
        while p.poll() == None:&lt;br /&gt;
            if time.time() - start_time &amp;gt; timeout:&lt;br /&gt;
                # kill process&lt;br /&gt;
                print(&amp;quot;TIMEOUT: &amp;quot; + str(timeout) + &amp;quot;sec - killing (&amp;quot; + str(p.pid) + &amp;quot;) - &amp;quot; + cmd)&lt;br /&gt;
                try:&lt;br /&gt;
                    os.kill(p.pid, signal.SIGTERM)&lt;br /&gt;
                except OSError as e:&lt;br /&gt;
                    print(&amp;quot;Kill exception: &amp;quot; + str(e))&lt;br /&gt;
                timeout_fail = True&lt;br /&gt;
                break&lt;br /&gt;
            #print(&amp;quot;.&amp;quot;)&lt;br /&gt;
            time.sleep(1)&lt;br /&gt;
        status = p.poll()&lt;br /&gt;
        output = p.stdout.read()&lt;br /&gt;
        if timeout_fail == False:&lt;br /&gt;
            break&lt;br /&gt;
    seconds = int(time.time() - start_time)&lt;br /&gt;
    return (status, output, seconds)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
Process input and output wrapper (from minecraft):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import subprocess&lt;br /&gt;
import select&lt;br /&gt;
import re&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
cmd = &amp;quot;/usr/bin/java -Xms256M -Xmx1024M -jar minecraft_server.jar nogui&amp;quot;&lt;br /&gt;
&lt;br /&gt;
p = subprocess.Popen(cmd, shell=True,&lt;br /&gt;
        stdin=subprocess.PIPE,&lt;br /&gt;
        stdout=subprocess.PIPE,&lt;br /&gt;
        stderr=subprocess.STDOUT)&lt;br /&gt;
&lt;br /&gt;
# cycle while process continues alive&lt;br /&gt;
while p.poll() == None:&lt;br /&gt;
&lt;br /&gt;
    if select.select([p.stdout.fileno()], [], [], 1)[0]:&lt;br /&gt;
        while select.select([p.stdout.fileno()], [], [], .1)[0]:&lt;br /&gt;
            line = p.stdout.readline()&lt;br /&gt;
            # &amp;lt;kiloforce&amp;gt; -tp joe&lt;br /&gt;
            match = re.findall(&amp;quot;&amp;lt;(.*)&amp;gt; -tp (.*)&amp;quot;, line)&lt;br /&gt;
            if match:&lt;br /&gt;
                user1 = match[0][0]&lt;br /&gt;
                user2 = match[0][1]&lt;br /&gt;
                print &amp;quot;&amp;gt;&amp;gt; ACTION: Teleporting %s to %s&amp;quot; % (user1, user2)&lt;br /&gt;
                p.stdin.write(&amp;quot;tp %s %s\n&amp;quot; % (user1, user2))&lt;br /&gt;
            if line:&lt;br /&gt;
                print &amp;quot;&amp;gt;&amp;gt; SERVER: %s&amp;quot; % line.strip()&lt;br /&gt;
            else:&lt;br /&gt;
                print &amp;quot;The server died!&amp;quot;&lt;br /&gt;
                sys.exit(1)&lt;br /&gt;
&lt;br /&gt;
    if select.select([sys.stdin.fileno()], [], [], .1)[0]:&lt;br /&gt;
        line = sys.stdin.readline()&lt;br /&gt;
        print &amp;quot;&amp;gt;&amp;gt; CONSOLE: %s&amp;quot; % line.strip()&lt;br /&gt;
        p.stdin.write(&amp;quot;%s&amp;quot; % line)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Command With Timeout ====&lt;br /&gt;
&lt;br /&gt;
python - Using module &#039;subprocess&#039; with timeout - Stack Overflow - http://stackoverflow.com/questions/1191374/using-module-subprocess-with-timeout&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import subprocess, threading&lt;br /&gt;
&lt;br /&gt;
class Command(object):&lt;br /&gt;
    def __init__(self, cmd):&lt;br /&gt;
        self.cmd = cmd&lt;br /&gt;
        self.process = None&lt;br /&gt;
&lt;br /&gt;
    def run(self, timeout):&lt;br /&gt;
        def target():&lt;br /&gt;
            print &#039;Thread started&#039;&lt;br /&gt;
            self.process = subprocess.Popen(self.cmd, shell=True)&lt;br /&gt;
            self.process.communicate()&lt;br /&gt;
            print &#039;Thread finished&#039;&lt;br /&gt;
&lt;br /&gt;
        thread = threading.Thread(target=target)&lt;br /&gt;
        thread.start()&lt;br /&gt;
&lt;br /&gt;
        thread.join(timeout)&lt;br /&gt;
        if thread.is_alive():&lt;br /&gt;
            print &#039;Terminating process&#039;&lt;br /&gt;
            self.process.terminate()&lt;br /&gt;
            thread.join()&lt;br /&gt;
        print self.process.returncode&lt;br /&gt;
&lt;br /&gt;
command = Command(&amp;quot;echo &#039;Process started&#039;; sleep 2; echo &#039;Process finished&#039;&amp;quot;)&lt;br /&gt;
command.run(timeout=3)&lt;br /&gt;
command.run(timeout=1)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
My version:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import subprocess&lt;br /&gt;
import threading&lt;br /&gt;
&lt;br /&gt;
class Command(object):&lt;br /&gt;
    def __init__(self, cmd, capture=False, shell=True):&lt;br /&gt;
        self.cmd = cmd&lt;br /&gt;
        self.process = None&lt;br /&gt;
        self.thread = None&lt;br /&gt;
        self.shell = shell&lt;br /&gt;
        if type(cmd) == list:&lt;br /&gt;
            self.shell = False&lt;br /&gt;
        self.rc = None&lt;br /&gt;
        self.pid = None&lt;br /&gt;
        self.stdout = None&lt;br /&gt;
        self.stderr = None&lt;br /&gt;
        self.capture = capture  # capture stdout?&lt;br /&gt;
&lt;br /&gt;
    def run(self, timeout=None, wait=True):&lt;br /&gt;
        def target():&lt;br /&gt;
            print &#039;&amp;gt;&amp;gt; Thread started (%s)&#039; % self.cmd&lt;br /&gt;
            if self.capture:&lt;br /&gt;
                self.process = subprocess.Popen(self.cmd, shell=self.shell, stdout=subprocess.PIPE, stderr=subprocess.PIPE)&lt;br /&gt;
            else:&lt;br /&gt;
                self.process = subprocess.Popen(self.cmd, shell=self.shell)&lt;br /&gt;
            print &#039;&amp;gt;&amp;gt; Thread PID: %d&#039; % self.process.pid&lt;br /&gt;
            self.pid = self.process.pid&lt;br /&gt;
            self.stdout, self.stderr = self.process.communicate()&lt;br /&gt;
            self.rc = self.process.returncode&lt;br /&gt;
            print &#039;&amp;gt;&amp;gt; Thread finished: %d&#039; % self.rc&lt;br /&gt;
&lt;br /&gt;
        self.thread = threading.Thread(target=target)&lt;br /&gt;
        self.thread.start()&lt;br /&gt;
&lt;br /&gt;
        if wait:&lt;br /&gt;
            self.wait(timeout)&lt;br /&gt;
        return self  # so you can do: c = Command().run()&lt;br /&gt;
&lt;br /&gt;
    def wait(self, timeout=None):&lt;br /&gt;
        print &#039;&amp;gt;&amp;gt; Waiting for thread...&#039;&lt;br /&gt;
        if timeout:&lt;br /&gt;
            self.thread.join(timeout)&lt;br /&gt;
        else:&lt;br /&gt;
            self.thread.join()&lt;br /&gt;
        if self.thread.is_alive():&lt;br /&gt;
            print &#039;&amp;gt;&amp;gt; Terminating process&#039;&lt;br /&gt;
            self.process.terminate()&lt;br /&gt;
            self.rc = self.process.returncode&lt;br /&gt;
            self.thread.join()&lt;br /&gt;
            if self.thread.is_alive():&lt;br /&gt;
                print &#039;&amp;gt;&amp;gt; Failed to terminate&#039;&lt;br /&gt;
        else:&lt;br /&gt;
            print &#039;&amp;gt;&amp;gt; Thread completed&#039;&lt;br /&gt;
        #print self.process.returncode&lt;br /&gt;
&lt;br /&gt;
    def is_alive(self ):&lt;br /&gt;
        return self.thread.is_alive()&lt;br /&gt;
&lt;br /&gt;
command = Command(&#039;do something&#039;).run()&lt;br /&gt;
&lt;br /&gt;
command2 = Command([&#039;do&#039;, &#039;something&#039;, &#039;long&#039;]).run(wait=False)&lt;br /&gt;
command2.wait(timeout=10)&lt;br /&gt;
&lt;br /&gt;
command3 = Command(&#039;want output&#039;, capture=True).run()&lt;br /&gt;
print command3.stdout&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== System call ===&lt;br /&gt;
&lt;br /&gt;
 os.system(&amp;quot;some_command with args&amp;quot;)&lt;br /&gt;
 os.system(&amp;quot;some_command &amp;lt; input_file | another_command &amp;gt; output_file&amp;quot;)&lt;br /&gt;
 stream = os.popen(&amp;quot;some_command with args&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Here&#039;s a summary of the ways to call external programs and the advantages and disadvantages of each:&lt;br /&gt;
&lt;br /&gt;
1.&lt;br /&gt;
: os.system(&amp;quot;some_command with args&amp;quot;) passes the command and arguments to your system&#039;s shell. This is nice because you can actually run multiple commands at once in this manner and set up pipes and input/output redirection. For example,&lt;br /&gt;
: os.system(&amp;quot;some_command &amp;lt; input_file | another_command &amp;gt; output_file&amp;quot;)&lt;br /&gt;
: However, while this is convenient, you have to manually handle the escaping of shell characters such as spaces, etc. On the other hand, this also lets you run commands which are simply shell commands and not actually external programs.&lt;br /&gt;
: http://docs.python.org/lib/os-process.html&lt;br /&gt;
&lt;br /&gt;
2.&lt;br /&gt;
: stream = os.popen(&amp;quot;some_command with args&amp;quot;) will do the same thing as os.system except that it gives you a file-like object that you can use to access standard input/output for that process. There are 3 other variants of popen that all handle the i/o slightly differently. If you pass everything as a string, then your command is passed to the shell; if you pass them as a list then you don&#039;t need to worry about escaping anything.&lt;br /&gt;
: http://docs.python.org/lib/os-newstreams.html&lt;br /&gt;
&lt;br /&gt;
3.&lt;br /&gt;
: The Popen class of the subprocess module. This is intended as a replacement for os.popen but has the downside of being slightly more complicated by virtue of being so comprehensive. For example, you&#039;d say&lt;br /&gt;
: print Popen(&amp;quot;echo Hello World&amp;quot;, stdout=PIPE, shell=True).stdout.read()&lt;br /&gt;
: instead of&lt;br /&gt;
: print os.popen(&amp;quot;echo Hello World&amp;quot;).read()&lt;br /&gt;
: but it is nice to have all of the options there in one unified class instead of 4 different popen functions.&lt;br /&gt;
: http://docs.python.org/lib/node528.html&lt;br /&gt;
&lt;br /&gt;
4.&lt;br /&gt;
: The call function from the subprocess module. This is basically just like the Popen class and takes all of the same arguments, but it simply wait until the command completes and gives you the return code. For example:&lt;br /&gt;
: return_code = call(&amp;quot;echo Hello World&amp;quot;, shell=True)&lt;br /&gt;
: http://docs.python.org/lib/node529.html&lt;br /&gt;
&lt;br /&gt;
5.&lt;br /&gt;
: The os module also has all of the fork/exec/spawn functions that you&#039;d have in a C program, but I don&#039;t recommend using them directly.&lt;br /&gt;
&lt;br /&gt;
: The subprocess module should probably be what you use.&lt;br /&gt;
&lt;br /&gt;
Source: [http://stackoverflow.com/questions/89228/how-to-call-external-command-in-python]&lt;br /&gt;
&lt;br /&gt;
== Advanced Code ==&lt;br /&gt;
&lt;br /&gt;
=== Executing Code from Command Line ===&lt;br /&gt;
&lt;br /&gt;
 python -c [cmd]&lt;br /&gt;
 # -c cmd : program passed in as string (terminates option list)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python -c &amp;quot;import sys;exec(sys.stdin.read())&amp;quot; &amp;lt;&amp;lt; &amp;quot;EOF&amp;quot;&lt;br /&gt;
def test1():&lt;br /&gt;
  print &amp;quot;test1&amp;quot;&lt;br /&gt;
test1()&lt;br /&gt;
print &amp;quot;test&amp;quot;&lt;br /&gt;
EOF&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Integer Return Code Class ===&lt;br /&gt;
&lt;br /&gt;
Python3 version:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class RC(int):&lt;br /&gt;
  def __new__(cls, rc, stdout=&#039;&#039;, stderr=&#039;&#039;):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;We can&#039;t use use __init__ because int is immutable.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    return super(RC, cls).__new__(cls, rc)&lt;br /&gt;
  def __init__(self, rc, stdout=&#039;&#039;, stderr=&#039;&#039;):&lt;br /&gt;
    super().__init__()&lt;br /&gt;
    self.rc = rc  # redundant&lt;br /&gt;
    self.stdout = stdout&lt;br /&gt;
    self.stderr = stderr&lt;br /&gt;
  def __repr__(self):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;Optional string output&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    return &amp;quot;(%s, &#039;%s&#039;, &#039;%s&#039;)&amp;quot; % (self.rc, self.stdout, self.stderr)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Python2 version:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class RC(int):&lt;br /&gt;
  def __new__(cls, rc, stdout=&#039;&#039;, stderr=&#039;&#039;):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;We can&#039;t use use __init__ because int is immutable.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    return super(RC, cls).__new__(cls, rc)&lt;br /&gt;
  def __init__(self, rc, stdout=&#039;&#039;, stderr=&#039;&#039;):&lt;br /&gt;
    super(self.__class__, self).__init__(rc)&lt;br /&gt;
    self.rc = rc  # redundant&lt;br /&gt;
    self.stdout = stdout&lt;br /&gt;
    self.stderr = stderr&lt;br /&gt;
  def __repr__(self):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;Optional string output&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    return &amp;quot;(%s, &#039;%s&#039;, &#039;%s&#039;)&amp;quot; % (self, self.stdout, self.stderr)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
sample:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; rc1 = RC(5)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; rc2 = RC(0, &#039;out&#039;, &#039;err&#039;)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; rc1&lt;br /&gt;
(5, &#039;&#039;, &#039;&#039;)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; rc2&lt;br /&gt;
(5, &#039;out&#039;, &#039;err&#039;)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; rc2.stdout&lt;br /&gt;
&#039;out&#039;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; int(rc1)&lt;br /&gt;
5&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; 0 + rc1&lt;br /&gt;
5&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; if rc1 &amp;lt;= 5:  print &amp;quot;yes&amp;quot;&lt;br /&gt;
...&lt;br /&gt;
yes&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; if rc2:  print &amp;quot;non-zero&amp;quot;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Smart Execute ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class RC(int):&lt;br /&gt;
    def __new__(cls, rc, output=&#039;&#039;):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;We can&#039;t use use __init__ because int is immutable.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        return super(RC, cls).__new__(cls, rc)&lt;br /&gt;
    def __init__(self, rc, output=&#039;&#039;):&lt;br /&gt;
        super().__init__()&lt;br /&gt;
        self.rc = rc  # redundant&lt;br /&gt;
        self.output = output&lt;br /&gt;
    def __repr__(self):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Optional string output&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        return &amp;quot;(%s, &#039;%s&#039;)&amp;quot; % (self.rc, self.output)&lt;br /&gt;
&lt;br /&gt;
def smart_execute(cmd, display=True, checked=False):&lt;br /&gt;
    output = &amp;quot;&amp;quot;&lt;br /&gt;
    process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, bufsize=1, shell=True, encoding=&#039;utf-8&#039;)&lt;br /&gt;
    for c in iter(lambda: process.stdout.read(1), &amp;quot;&amp;quot;):&lt;br /&gt;
        if display:&lt;br /&gt;
            sys.stdout.buffer.write(c.encode(&#039;utf-8&#039;))&lt;br /&gt;
        output += c&lt;br /&gt;
    process.stdout.close()&lt;br /&gt;
    rc = process.wait()&lt;br /&gt;
    if checked and rc:&lt;br /&gt;
        raise subprocess.CalledProcessError(ret, cmd)&lt;br /&gt;
    return RC(rc, output.strip())&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Not smart version:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def execute(cmd, return_output=False):&lt;br /&gt;
    out = &amp;quot;&amp;quot;&lt;br /&gt;
    process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, bufsize=1, shell=True, encoding=&#039;utf-8&#039;)&lt;br /&gt;
    for c in iter(lambda: process.stdout.read(1), &amp;quot;&amp;quot;):&lt;br /&gt;
        sys.stdout.buffer.write(c.encode(&#039;utf-8&#039;))&lt;br /&gt;
        if return_output:&lt;br /&gt;
            out += c&lt;br /&gt;
    process.stdout.close()&lt;br /&gt;
    ret = process.wait()&lt;br /&gt;
    if ret:&lt;br /&gt;
        raise subprocess.CalledProcessError(ret, cmd)&lt;br /&gt;
    if return_output:&lt;br /&gt;
        return out.strip()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== select ===&lt;br /&gt;
&lt;br /&gt;
usage: select.select(rlist, wlist, xlist[, timeout]) [http://docs.python.org/2/library/select.html]&lt;br /&gt;
* rlist: wait until ready for reading&lt;br /&gt;
* wlist: wait until ready for writing&lt;br /&gt;
* xlist: wait for an “exceptional condition” (see the manual page for what your system considers such a condition)&lt;br /&gt;
* The optional timeout argument specifies a time-out as a floating point number in seconds.&lt;br /&gt;
&lt;br /&gt;
 if select.select([p.stdout.fileno()], [], [], 1)[0]:&lt;br /&gt;
&lt;br /&gt;
=== ANSI Color ===&lt;br /&gt;
&lt;br /&gt;
* ANSI escape code - http://en.wikipedia.org/wiki/ANSI_escape_code&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
unicode - Print in terminal with colors using Python? - Stack Overflow - https://stackoverflow.com/questions/287871/print-in-terminal-with-colors-using-python&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class bcolors:&lt;br /&gt;
    HEADER = &#039;\033[95m&#039;&lt;br /&gt;
    OKBLUE = &#039;\033[94m&#039;&lt;br /&gt;
    OKGREEN = &#039;\033[92m&#039;&lt;br /&gt;
    WARNING = &#039;\033[93m&#039;&lt;br /&gt;
    FAIL = &#039;\033[91m&#039;&lt;br /&gt;
    ENDC = &#039;\033[0m&#039;&lt;br /&gt;
    BOLD = &#039;\033[1m&#039;&lt;br /&gt;
    UNDERLINE = &#039;\033[4m&#039;&lt;br /&gt;
&lt;br /&gt;
print bcolors.WARNING + &amp;quot;Warning: No active frommets remain. Continue?&amp;quot; + bcolors.ENDC&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class colors:&lt;br /&gt;
  black = 0&lt;br /&gt;
  red = 1&lt;br /&gt;
  green = 2&lt;br /&gt;
  yellow = 3&lt;br /&gt;
  blue = 4&lt;br /&gt;
  magenta = 5&lt;br /&gt;
  cyan = 6&lt;br /&gt;
  white = 7&lt;br /&gt;
  fg = 30  # foreground add&lt;br /&gt;
  bg = 40  # background add&lt;br /&gt;
  bfg = 90  # bold foreground add&lt;br /&gt;
  bbg = 100  # bold background add&lt;br /&gt;
&lt;br /&gt;
print &#039;\033[%dm red foreground \033[0m&#039; % (colors.red + colors.fg)&lt;br /&gt;
print &#039;\033[%dm bold red foreground \033[0m&#039; % (colors.red + colors.bfg)&lt;br /&gt;
print &#039;\033[%dm blue background \033[0m&#039; % (colors.blue + colors.bg)&lt;br /&gt;
print &#039;\033[%dm bold blue background \033[0m&#039; % (colors.blue + colors.bbg)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
Before you start spouting escape sequences, you should check that stdout is a tty. You can do this with sys.stdout.isatty()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sys.stdout.isatty()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def hilite(string, status, bold):&lt;br /&gt;
    attr = []&lt;br /&gt;
    if status:&lt;br /&gt;
        # green&lt;br /&gt;
        attr.append(&#039;32&#039;)&lt;br /&gt;
    else:&lt;br /&gt;
        # red&lt;br /&gt;
        attr.append(&#039;31&#039;)&lt;br /&gt;
    if bold:&lt;br /&gt;
        attr.append(&#039;1&#039;)&lt;br /&gt;
    return &#039;\x1b[%sm%s\x1b[0m&#039; % (&#039;;&#039;.join(attr), string)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Python | change text color in shell - Stack Overflow - https://stackoverflow.com/questions/2330245/python-change-text-color-in-shell&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
For reference, a small bash script which prints a table of escape sequences: colortable16.sh: ([http://www.frexx.de/xterm-256-notes/ The 256 color mode of xterm], [http://plug.org/pipermail/plug/2008-March/016821.html The 90s called; they want their 256 colors back])&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
&lt;br /&gt;
# prints a color table of 8bg * 8fg * 2 states (regular/bold)&lt;br /&gt;
echo&lt;br /&gt;
echo Table for 16-color terminal escape sequences.&lt;br /&gt;
echo Replace ESC with \\033 in bash.&lt;br /&gt;
echo&lt;br /&gt;
echo &amp;quot;Background | Foreground colors&amp;quot;&lt;br /&gt;
echo &amp;quot;---------------------------------------------------------------------&amp;quot;&lt;br /&gt;
for((bg=40;bg&amp;lt;=47;bg++)); do&lt;br /&gt;
	for((bold=0;bold&amp;lt;=1;bold++)) do&lt;br /&gt;
		echo -en &amp;quot;\033[0m&amp;quot;&amp;quot; ESC[${bg}m   | &amp;quot;&lt;br /&gt;
		for((fg=30;fg&amp;lt;=37;fg++)); do&lt;br /&gt;
			if [ $bold == &amp;quot;0&amp;quot; ]; then&lt;br /&gt;
				echo -en &amp;quot;\033[${bg}m\033[${fg}m [${fg}m  &amp;quot;&lt;br /&gt;
			else&lt;br /&gt;
				echo -en &amp;quot;\033[${bg}m\033[1;${fg}m [1;${fg}m&amp;quot;&lt;br /&gt;
			fi&lt;br /&gt;
		done&lt;br /&gt;
		echo -e &amp;quot;\033[0m&amp;quot;&lt;br /&gt;
	done&lt;br /&gt;
	echo &amp;quot;--------------------------------------------------------------------- &amp;quot;&lt;br /&gt;
done&lt;br /&gt;
&lt;br /&gt;
echo&lt;br /&gt;
echo&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Python version: (modified by me)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
# prints a color table of 8bg * 8fg * 2 states (regular/bold)&lt;br /&gt;
print&lt;br /&gt;
print &amp;quot;Table for 16-color terminal escape sequences.&amp;quot;&lt;br /&gt;
print &amp;quot;Replace ESC with \\033 in bash.&amp;quot;&lt;br /&gt;
print&lt;br /&gt;
print &amp;quot;Background | Foreground colors&amp;quot;&lt;br /&gt;
print &amp;quot;---------------------------------------------------------------------&amp;quot;&lt;br /&gt;
for bg in range(40, 47+1):&lt;br /&gt;
  for bold in range(0, 1+1):&lt;br /&gt;
                sys.stdout.write(&amp;quot;\033[0m&amp;quot;&amp;quot; ESC[{bg}m   | &amp;quot;.format(bg=bg))&lt;br /&gt;
                for fg in range(30, 37+1):&lt;br /&gt;
                        if bold == 0:&lt;br /&gt;
                                sys.stdout.write(&amp;quot;\033[{bg}m\033[{fg}m [{fg}m  &amp;quot;.format(bg=bg, fg=fg))&lt;br /&gt;
                        else:&lt;br /&gt;
                                sys.stdout.write(&amp;quot;\033[{bg}m\033[1;{fg}m [1;{fg}m&amp;quot;.format(bg=bg, fg=fg))&lt;br /&gt;
                sys.stdout.write(&amp;quot;\033[0m\n&amp;quot;)&lt;br /&gt;
  print &amp;quot;--------------------------------------------------------------------- &amp;quot;&lt;br /&gt;
&lt;br /&gt;
print&lt;br /&gt;
print&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Execute External Application ===&lt;br /&gt;
&lt;br /&gt;
Execute program: (and send output to STDOUT)&lt;br /&gt;
 encoded_wait_code = os.system(&#039;mkdir mydir&#039;)  # output sent to STDOUT&lt;br /&gt;
&lt;br /&gt;
Get output and ugly return code: (STDERR goes to STDOUT)&lt;br /&gt;
 p = os.popen(cmd)&lt;br /&gt;
 print p.readlines()&lt;br /&gt;
 encoded_wait_code = p.close()&lt;br /&gt;
&lt;br /&gt;
Execute other python script&lt;br /&gt;
 import sys&lt;br /&gt;
 sys.argv = [, &#039;my&#039;, &#039;args&#039;, &#039;here&#039;]&lt;br /&gt;
 execfile(&#039;myscript.py&#039;)  # does not support arguments directly&lt;br /&gt;
&lt;br /&gt;
Subprocess:&lt;br /&gt;
* See [[#Subprocess]]&lt;br /&gt;
&lt;br /&gt;
=== Program Layout ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
PackageName/&lt;br /&gt;
    README&lt;br /&gt;
    setup.py&lt;br /&gt;
    bin/&lt;br /&gt;
        script&lt;br /&gt;
    docs/&lt;br /&gt;
    test/  # some include in package_name&lt;br /&gt;
    pacakgename/&lt;br /&gt;
        __init__.py&lt;br /&gt;
        code1.py&lt;br /&gt;
        subpackage/&lt;br /&gt;
            __init__.py&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== __init__.py ===&lt;br /&gt;
&lt;br /&gt;
Purpose: Makes the folder into a package library&lt;br /&gt;
&lt;br /&gt;
NOTE: This file is most commonly blank&lt;br /&gt;
&lt;br /&gt;
Good place to put your package functions.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# ken/__init__.py&lt;br /&gt;
def load():&lt;br /&gt;
  ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import ken&lt;br /&gt;
ken.load()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Can import other modules to then use as package modules:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# ken/__init__.py&lt;br /&gt;
from ken.client import Server&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import ken&lt;br /&gt;
ken.Server()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Good place to put your Exceptions.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class MyException(Exception):&lt;br /&gt;
  &amp;quot;&amp;quot;&amp;quot; My Error Exception &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use the __all__ to specify what gets imported on &#039;from package import *&#039;&lt;br /&gt;
  __all__ = [&#039;func1&#039;, &#039;func2&#039;]&lt;br /&gt;
&lt;br /&gt;
=== Metadata ===&lt;br /&gt;
&lt;br /&gt;
 VERSION = (0, 2, 1)&lt;br /&gt;
or&lt;br /&gt;
 __version__ = &#039;0.2.1&#039;&lt;br /&gt;
&lt;br /&gt;
Also See [[#pydoc]]&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
 __version__ = &#039;1.10&#039;&lt;br /&gt;
 __author__ = &#039;Joshua Roesslein&#039;&lt;br /&gt;
 __license__ = &#039;MIT&#039;&lt;br /&gt;
&lt;br /&gt;
=== setup.py ===&lt;br /&gt;
&lt;br /&gt;
See [[#Distributing Python Modules with Distutils]]&lt;br /&gt;
&lt;br /&gt;
=== Distributing Python Modules with Distutils ===&lt;br /&gt;
&lt;br /&gt;
Distributing Python Modules — http://docs.python.org/distutils/index.html&lt;br /&gt;
&lt;br /&gt;
Uses setup.py for package installation.&lt;br /&gt;
 python setup.py install&lt;br /&gt;
&lt;br /&gt;
==== Simple example ====&lt;br /&gt;
&lt;br /&gt;
To install foo.py:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from distutils.core import setup&lt;br /&gt;
setup(name=&#039;foo&#039;,&lt;br /&gt;
      version=&#039;1.0&#039;,&lt;br /&gt;
      py_modules=[&#039;foo&#039;],&lt;br /&gt;
      )&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Source: http://docs.python.org/distutils/introduction.html&lt;br /&gt;
&lt;br /&gt;
==== klib example ====&lt;br /&gt;
&lt;br /&gt;
klib setup.py:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from distutils.core import setup&lt;br /&gt;
&lt;br /&gt;
setup(name = &amp;quot;klib&amp;quot;,&lt;br /&gt;
    version = &amp;quot;101&amp;quot;,&lt;br /&gt;
    description = &amp;quot;klib library&amp;quot;,&lt;br /&gt;
    url = &amp;quot;http://www.oeey.com/klib&amp;quot;,&lt;br /&gt;
    author = &amp;quot;Kenneth&amp;quot;,&lt;br /&gt;
    author_email = &amp;quot;kenneth@oeey.com&amp;quot;,&lt;br /&gt;
    license = &amp;quot;Kenneth License&amp;quot;,&lt;br /&gt;
    long_description = &amp;quot;&amp;quot;&amp;quot;Really long text here.&amp;quot;&amp;quot;&amp;quot;,&lt;br /&gt;
    platforms = &amp;quot;Any Platform&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
    packages = [&#039;klib&#039;,&#039;klib.messenger&#039;],&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Installed to:&lt;br /&gt;
 /opt/python26/lib/python2.6/site-packages/klib/&lt;br /&gt;
 /opt/python26/lib/python2.6/site-packages/klib-100-py2.6.egg-info&lt;br /&gt;
&lt;br /&gt;
Metadata: (/opt/python26/lib/python2.6/site-packages/klib-101-py2.6.egg-info)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Metadata-Version: 1.0&lt;br /&gt;
Name: klib&lt;br /&gt;
Version: 101&lt;br /&gt;
Summary: klib library&lt;br /&gt;
Home-page: http://www.oeey.com/klib&lt;br /&gt;
Author: Kenneth&lt;br /&gt;
Author-email: kenneth@oeey.com&lt;br /&gt;
License: Kenneth License&lt;br /&gt;
Description: Really long text here.&lt;br /&gt;
Platform: Any platform&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Any fields not included will be marked:&lt;br /&gt;
 Platform: UNKNOWN&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* 2. Writing the Setup Script — Python v2.7.2 documentation - http://docs.python.org/distutils/setupscript.html&lt;br /&gt;
* http://wiki.python.org/moin/Distutils/Tutorial&lt;br /&gt;
&lt;br /&gt;
==== Uninstall Package ====&lt;br /&gt;
&lt;br /&gt;
Collect files during install:&lt;br /&gt;
 python setup.py install --record install-record.txt&lt;br /&gt;
 sudo rm $(cat install-record.txt)&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* installation - python setup.py uninstall - Stack Overflow - http://stackoverflow.com/questions/1550226/python-setup-py-uninstall&lt;br /&gt;
&lt;br /&gt;
=== Distributing Python Modules with Setuptools ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
import setuptools&lt;br /&gt;
&lt;br /&gt;
setuptools.setup(name=&amp;quot;tweepy&amp;quot;,&lt;br /&gt;
      version=&amp;quot;1.10&amp;quot;,&lt;br /&gt;
      description=&amp;quot;Twitter library for python&amp;quot;,&lt;br /&gt;
      license=&amp;quot;MIT&amp;quot;,&lt;br /&gt;
      author=&amp;quot;Joshua Roesslein&amp;quot;,&lt;br /&gt;
      author_email=&amp;quot;tweepy@googlegroups.com&amp;quot;,&lt;br /&gt;
      url=&amp;quot;http://github.com/tweepy/tweepy&amp;quot;,&lt;br /&gt;
      packages = setuptools.find_packages(),&lt;br /&gt;
      keywords= &amp;quot;twitter library&amp;quot;,&lt;br /&gt;
      zip_safe = True)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Decorators ===&lt;br /&gt;
&lt;br /&gt;
Decorators wrap functions&lt;br /&gt;
&lt;br /&gt;
Function Counter: [http://stackoverflow.com/questions/739654/understanding-python-decorators]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def fcount(func):&lt;br /&gt;
    def wrapper(*args, **kw):&lt;br /&gt;
        wrapper.count = wrapper.count + 1&lt;br /&gt;
        return func(*args, **kw)&lt;br /&gt;
    wrapper.count = 0&lt;br /&gt;
    return wrapper&lt;br /&gt;
&lt;br /&gt;
@fcount&lt;br /&gt;
def f(n):&lt;br /&gt;
    return n*n&lt;br /&gt;
&lt;br /&gt;
print &amp;quot;f.count = &amp;quot;, f.count&lt;br /&gt;
print &amp;quot;f(10) = &amp;quot;, f(10)&lt;br /&gt;
print &amp;quot;f.count = &amp;quot;, f.count&lt;br /&gt;
print &amp;quot;f(3) = &amp;quot;, f(3)&lt;br /&gt;
print &amp;quot;f.count = &amp;quot;, f.count&lt;br /&gt;
print &amp;quot;f(12) = &amp;quot;, f(12)&lt;br /&gt;
print &amp;quot;f.count = &amp;quot;, f.count&lt;br /&gt;
print &amp;quot;f(15) = &amp;quot;, f(15)&lt;br /&gt;
print &amp;quot;f.count = &amp;quot;, f.count&lt;br /&gt;
&lt;br /&gt;
# Output:&lt;br /&gt;
# f.count =  0&lt;br /&gt;
# f(10) =  100&lt;br /&gt;
# f.count =  1&lt;br /&gt;
# f(3) =  9&lt;br /&gt;
# f.count =  2&lt;br /&gt;
# f(12) =  144&lt;br /&gt;
# f.count =  3&lt;br /&gt;
# f(15) =  225&lt;br /&gt;
# f.count =  4&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Great reference: Understanding Python decorators - Stack Overflow - http://stackoverflow.com/questions/739654/understanding-python-decorators&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Example 1:&lt;br /&gt;
 @dec1&lt;br /&gt;
 def func(arg1, arg2, ...): pass&lt;br /&gt;
&lt;br /&gt;
 # equivalent to:&lt;br /&gt;
 def func(arg1, arg2, ...): pass&lt;br /&gt;
 func = dec1(func)&lt;br /&gt;
&lt;br /&gt;
Example 2:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
@dec2&lt;br /&gt;
@dec1&lt;br /&gt;
def func(arg1, arg2, ...):&lt;br /&gt;
    pass&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# equivalent to:&lt;br /&gt;
def func(arg1, arg2, ...):&lt;br /&gt;
    pass&lt;br /&gt;
func = dec2(dec1(func))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example 3:&lt;br /&gt;
 @decomaker(argA, argB, ...)&lt;br /&gt;
 def func(arg1, arg2, ...):&lt;br /&gt;
     pass&lt;br /&gt;
&lt;br /&gt;
 # equivalent to:&lt;br /&gt;
 func = decomaker(argA, argB, ...)(func)&lt;br /&gt;
&lt;br /&gt;
 # example:&lt;br /&gt;
 @accepts(int,int)&lt;br /&gt;
 @returns(float)&lt;br /&gt;
 def bar(low,high):&lt;br /&gt;
     pass&lt;br /&gt;
&lt;br /&gt;
Example 4: (overrides and ignores passed in function - bad, unless desired)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def spamrun(fn):&lt;br /&gt;
    def sayspam(*args):&lt;br /&gt;
        print &amp;quot;spam, spam, spam&amp;quot;&lt;br /&gt;
    return sayspam&lt;br /&gt;
&lt;br /&gt;
@spamrun&lt;br /&gt;
def useful(a, b):&lt;br /&gt;
    print a**2 + b**2&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example 5: (Decorator that modifies behavior of undecorated func)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def addspam(fn):&lt;br /&gt;
    def new(*args):&lt;br /&gt;
        print &amp;quot;spam, spam, spam&amp;quot;&lt;br /&gt;
        return fn(*args)&lt;br /&gt;
    return new&lt;br /&gt;
&lt;br /&gt;
@addspam&lt;br /&gt;
def useful(a, b):&lt;br /&gt;
    print a**2 + b**2&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
My Example 1: (print args and continue to function)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def showargs(fn):&lt;br /&gt;
    def doshowargs(*args, **kw):&lt;br /&gt;
        print &amp;quot;Args for:&amp;quot;, fn.__name__, args, kw&lt;br /&gt;
        return fn(*args, **kw)&lt;br /&gt;
    return doshowargs&lt;br /&gt;
&lt;br /&gt;
@showargs&lt;br /&gt;
def useful(a, b):&lt;br /&gt;
    print a**2 + b**2&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Another Example: [http://stackoverflow.com/questions/739654/understanding-python-decorators]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def makebold(fn):&lt;br /&gt;
    def wrapped(*args, **kw):&lt;br /&gt;
        return &amp;quot;&amp;lt;b&amp;gt;&amp;quot; + fn(*args, **kw) + &amp;quot;&amp;lt;/b&amp;gt;&amp;quot;&lt;br /&gt;
    return wrapped&lt;br /&gt;
&lt;br /&gt;
def makeitalic(fn):&lt;br /&gt;
    def wrapped(*args, **kw):&lt;br /&gt;
        return &amp;quot;&amp;lt;i&amp;gt;&amp;quot; + fn(*args, **kw) + &amp;quot;&amp;lt;/i&amp;gt;&amp;quot;&lt;br /&gt;
    return wrapped&lt;br /&gt;
&lt;br /&gt;
@makebold&lt;br /&gt;
@makeitalic&lt;br /&gt;
def hello(msg):&lt;br /&gt;
    return msg&lt;br /&gt;
&lt;br /&gt;
print hello(&amp;quot;hello world&amp;quot;)&lt;br /&gt;
# output: &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;hello world&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* PEP 318 -- Decorators for Functions and Methods - http://www.python.org/dev/peps/pep-0318/&lt;br /&gt;
* Charming Python: Decorators make magic easy - http://www.ibm.com/developerworks/linux/library/l-cpdecor/index.html&lt;br /&gt;
* What are some common uses for Python decorators? - Stack Overflow - http://stackoverflow.com/questions/489720/what-are-some-common-uses-for-python-decorators&lt;br /&gt;
* Understanding Python decorators - Stack Overflow - http://stackoverflow.com/questions/739654/understanding-python-decorators&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
Utah Python July 2013 Meeting - Decorator Examples: [https://www.youtube.com/watch?v=uh9uhzitdvw]&lt;br /&gt;
&lt;br /&gt;
Example of uses:&lt;br /&gt;
* Count function calls&lt;br /&gt;
* Add additional output (debugging)&lt;br /&gt;
* Timing code&lt;br /&gt;
* Thread synchronization (locks)&lt;br /&gt;
* Type checking&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
## Simple wrapping call&lt;br /&gt;
def shout(f):&lt;br /&gt;
    def wrapper(*args):&lt;br /&gt;
        print(&#039;This is before {name}&#039;.format(name=f.__name__))&lt;br /&gt;
        ret = f(*args)&lt;br /&gt;
        print(&#039;This is after {name}&#039;.format(name=f.__name__))&lt;br /&gt;
        return ret&lt;br /&gt;
    wrapper.__name__ = f.__name__&lt;br /&gt;
    return wrapper&lt;br /&gt;
&lt;br /&gt;
@shout&lt;br /&gt;
def echo(text):&lt;br /&gt;
    print(text)&lt;br /&gt;
&lt;br /&gt;
echo(&#039;this is a test&#039;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
## Counting function calls&lt;br /&gt;
def count(f):&lt;br /&gt;
    def wrapper(*args):&lt;br /&gt;
        wrapper.counter += 1&lt;br /&gt;
        print(&amp;quot;Function called {count} times&amp;quot;.format(count=wrapper.counter))&lt;br /&gt;
        return f(*args)&lt;br /&gt;
    wrapper.counter = 0&lt;br /&gt;
    # change wrapper name, or it will just be &#039;wrapper&#039; (for inspection)&lt;br /&gt;
    wrapper.__name__ = f.__name__&lt;br /&gt;
    return wrapper&lt;br /&gt;
&lt;br /&gt;
@count&lt;br /&gt;
def donothing():&lt;br /&gt;
    pass&lt;br /&gt;
&lt;br /&gt;
donothing()&lt;br /&gt;
donothing()&lt;br /&gt;
print(&amp;quot;Function called a total of {count} times&amp;quot;.format(count=donothing.counter))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
## Timing your code&lt;br /&gt;
import time&lt;br /&gt;
&lt;br /&gt;
def timer(f):&lt;br /&gt;
    def wrapper(*arg):&lt;br /&gt;
        t = time.time()&lt;br /&gt;
        ret = f(*arg)&lt;br /&gt;
        print(&amp;quot;Took {elapsedtime} seconds&amp;quot;.format(elapsedtime=time.time()-t))&lt;br /&gt;
        return ret&lt;br /&gt;
    return wrapper&lt;br /&gt;
&lt;br /&gt;
@timer&lt;br /&gt;
def fact(n):&lt;br /&gt;
    prod = 1&lt;br /&gt;
    while n &amp;gt; 0:&lt;br /&gt;
        prod *= n&lt;br /&gt;
        n -= 1&lt;br /&gt;
    return prod&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
total = fact(10000)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
## Synchronization&lt;br /&gt;
import threading&lt;br /&gt;
&lt;br /&gt;
def synchronized(lock):&lt;br /&gt;
    def wrap(f):&lt;br /&gt;
        def wrapper(*args, **kwargs):&lt;br /&gt;
            lock.acquire()&lt;br /&gt;
            try:&lt;br /&gt;
                return f(*args, **kwargs)&lt;br /&gt;
            finally:&lt;br /&gt;
                lock.release()&lt;br /&gt;
        return wrapper&lt;br /&gt;
    return wrap&lt;br /&gt;
&lt;br /&gt;
mylock = threading.Lock()&lt;br /&gt;
&lt;br /&gt;
@synchronized(mylock)&lt;br /&gt;
def myfunc():&lt;br /&gt;
    pass&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
## Type checking&lt;br /&gt;
def myMethod(ID, name):&lt;br /&gt;
    &#039;&#039;&#039; Old way &#039;&#039;&#039;&lt;br /&gt;
    if not (isinstance(ID, &#039;uint&#039;) and isinstance(name, &#039;utf8string&#039;)):&lt;br /&gt;
        raise Exception()&lt;br /&gt;
&lt;br /&gt;
def accepts(*typeargs):&lt;br /&gt;
    &#039;&#039;&#039; Decorator way &#039;&#039;&#039;&lt;br /&gt;
    def wrap(f):&lt;br /&gt;
        def wrapper(*args):&lt;br /&gt;
            for a, t in zip(args, typeargs):&lt;br /&gt;
                if not isinstance(a, t):&lt;br /&gt;
                    raise Exception(&#039;{a} not of type {t}&#039;.format(a=a, t=t))&lt;br /&gt;
            return f(*args)&lt;br /&gt;
        return wrapper&lt;br /&gt;
    return wrap&lt;br /&gt;
&lt;br /&gt;
@accepts(int)&lt;br /&gt;
def add1(n):&lt;br /&gt;
    return n + 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
## Memoize&lt;br /&gt;
def memoize(f):&lt;br /&gt;
    def wrapper(*args):&lt;br /&gt;
        if not wrapper.ret:&lt;br /&gt;
            wrapper.ret = f(*args)&lt;br /&gt;
        return wrapper.ret&lt;br /&gt;
    wrapper.ret = False&lt;br /&gt;
    wrapper.__name__ = f.__name__&lt;br /&gt;
    return wrapper&lt;br /&gt;
&lt;br /&gt;
import time&lt;br /&gt;
&lt;br /&gt;
@memoize&lt;br /&gt;
def sumto10():&lt;br /&gt;
    count = 0&lt;br /&gt;
    sum = 0&lt;br /&gt;
    while count &amp;lt; 10:&lt;br /&gt;
        sum += count&lt;br /&gt;
        time.sleep(1)&lt;br /&gt;
        count += 1&lt;br /&gt;
    return sum&lt;br /&gt;
&lt;br /&gt;
# first time will count slow&lt;br /&gt;
print sumto10()&lt;br /&gt;
# second time will return cached value instantly&lt;br /&gt;
print sumto10()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Memoize: &amp;quot;Caches a function&#039;s return value each time it is called. If called later with the same arguments, the cached value is returned (not reevaluated)&amp;quot; [http://wiki.python.org/moin/PythonDecoratorLibrary#Memoize]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
## Nested decorators&lt;br /&gt;
import time&lt;br /&gt;
@shout&lt;br /&gt;
@memoize&lt;br /&gt;
def test1():&lt;br /&gt;
  print &amp;quot;calculating&amp;quot;&lt;br /&gt;
  time.sleep(3)&lt;br /&gt;
  return 100&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Order is important!  For tested decorators the execution order is from the top to the bottom.  If you reverse @shout and @memoize, the @shout will not run because of the way @memoize was written.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
## registry&lt;br /&gt;
registry = []&lt;br /&gt;
# can also decorate decorators:&lt;br /&gt;
@shout&lt;br /&gt;
def registry(f):&lt;br /&gt;
    registry.append(f)&lt;br /&gt;
    return f&lt;br /&gt;
&lt;br /&gt;
@register&lt;br /&gt;
def test2():&lt;br /&gt;
    pass&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Decorator is just a function that returns a function.&lt;br /&gt;
&lt;br /&gt;
Can use functools to automatically update decorator wrappers with __name__, etc [http://docs.python.org/2/library/functools.html]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
## Auto syntax sygar the wrapper for you&lt;br /&gt;
import functools&lt;br /&gt;
def my_decorator(f):&lt;br /&gt;
    @functools.wraps(f)&lt;br /&gt;
    def wrapper(*args, **kwds):&lt;br /&gt;
        print &#039;Calling decorated function&#039;&lt;br /&gt;
        return f(*args, **kwds)&lt;br /&gt;
    return wrapper&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Class Method Decorators ===&lt;br /&gt;
&lt;br /&gt;
Static methods: [http://docs.python.org/library/functions.html#staticmethod]&lt;br /&gt;
: Similar to C++ and Java static methods&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class C:&lt;br /&gt;
  @staticmethod&lt;br /&gt;
  def say(msg):&lt;br /&gt;
    print(msg)&lt;br /&gt;
&lt;br /&gt;
C.say(&#039;hi&#039;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Class method: [http://docs.python.org/library/functions.html#classmethod]&lt;br /&gt;
: A class method receives the class as implicit first argument, just like an instance method receives the instance.&lt;br /&gt;
: Class methods are different than C++ or Java static methods. If you want those, see staticmethod() in this section.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    @classmethod&lt;br /&gt;
    def setup_parser(cls, parser):&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See also [[#Class Properties]]&lt;br /&gt;
&lt;br /&gt;
=== Class Properties ===&lt;br /&gt;
&lt;br /&gt;
Properties: (not using decorators)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class C(object):&lt;br /&gt;
    def __init__(self):&lt;br /&gt;
        self._x = None&lt;br /&gt;
    def getx(self):&lt;br /&gt;
        print(&amp;quot;get x&amp;quot;)&lt;br /&gt;
        return self._x&lt;br /&gt;
    def setx(self, value):&lt;br /&gt;
        print(&amp;quot;set x&amp;quot;)&lt;br /&gt;
        self._x = value&lt;br /&gt;
    def delx(self):&lt;br /&gt;
        print(&amp;quot;del x&amp;quot;)&lt;br /&gt;
        del self._x&lt;br /&gt;
    x = property(getx, setx, delx, &amp;quot;I&#039;m the &#039;x&#039; property.&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#usage&lt;br /&gt;
c = C()&lt;br /&gt;
c.x = 5&lt;br /&gt;
print(c.x)&lt;br /&gt;
del(c.x)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Getter and Setter Property Decorators: [http://docs.python.org/library/functions.html#property]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class C(object):    # make sure to inherit from object for these properties to work!&lt;br /&gt;
    def __init__(self):&lt;br /&gt;
        self._x = None&lt;br /&gt;
    &lt;br /&gt;
    @property&lt;br /&gt;
    def x(self):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;I&#039;m the &#039;x&#039; property.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        print(&amp;quot;get x&amp;quot;)&lt;br /&gt;
        return self._x&lt;br /&gt;
    &lt;br /&gt;
    @x.setter   # python &amp;gt;= 2.6&lt;br /&gt;
    def x(self, value):&lt;br /&gt;
        print(&amp;quot;set x&amp;quot;)&lt;br /&gt;
        self._x = value&lt;br /&gt;
    &lt;br /&gt;
    @x.deleter  # python &amp;gt;= 2.6&lt;br /&gt;
    def x(self):&lt;br /&gt;
        print(&amp;quot;del x&amp;quot;)&lt;br /&gt;
        del self._x&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#usage&lt;br /&gt;
c = C()&lt;br /&gt;
c.x = 5&lt;br /&gt;
print(c.x)&lt;br /&gt;
del(c.x)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: If you don&#039;t add the @x.setter, the property will be read only, and will throw a &amp;quot;AttributeError: can&#039;t set attribute&amp;quot; if attempted to be set.&lt;br /&gt;
&lt;br /&gt;
Using x.getter example: [http://wiki.python.org/moin/AlternativeDescriptionOfProperty]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Cls(object):&lt;br /&gt;
    def __init__(self):&lt;br /&gt;
        self._x = 100&lt;br /&gt;
&lt;br /&gt;
    x = property()&lt;br /&gt;
&lt;br /&gt;
    @x.getter&lt;br /&gt;
    def x(self):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;I&#039;m the &#039;x&#039; property.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        return self._x&lt;br /&gt;
&lt;br /&gt;
    @x.setter&lt;br /&gt;
    def x(self, value):&lt;br /&gt;
        self._x = value&lt;br /&gt;
&lt;br /&gt;
    @x.deleter&lt;br /&gt;
    def x(self):&lt;br /&gt;
        del self._x&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Custom Decorators ===&lt;br /&gt;
&lt;br /&gt;
decorator&lt;br /&gt;
 @dec1&lt;br /&gt;
 def func(arg1, arg2, ...): pass&lt;br /&gt;
&lt;br /&gt;
equivalent to:&lt;br /&gt;
 def func(arg1, arg2, ...): pass&lt;br /&gt;
 func = dec1(func)&lt;br /&gt;
&lt;br /&gt;
Basic layout (names are arbitrary):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def my_decorator(function_name):&lt;br /&gt;
  # update wrapper.__doc__ and .func_name&lt;br /&gt;
  # or @functools.wraps(my_wrapper)&lt;br /&gt;
  def mywrapper(*args, **kw):&lt;br /&gt;
    # do something before&lt;br /&gt;
    result = function_name(*args, **kw)&lt;br /&gt;
    # do something after&lt;br /&gt;
    return result&lt;br /&gt;
  return my_wrapper&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def limit(length):&lt;br /&gt;
  def decorator(function):&lt;br /&gt;
    def wrapper(*args, **kw):&lt;br /&gt;
      result = function(*args, **kw)&lt;br /&gt;
      result = result[:length]&lt;br /&gt;
      return result&lt;br /&gt;
    return wrapper&lt;br /&gt;
  return decorator&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
@limit(3)&lt;br /&gt;
def echo(foo):  return foo&lt;br /&gt;
&lt;br /&gt;
echo(&#039;123456&#039;)  # &#039;123&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== assert ===&lt;br /&gt;
&lt;br /&gt;
 assert True&lt;br /&gt;
 assert False  # exception&lt;br /&gt;
 assert 1 == 1&lt;br /&gt;
 assert 1 == 2, &amp;quot;some message&amp;quot;  # AssertionError: some message&lt;br /&gt;
&lt;br /&gt;
=== Snake Case ===&lt;br /&gt;
&lt;br /&gt;
Convert Camel Case to Snake Case: [http://stackoverflow.com/questions/1175208/elegant-python-function-to-convert-camelcase-to-snake-case]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def snake_case(name):&lt;br /&gt;
    s1 = re.sub(&#039;(.)([A-Z][a-z]+)&#039;, r&#039;\1_\2&#039;, name)&lt;br /&gt;
    return re.sub(&#039;([a-z0-9])([A-Z])&#039;, r&#039;\1_\2&#039;, s1).lower()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; convert(&#039;CamelCase&#039;)&lt;br /&gt;
&#039;camel_case&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Camel Case ===&lt;br /&gt;
&lt;br /&gt;
Camel Case: [http://stackoverflow.com/questions/8347048/camelcase-every-string-any-standard-library]&lt;br /&gt;
&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; &#039;&#039;.join(x for x in &#039;make IT camel CaSe&#039;.title() if not x.isspace())&lt;br /&gt;
 &#039;MakeItCamelCase&#039;&lt;br /&gt;
&lt;br /&gt;
To titleize a sentence:&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; &amp;quot;this is a test&amp;quot;.title()&lt;br /&gt;
 &amp;quot;This Is A Test&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Lambda ===&lt;br /&gt;
&lt;br /&gt;
Simple functions&lt;br /&gt;
 mul = lambda a, b: a * b&lt;br /&gt;
&lt;br /&gt;
 # equivalent to:&lt;br /&gt;
 def mul(a, b):&lt;br /&gt;
   return a * b&lt;br /&gt;
&lt;br /&gt;
Sort usage:&lt;br /&gt;
 data = [dict(number=x) for x in &#039;036149&#039;]&lt;br /&gt;
 data.sort(key=lambda x: float(x[&#039;number&#039;]))&lt;br /&gt;
&lt;br /&gt;
Compare usage:&lt;br /&gt;
 data = [dict(number=x) for x in &#039;036149&#039;]&lt;br /&gt;
 data.sort(cmp=lambda x,y: cmp(x[&#039;number&#039;], y[&#039;number&#039;]))&lt;br /&gt;
&lt;br /&gt;
Boolean:&lt;br /&gt;
 lambda x: x % 3 == 0&lt;br /&gt;
&lt;br /&gt;
Multiple parameter:&lt;br /&gt;
 lambda x, y: x + y&lt;br /&gt;
&lt;br /&gt;
Call another function:&lt;br /&gt;
 lambda word: len(word)&lt;br /&gt;
&lt;br /&gt;
Strings:&lt;br /&gt;
 lambda line: line.split()[2]&lt;br /&gt;
&lt;br /&gt;
Embedded:&lt;br /&gt;
 def transform(n):&lt;br /&gt;
    return lambda x: x + n&lt;br /&gt;
&lt;br /&gt;
No parameters:&lt;br /&gt;
 lambda: 1&lt;br /&gt;
&lt;br /&gt;
Default parameters:&lt;br /&gt;
 lambda x=1: x+1&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* Python: Lambda Functions - http://www.secnetix.de/olli/Python/lambda_functions.hawk&lt;br /&gt;
&lt;br /&gt;
=== Map ===&lt;br /&gt;
&lt;br /&gt;
Apply a function to items of a sequence:&lt;br /&gt;
 map(str, range(3))   # [&#039;0&#039;, &#039;1&#039;, &#039;2&#039;]&lt;br /&gt;
&lt;br /&gt;
Note: list comprehensions can replace map and filter&lt;br /&gt;
&lt;br /&gt;
=== Reduce ===&lt;br /&gt;
&lt;br /&gt;
Apply a function to pairs of the sequence:&lt;br /&gt;
 import operator&lt;br /&gt;
 reduce(operator.mul, [1,2,3,4])   # 24   - ((1*2)*3)*4)&lt;br /&gt;
&lt;br /&gt;
Note: sum or for loop can replace reduce&lt;br /&gt;
&lt;br /&gt;
=== Filter ===&lt;br /&gt;
&lt;br /&gt;
Return a sequence of items for which function(item) is True&lt;br /&gt;
 filter(lambda x: x &amp;gt;= 0, [0, -1, 3])  # [0, 3]&lt;br /&gt;
&lt;br /&gt;
Note: list comprehensions can replace map and filter&lt;br /&gt;
&lt;br /&gt;
Find matching items in two lists:&lt;br /&gt;
 a = [&#039;a&#039;,&#039;b&#039;,&#039;c&#039;]&lt;br /&gt;
 b = [&#039;c&#039;,&#039;d&#039;]&lt;br /&gt;
 filter(lambda x: x in a, b)  # returns only &#039;c&#039; as it is in both lists&lt;br /&gt;
&lt;br /&gt;
=== List comprehension ===&lt;br /&gt;
&lt;br /&gt;
Nothing more than Syntactic Sugar&lt;br /&gt;
&lt;br /&gt;
5. Data Structures — Python v2.7.5 documentation - http://docs.python.org/2/tutorial/datastructures.html#list-comprehensions&lt;br /&gt;
: &amp;quot;List comprehensions provide a concise way to create lists.&amp;quot;&lt;br /&gt;
: &amp;quot;A list comprehension consists of &#039;&#039;&#039;brackets&#039;&#039;&#039; containing an &#039;&#039;&#039;expression&#039;&#039;&#039; followed by a &#039;&#039;&#039;for clause&#039;&#039;&#039;, then &#039;&#039;&#039;zero or more for or if clauses&#039;&#039;&#039;. &amp;quot;&lt;br /&gt;
&lt;br /&gt;
Remove newlines from each item in a list:&lt;br /&gt;
 mylist = [x.strip() for x in mylist]&lt;br /&gt;
&lt;br /&gt;
Simple:&lt;br /&gt;
 doubled = [x*2 for x in mylist]&lt;br /&gt;
 squares = [x**2 for x in range(10)]&lt;br /&gt;
&lt;br /&gt;
If:&lt;br /&gt;
 [ 2*x for x in range(1,10) if x &amp;gt;= 5 ]&lt;br /&gt;
&lt;br /&gt;
Complex:&lt;br /&gt;
 [(x, y) for x in [1,2,3] for y in [3,1,4] if x != y]&lt;br /&gt;
&lt;br /&gt;
Expanding PI:&lt;br /&gt;
 [str(round(pi, i)) for i in range(1, 6)]&lt;br /&gt;
&lt;br /&gt;
Return list of words&lt;br /&gt;
 my_list = [current_word.lower() for current_word in words]&lt;br /&gt;
&lt;br /&gt;
Utah Python July 2013 Meeting: (http://basepi.net)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Iterative&lt;br /&gt;
squares = []&lt;br /&gt;
for x in range(10):&lt;br /&gt;
    squares.append(x**2)&lt;br /&gt;
# [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]&lt;br /&gt;
&lt;br /&gt;
## Functional&lt;br /&gt;
squares = map(lambda x: x**2, range(10))&lt;br /&gt;
&lt;br /&gt;
## List comprehension&lt;br /&gt;
squares = [x**2 for x in range(10)]&lt;br /&gt;
even_squares = [x**2 for x in range(10) if x%2 == 0]&lt;br /&gt;
&lt;br /&gt;
# get hash of strings in list:&lt;br /&gt;
import sha&lt;br /&gt;
strings = [&#039;Python is cool!&#039;, &#039;I love python&#039;]&lt;br /&gt;
hashes = [sha.sha(x).digest() for x in strings]&lt;br /&gt;
&lt;br /&gt;
# flatten matrix:&lt;br /&gt;
matrix = [[1, 2, 3], [4, 5, 6]]&lt;br /&gt;
[x for row in matrix for x in row]&lt;br /&gt;
# [1, 2, 3, 4, 5, 6]&lt;br /&gt;
&lt;br /&gt;
# build matrix:&lt;br /&gt;
[(x,y) for x in range(10) for y in range(10)]&lt;br /&gt;
# matrix of not both odd and not both even&lt;br /&gt;
[(x,y) for x in range(10) for y in range(10) if x%2 != y%2]&lt;br /&gt;
&lt;br /&gt;
# suck lines of files into list, ignoring commented lines&lt;br /&gt;
[line.strip().split(&amp;quot;\t&amp;quot;) for line in open(&amp;quot;my_file.tab&amp;quot;)&lt;br /&gt;
    if not line.startswith(&#039;#&#039;)]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* 5.1.4. List Comprehensions - Data Structures — Python v2.7.2 documentation - http://docs.python.org/tutorial/datastructures.html#list-comprehensions&lt;br /&gt;
* Utah Python July 2013 Meeting - YouTube - https://www.youtube.com/watch?v=uh9uhzitdvw [http://basepi.net]&lt;br /&gt;
&lt;br /&gt;
=== [http://docs.python.org/reference/expressions#calls Mass Parameter Passing] ===&lt;br /&gt;
&lt;br /&gt;
Using: *args and **kw&lt;br /&gt;
* *args a tuple of remaining unnamed parameters&lt;br /&gt;
* **kw a dictionary of remaining named parameters&lt;br /&gt;
&lt;br /&gt;
 def param_func(a, b=&#039;b&#039;, *args, **kw):&lt;br /&gt;
   print( [a, b, args, kw] )&lt;br /&gt;
&lt;br /&gt;
WARNING: If not careful, this can result in this error: &amp;quot;TypeError: param_func() got multiple values for keyword argument &#039;myvar&#039;&amp;quot;.  Might be better to just use:&lt;br /&gt;
&lt;br /&gt;
 def param_func(*args, **kw):&lt;br /&gt;
   print( [args, kw] )&lt;br /&gt;
&lt;br /&gt;
 param_func(1, 2, 3, 4, 5)  # [1, 2, (3, 4, 5), {}]&lt;br /&gt;
 param_func(1, 2, 3, 4, 5, joe=&#039;test&#039;)  # [1, 2, (3, 4, 5), {&#039;joe&#039;: &#039;test&#039;}]&lt;br /&gt;
 mylist = (&amp;quot;a&amp;quot;, &amp;quot;c&amp;quot;, &amp;quot;g&amp;quot;, &amp;quot;h&amp;quot;, 5)&lt;br /&gt;
 param_func(mylist)  # [(&#039;a&#039;, &#039;c&#039;, &#039;g&#039;, &#039;h&#039;, 5), &#039;b&#039;, (), {}]&lt;br /&gt;
 param_func(*mylist)  # [&#039;a&#039;, &#039;c&#039;, (&#039;g&#039;, &#039;h&#039;, 5), {}]  *tricky*&lt;br /&gt;
 Note: *mydict will strip out just keys and treat like list&lt;br /&gt;
 Note: **mydict will treat like named parameters&lt;br /&gt;
&lt;br /&gt;
 def mywrapper(*args, **kw):&lt;br /&gt;
   # do something before&lt;br /&gt;
   result = function_name(*args, **kw)&lt;br /&gt;
&lt;br /&gt;
Passing arbitrary parameters:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def fun2(**kw):&lt;br /&gt;
  print kw  # {&#039;a&#039;: &#039;1&#039;, &#039;b&#039;: &#039;2&#039;, &#039;c&#039;: &#039;3&#039;}&lt;br /&gt;
&lt;br /&gt;
def fun1(c=&#039;3&#039;, **kw):&lt;br /&gt;
 print kw  # {&#039;a&#039;: &#039;1&#039;, &#039;b&#039;: &#039;2&#039;}&lt;br /&gt;
 fun2(c=&#039;3&#039;, **kw)&lt;br /&gt;
&lt;br /&gt;
fun1(a=&#039;1&#039;, b=&#039;2&#039;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [http://www.python.org/dev/peps/pep-0234/ Iteration Protocol] ===&lt;br /&gt;
&lt;br /&gt;
[http://www.python.org/dev/peps/pep-0234/ PEP 234 -- Iterators]&lt;br /&gt;
&lt;br /&gt;
Making a class iterable:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class mycount(object):&lt;br /&gt;
  def __init__(self, max):&lt;br /&gt;
    self.x = 0&lt;br /&gt;
    self.max = max&lt;br /&gt;
  def __iter__(self):  # return object that implements __next__() or next()&lt;br /&gt;
    return self&lt;br /&gt;
  def next(self):&lt;br /&gt;
    if self.x &amp;lt; self.max:&lt;br /&gt;
      self.x += 1&lt;br /&gt;
      return self.x&lt;br /&gt;
    else:&lt;br /&gt;
      self.x = 0&lt;br /&gt;
      raise StopIteration()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 for i in mycount(10): print i     # 1 ... 10&lt;br /&gt;
 print [x for x in mycount(10) ]   # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]&lt;br /&gt;
&lt;br /&gt;
 c = mycount(10)&lt;br /&gt;
 for i in c: print i    # 1 ... 10&lt;br /&gt;
 [ x for x in c ]       # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]&lt;br /&gt;
&lt;br /&gt;
=== Generators ===&lt;br /&gt;
&lt;br /&gt;
Generators are functions that return to their previous state (using &#039;yield&#039;) when iterated over, which can be used in for loops.&lt;br /&gt;
&lt;br /&gt;
==== Yield ====&lt;br /&gt;
&lt;br /&gt;
Improve on Iterators:&lt;br /&gt;
* Infinite data (infinite iterators)&lt;br /&gt;
* Memory-intensive iteration&lt;br /&gt;
* Cooperative Multi-threading&lt;br /&gt;
&lt;br /&gt;
Generators are functions that return to their previous state when iterated over, which can be used in for loops.&lt;br /&gt;
&lt;br /&gt;
Note: Generators throw StopIteration when completed&lt;br /&gt;
&lt;br /&gt;
Note: the &#039;yield&#039; keyword will stash away the state of the function and return the value. (Continuations)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def gen_range(end):&lt;br /&gt;
  cur = 0&lt;br /&gt;
  while cur &amp;lt; end:&lt;br /&gt;
    yield cur&lt;br /&gt;
    # return here next time&lt;br /&gt;
    cur += 1&lt;br /&gt;
&lt;br /&gt;
# for loop iteration&lt;br /&gt;
for i in gen_range(10):  print i&lt;br /&gt;
&lt;br /&gt;
# manual iteration&lt;br /&gt;
my_gen = gen_range(10)&lt;br /&gt;
try:&lt;br /&gt;
  while True:&lt;br /&gt;
    print my_gen.next()&lt;br /&gt;
except StopIteration:&lt;br /&gt;
  pass&lt;br /&gt;
&lt;br /&gt;
# list comprehension&lt;br /&gt;
numbers = [x for x in gen_range(10)]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: one can place an empty &#039;return&#039; in a generator if needed.  A &#039;return&#039; with argument is invalid.&lt;br /&gt;
&lt;br /&gt;
Making a class generate:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class mycount(object):&lt;br /&gt;
  def __init__(self, max):&lt;br /&gt;
    self.max = max&lt;br /&gt;
  def __iter__(self):&lt;br /&gt;
    return self.next()      # change here&lt;br /&gt;
  def next(self):           # change here&lt;br /&gt;
    x = 0&lt;br /&gt;
    while x &amp;lt; self.max:&lt;br /&gt;
      x += 1&lt;br /&gt;
      yield x&lt;br /&gt;
&lt;br /&gt;
for i in mycount(10): print i     # 1 ... 10&lt;br /&gt;
print [x for x in mycount(10) ]   # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]&lt;br /&gt;
&lt;br /&gt;
c = mycount(10)&lt;br /&gt;
for i in c: print i    # 1 ... 10&lt;br /&gt;
[ x for x in c ]       # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]&lt;br /&gt;
&lt;br /&gt;
itr = mycount(10).next()&lt;br /&gt;
itr.next()  # 1&lt;br /&gt;
itr.next()  # 2  - eventually throws StopIteration exception&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Utah Python July 2013 Meeting: [https://www.youtube.com/watch?v=uh9uhzitdvw] [http://basepi.net]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
* Iterators are used to traverse a list&lt;br /&gt;
* Generators are more powerful Iterators&lt;br /&gt;
&lt;br /&gt;
# simple &#039;n&#039; number in functional form&lt;br /&gt;
def firstn(n):&lt;br /&gt;
    num = 0&lt;br /&gt;
    nums = []&lt;br /&gt;
    while num &amp;lt; n:&lt;br /&gt;
        nums.append(num)&lt;br /&gt;
        num += 1&lt;br /&gt;
    return nums&lt;br /&gt;
&lt;br /&gt;
# simple &#039;n&#039; number in generator form&lt;br /&gt;
def firstn(n):&lt;br /&gt;
    num = 0&lt;br /&gt;
    while num &amp;lt; n:&lt;br /&gt;
        yield num&lt;br /&gt;
        num += 1&lt;br /&gt;
&lt;br /&gt;
-&lt;br /&gt;
&lt;br /&gt;
# Infinite list generator&lt;br /&gt;
def counter():&lt;br /&gt;
    num = 0&lt;br /&gt;
    while True:&lt;br /&gt;
        yield num&lt;br /&gt;
        num += 1&lt;br /&gt;
&lt;br /&gt;
# Fibbonacci generator&lt;br /&gt;
def fib():&lt;br /&gt;
    num1 = 0&lt;br /&gt;
    num2 = 1&lt;br /&gt;
    yield num1&lt;br /&gt;
    while True:&lt;br /&gt;
        num1, num2 = num2, num1 + num2&lt;br /&gt;
        yield num1&lt;br /&gt;
&lt;br /&gt;
# Fibbonacci generator 2&lt;br /&gt;
def fib(n):&lt;br /&gt;
    num1 = 0&lt;br /&gt;
    num2 = 1&lt;br /&gt;
    count = 0&lt;br /&gt;
    yield num1&lt;br /&gt;
    while count &amp;lt; n:&lt;br /&gt;
        count += 1&lt;br /&gt;
        num1, num2 = num2, num1 + num2&lt;br /&gt;
        yield num1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Utah Python July 2013 Meeting: [https://www.youtube.com/watch?v=uh9uhzitdvw] [http://basepi.net]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
## Cooperative Multi-Threading:&lt;br /&gt;
# Cooperative multithreading relies on the threads themselves to relinquish control once they are at a stopping point.&lt;br /&gt;
&lt;br /&gt;
def mythread(name):&lt;br /&gt;
    print(&#039;Starting Thread: {name}...&#039;.format(name=name))&lt;br /&gt;
    counter = 10&lt;br /&gt;
    while counter &amp;gt; 0:&lt;br /&gt;
        print(&#039;Thread: {name} doing some work!&#039;.format(name=name))&lt;br /&gt;
        counter -= 1&lt;br /&gt;
        yield&lt;br /&gt;
&lt;br /&gt;
thread1 = mythread(&#039;Alice&#039;)&lt;br /&gt;
thread2 = mythread(&#039;Bob&#039;)&lt;br /&gt;
thread3 = mythread(&#039;Trudy&#039;)&lt;br /&gt;
&lt;br /&gt;
try:&lt;br /&gt;
    while True:&lt;br /&gt;
        thread1.next()&lt;br /&gt;
        thread2.next()&lt;br /&gt;
        thread3.next()&lt;br /&gt;
except StopIteration:&lt;br /&gt;
    pass&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* Utah Python July 2013 Meeting: [https://www.youtube.com/watch?v=uh9uhzitdvw] [http://basepi.net]&lt;br /&gt;
** http://files.basepi.net/talks/pyarmory.zip&lt;br /&gt;
&lt;br /&gt;
=== dunder methods ===&lt;br /&gt;
&lt;br /&gt;
Some dunder (double under) methods determine what will happen when + (__add__) or other similar numerical symbols used.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class str_add(object):&lt;br /&gt;
    def __init__(self, name):&lt;br /&gt;
        self.name = name&lt;br /&gt;
    def __add__(self, other):&lt;br /&gt;
        self.name += other.name&lt;br /&gt;
        return self&lt;br /&gt;
        # note: only need to return self if you want to go beyond &#039;a + b&#039;&lt;br /&gt;
&lt;br /&gt;
a = str_add(&#039;a_&#039;)&lt;br /&gt;
b = str_add(&#039;b_&#039;)&lt;br /&gt;
c = str_add(&#039;c_&#039;)&lt;br /&gt;
d = a + b + c&lt;br /&gt;
print(a.name)  # a_b_c_&lt;br /&gt;
print(b.name)  # b_&lt;br /&gt;
print(c.name)  # c_&lt;br /&gt;
print(d.name)  # a_b_c_&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Other common methods to override:&lt;br /&gt;
* __add__ for +&lt;br /&gt;
* __sub__ for -&lt;br /&gt;
* __mul__ for *&lt;br /&gt;
* __div__ for /&lt;br /&gt;
* __mod__ for %&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* Emulating numeric types - http://docs.python.org/2/reference/datamodel.html#emulating-numeric-types&lt;br /&gt;
&lt;br /&gt;
=== [http://docs.python.org/library/doctest.html doctest] ===&lt;br /&gt;
&lt;br /&gt;
test.py:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
This is the &amp;quot;example&amp;quot; module.&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; double(5)&lt;br /&gt;
10&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
def double(n):&lt;br /&gt;
  &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  This is double function&lt;br /&gt;
&lt;br /&gt;
  &amp;gt;&amp;gt;&amp;gt; double(3)&lt;br /&gt;
  6&lt;br /&gt;
  &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  return n * 2&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
    import doctest&lt;br /&gt;
    doctest.testmod()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== unittest ===&lt;br /&gt;
&lt;br /&gt;
 unittest.TestCase&lt;br /&gt;
&lt;br /&gt;
Here is a short script to test three functions from the random module:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import random&lt;br /&gt;
import unittest&lt;br /&gt;
&lt;br /&gt;
class TestSequenceFunctions(unittest.TestCase):&lt;br /&gt;
&lt;br /&gt;
    def setUp(self):&lt;br /&gt;
        self.seq = range(10)&lt;br /&gt;
&lt;br /&gt;
    def test_shuffle(self):&lt;br /&gt;
        # make sure the shuffled sequence does not lose any elements&lt;br /&gt;
        random.shuffle(self.seq)&lt;br /&gt;
        self.seq.sort()&lt;br /&gt;
        self.assertEqual(self.seq, range(10))&lt;br /&gt;
&lt;br /&gt;
        # should raise an exception for an immutable sequence&lt;br /&gt;
        self.assertRaises(TypeError, random.shuffle, (1,2,3))&lt;br /&gt;
&lt;br /&gt;
    def test_choice(self):&lt;br /&gt;
        element = random.choice(self.seq)&lt;br /&gt;
        self.assertTrue(element in self.seq)&lt;br /&gt;
&lt;br /&gt;
    def test_sample(self):&lt;br /&gt;
        with self.assertRaises(ValueError):&lt;br /&gt;
            random.sample(self.seq, 20)&lt;br /&gt;
        for element in random.sample(self.seq, 5):&lt;br /&gt;
            self.assertTrue(element in self.seq)&lt;br /&gt;
&lt;br /&gt;
if __name__ == &#039;__main__&#039;:&lt;br /&gt;
    unittest.main()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The unittest module can be used from the command line to run tests from modules, classes or even individual test methods:&lt;br /&gt;
 python -m unittest test_module1 test_module2&lt;br /&gt;
 python -m unittest test_module.TestClass&lt;br /&gt;
 python -m unittest test_module.TestClass.test_method&lt;br /&gt;
 python -m unittest -v test_module  # verbose&lt;br /&gt;
 python -m unittest -h   # help&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* 25.3. unittest — Unit testing framework — Python v2.7.4 documentation - http://docs.python.org/2/library/unittest.html&lt;br /&gt;
* Python Debugging Tips - Google Drive - https://docs.google.com/presentation/d/130Wl--IzbDh9ymF6KHMu0WrsIwz6k32pav1gFbsw7NI/edit?usp=sharing&lt;br /&gt;
&lt;br /&gt;
=== Internet Access ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Python 3&lt;br /&gt;
from urllib.request import urlopen&lt;br /&gt;
for line in urlopen(&#039;http://tycho.usno.navy.mil/cgi-bin/timer.pl&#039;):&lt;br /&gt;
  line = line.decode(&#039;utf-8&#039;)&lt;br /&gt;
  if &#039;EST&#039; in line or &#039;EDT&#039; in line:  # look for eastern time&lt;br /&gt;
    print(line)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Simple SMTP ===&lt;br /&gt;
&lt;br /&gt;
Requires local STMP server.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import smtplib&lt;br /&gt;
server = smtplib.SMTP(&amp;quot;localhost&amp;quot;)&lt;br /&gt;
server.sendmail(&#039;mrken@demo.oeey.com&#039;, &#039;kenneth@demo.oeey.com&#039;,&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;To: kenneth@demo.oeey.com&lt;br /&gt;
From: mrken@demo.oeey.com&lt;br /&gt;
Subject: This is fun&lt;br /&gt;
&lt;br /&gt;
Beware of the dog.&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;)&lt;br /&gt;
server.quit()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
s = smtplib.SMTP(smtp_server)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
with TLS:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
s = smtplib.SMTP(&amp;quot;smtp.gmail.com&amp;quot;,587)&lt;br /&gt;
s.ehlo()&lt;br /&gt;
s.starttls()&lt;br /&gt;
s.ehlo()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
SSL:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
s = smtplib.SMTP_SSL(&#039;smtp.mail.yahoo.com&#039;, 465)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Data Compress ===&lt;br /&gt;
&lt;br /&gt;
zlib, gzip, bz2, zipfile, tarfile&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import zlib&lt;br /&gt;
s = b&#039;hello world&#039;  # only in python &amp;gt;3&lt;br /&gt;
len(s)&lt;br /&gt;
t = zlib.compress(s)&lt;br /&gt;
zlib.decompress(t)&lt;br /&gt;
zlib.crc32(s)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== gzip ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import gzip&lt;br /&gt;
content = &amp;quot;Lots of content here&amp;quot;&lt;br /&gt;
f = gzip.open(&#039;file.txt.gz&#039;, &#039;wb&#039;)&lt;br /&gt;
f.write(content)&lt;br /&gt;
f.close()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import gzip&lt;br /&gt;
f_in = open(&#039;file.txt&#039;, &#039;rb&#039;)&lt;br /&gt;
f_out = gzip.open(&#039;file.txt.gz&#039;, &#039;wb&#039;)&lt;br /&gt;
f_out.writelines(f_in)&lt;br /&gt;
f_out.close()&lt;br /&gt;
f_in.close()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Performance Timer ===&lt;br /&gt;
&lt;br /&gt;
Time a task repeated 10 times:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from timeit import Timer&lt;br /&gt;
Timer(&#039;t=a; a=b; b=t&#039;, &#039;a=1; b=2&#039;).timeit()&lt;br /&gt;
Timer(&#039;print(&amp;quot;hi&amp;quot;)&#039;).timeit(10)  # repeat 10 times and time&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Simple method:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
start_time = int(time.time())&lt;br /&gt;
... task ...&lt;br /&gt;
compute_time = int(time.time()) - start_time&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Python Version Check ===&lt;br /&gt;
&lt;br /&gt;
Solution:&lt;br /&gt;
&lt;br /&gt;
__init__.py:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Check Python Version:&lt;br /&gt;
import sys&lt;br /&gt;
assert sys.version_info &amp;gt;= (2, 6, 0), &#039;requires Python 2.6 or higher&#039;&lt;br /&gt;
del sys&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
resulting error if not &amp;gt; 2.6:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import nucleon&lt;br /&gt;
Traceback (most recent call last):&lt;br /&gt;
  File &amp;quot;&amp;lt;stdin&amp;gt;&amp;quot;, line 1, in ?&lt;br /&gt;
  File &amp;quot;nucleon/__init__.py&amp;quot;, line 9, in ?&lt;br /&gt;
    assert sys.version_info &amp;gt;= (2, 6, 0), &#039;nucleon requires Python 2.6 or higher&#039;&lt;br /&gt;
AssertionError: nucleon requires Python 2.6 or higher&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Other solutions:&lt;br /&gt;
&lt;br /&gt;
Note: this will throw syntax error on 2.4 due to ternary&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import sys&lt;br /&gt;
if sys.version_info &amp;lt; (2, 4):&lt;br /&gt;
    raise &amp;quot;must use python 2.5 or greater&amp;quot;&lt;br /&gt;
else:&lt;br /&gt;
    # syntax error in 2.4, ok in 2.5&lt;br /&gt;
    x = 1 if True else 2&lt;br /&gt;
    print x&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
maybe solution:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
try:&lt;br /&gt;
  eval(&amp;quot;1 if True else 2&amp;quot;)&lt;br /&gt;
except SyntaxError:&lt;br /&gt;
  # doesn&#039;t have ternary&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; try:&lt;br /&gt;
...     from my_module import twoPointSixCode&lt;br /&gt;
... except Exception: &lt;br /&gt;
...     print &amp;quot;can&#039;t import, probably because your python is too old!&amp;quot;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/env/python&lt;br /&gt;
import sys&lt;br /&gt;
if sys.version_info&amp;lt;(2,6,0):&lt;br /&gt;
  sys.stderr.write(&amp;quot;You need python 2.6 or later to run this script\n&amp;quot;)&lt;br /&gt;
  exit(1)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import sys&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; sys.hexversion  # hex printed as integer&lt;br /&gt;
33817584&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; &#039;%x&#039; % sys.hexversion  # output as hex, not zero fill  2.4.3&lt;br /&gt;
&#039;20403f0&#039;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; sys.hexversion &amp;lt; 0x02060000  # test if version less than 2.6&lt;br /&gt;
True&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; print &amp;quot;0x%08x&amp;quot; % sys.hexversion  # print as hex and zero fill and prepend &#039;0x&#039;&lt;br /&gt;
0x020403f0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import sys&lt;br /&gt;
if sys.hexversion &amp;lt; 0x02060500:&lt;br /&gt;
    print &amp;gt;&amp;gt; sys.stderr, &amp;quot;This script requires python 2.6.5 or higher.&amp;quot;&lt;br /&gt;
    exit(1)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import sys&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; sys.version_info&lt;br /&gt;
(2, 6, 4, &#039;final&#039;, 0)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; if not sys.version_info[:2] == (2, 6):&lt;br /&gt;
...    print &amp;quot;Error, I need python 2.6&amp;quot;&lt;br /&gt;
... else:&lt;br /&gt;
...    from my_module import twoPointSixCode&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* http://stackoverflow.com/questions/446052/python-best-way-to-check-for-python-version-in-program-that-uses-new-language-fe&lt;br /&gt;
* http://stackoverflow.com/questions/1093322/how-do-i-check-what-version-of-python-is-running-my-script&lt;br /&gt;
&lt;br /&gt;
=== [http://docs.python.org/library/struct.html Struct - Binary Data Record Layout] ===&lt;br /&gt;
&lt;br /&gt;
Format Characters:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Format	C Type		Python type 	Standard size&lt;br /&gt;
x	pad byte	no value	  	 &lt;br /&gt;
c	char		str of len 1	1	 &lt;br /&gt;
b	signed char	integer		1&lt;br /&gt;
B	unsigned char	integer 	1&lt;br /&gt;
?	_Bool		bool 		1&lt;br /&gt;
h	short		integer 	2&lt;br /&gt;
H	unsigned short 	integer 	2&lt;br /&gt;
i	int		integer 	4&lt;br /&gt;
I	unsigned int 	integer 	4&lt;br /&gt;
l	long		integer 	4&lt;br /&gt;
L	unsigned long	integer		4&lt;br /&gt;
q	long long	integer		8&lt;br /&gt;
Q	unsigned long long    integer	8&lt;br /&gt;
f	float		float		4&lt;br /&gt;
d	double		float		8&lt;br /&gt;
s	char[]		string&lt;br /&gt;
p	char[]		string&lt;br /&gt;
P	void *		integer&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 H  # two byte unassigned number&lt;br /&gt;
 I  # four byte unassigned number&lt;br /&gt;
 &amp;lt;  # standard size and in little-endian byte order&lt;br /&gt;
&lt;br /&gt;
 import struct&lt;br /&gt;
 data = struct.pack(&#039;&amp;lt;IIIHH&#039;, 1, 2, 3, 4, 5)&lt;br /&gt;
 # data = &#039;\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x04\x00\x05\x00&#039;&lt;br /&gt;
 &lt;br /&gt;
 fields = struct.unpack(&#039;&amp;lt;IIIHH&#039;, data)&lt;br /&gt;
 # fields = (1L, 2L, 3L, 4, 5)&lt;br /&gt;
 # using splice: fields = struct.unpack(&#039;&amp;lt;IIIHH&#039;, data[start:start+16])&lt;br /&gt;
 &lt;br /&gt;
 f1, f2, f3, f4, f5 = fields&lt;br /&gt;
 &lt;br /&gt;
 hex(f1)  # hex a field:&lt;br /&gt;
 #  &#039;0x1L&#039;&lt;br /&gt;
&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; struct.pack(&amp;quot;&amp;lt;5sh&amp;quot;, &amp;quot;helloo&amp;quot;, 11)&lt;br /&gt;
 &#039;hello\x0b\x00&#039;&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; struct.unpack(&amp;quot;&amp;lt;5sh&amp;quot;, &#039;hello\x0b\x00&#039;)&lt;br /&gt;
 (&#039;hello&#039;, 11)&lt;br /&gt;
&lt;br /&gt;
=== pdb interactive debugger ===&lt;br /&gt;
&lt;br /&gt;
 # uncomment the following to use the interactive debugger:&lt;br /&gt;
 # import pdb; pdb.set_trace()&lt;br /&gt;
&lt;br /&gt;
=== [http://docs.python.org/library/telnetlib.html Telnet] ===&lt;br /&gt;
&lt;br /&gt;
create:&lt;br /&gt;
 class telnetlib.Telnet([host[, port[, timeout]]])&lt;br /&gt;
&lt;br /&gt;
Note: The instance is initially not connected by default; the open() method must be used to establish a connection. Alternatively, the host name and optional port number can be passed to the constructor, to, in which case the connection to the server will be established before the constructor returns.&lt;br /&gt;
&lt;br /&gt;
open if not initially done so:&lt;br /&gt;
 Telnet.open(host[, port[, timeout]])&lt;br /&gt;
&lt;br /&gt;
Functions:&lt;br /&gt;
 Telnet.read_until(expected[, timeout])   # Read until a given string, expected, is encountered or until timeout seconds have passed.&lt;br /&gt;
                                          # on timeout return whatever is in queue, possibly empty string&lt;br /&gt;
 Telnet.close()         # close connection&lt;br /&gt;
 Telnet.read_all()      # Read all data until EOF; block until connection closed.&lt;br /&gt;
 Telnet.write(buffer)   # Write a string to the socket, doubling any IAC characters. This can block if the connection is blocked.&lt;br /&gt;
 Telnet.expect(list[, timeout])  # Read until one from a list of a regular expressions matches.&lt;br /&gt;
                        # Return a tuple of three items: the index in the list of matches; the match object; and the text read to match.&lt;br /&gt;
&lt;br /&gt;
Read until end of line:&lt;br /&gt;
 line = tn.read_until(&amp;quot;\n&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import getpass&lt;br /&gt;
import sys&lt;br /&gt;
import telnetlib&lt;br /&gt;
&lt;br /&gt;
HOST = &amp;quot;localhost&amp;quot;&lt;br /&gt;
user = raw_input(&amp;quot;Enter your remote account: &amp;quot;)&lt;br /&gt;
password = getpass.getpass()&lt;br /&gt;
&lt;br /&gt;
tn = telnetlib.Telnet(HOST)&lt;br /&gt;
&lt;br /&gt;
tn.read_until(&amp;quot;login: &amp;quot;)&lt;br /&gt;
tn.write(user + &amp;quot;\n&amp;quot;)&lt;br /&gt;
if password:&lt;br /&gt;
    tn.read_until(&amp;quot;Password: &amp;quot;)&lt;br /&gt;
    tn.write(password + &amp;quot;\n&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
tn.write(&amp;quot;ls\n&amp;quot;)&lt;br /&gt;
tn.write(&amp;quot;exit\n&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
print tn.read_all()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
&lt;br /&gt;
import sys&lt;br /&gt;
import telnetlib&lt;br /&gt;
&lt;br /&gt;
HOST = &amp;quot;216.119.193.252&amp;quot;&lt;br /&gt;
USER = &amp;quot;admin&amp;quot;&lt;br /&gt;
PASS = &amp;quot;@lt12345&amp;quot;&lt;br /&gt;
&lt;br /&gt;
tn = telnetlib.Telnet(HOST)&lt;br /&gt;
&lt;br /&gt;
tn.read_until(&amp;quot;login: &amp;quot;)&lt;br /&gt;
tn.write(USER + &amp;quot;\n&amp;quot;)&lt;br /&gt;
tn.read_until(&amp;quot;Password: &amp;quot;)&lt;br /&gt;
tn.write(PASS + &amp;quot;\n&amp;quot;)&lt;br /&gt;
tn.read_until(&amp;quot;# &amp;quot;)&lt;br /&gt;
&lt;br /&gt;
tn.write(&amp;quot;terminal length 0\n&amp;quot;)&lt;br /&gt;
tn.read_until(&amp;quot;# &amp;quot;)&lt;br /&gt;
&lt;br /&gt;
tn.write(&amp;quot;show running-config\n&amp;quot;)&lt;br /&gt;
configlines = tn.read_until(&amp;quot;# &amp;quot;)&lt;br /&gt;
&lt;br /&gt;
tn.write(&amp;quot;exit\n&amp;quot;)&lt;br /&gt;
tn.read_all()&lt;br /&gt;
&lt;br /&gt;
print(configlines)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== SSH ===&lt;br /&gt;
&lt;br /&gt;
Cheap method:&lt;br /&gt;
 os.system(&#039;ssh user@server command&#039;)&lt;br /&gt;
&lt;br /&gt;
SecureShell - PythonInfo Wiki - http://wiki.python.org/moin/SecureShell&lt;br /&gt;
: There are several ways to use Secure Shell (SSH) in Python&lt;br /&gt;
* pyssh - http://pyssh.sourceforge.net/&lt;br /&gt;
* paramiko - Paramiko is a native Python implementation of SSH. - http://www.lag.net/paramiko/&lt;br /&gt;
* conch - conch is another native implementation of SSH and part of the Twisted Matrix project - http://twistedmatrix.com/projects/conch &lt;br /&gt;
* SSH wrapper - Some tools just wrap around existing ssh/sftp implementations&lt;br /&gt;
** keyphrene - http://www.keyphrene.com/products/org.keyphrene/&lt;br /&gt;
** keyphrene SSH wrapper - http://membres.lycos.fr/fredp/python/pyscp.html&lt;br /&gt;
* Fabric - http://docs.fabfile.org/en/1.4.0/index.html&lt;br /&gt;
* pexpect - Noah.org - http://www.noah.org/wiki/Pexpect&lt;br /&gt;
&lt;br /&gt;
SFTP:&lt;br /&gt;
* SFTP in Python: Really Simple SSH | The best of Zeth - http://zeth.net/post/332/&lt;br /&gt;
&lt;br /&gt;
pexpect:&lt;br /&gt;
 wget http://pexpect.sourceforge.net/pexpect-2.3.tar.gz&lt;br /&gt;
 tar xzf pexpect-2.3.tar.gz&lt;br /&gt;
 cd pexpect-2.3&lt;br /&gt;
 sudo python ./setup.py install&lt;br /&gt;
&lt;br /&gt;
=== SFTP ===&lt;br /&gt;
&lt;br /&gt;
SFTP in Python? (platform independent) - Stack Overflow - http://stackoverflow.com/questions/432385/sftp-in-python-platform-independent&lt;br /&gt;
&lt;br /&gt;
paramiko: ssh2 protocol for python - http://www.lag.net/paramiko/&lt;br /&gt;
&lt;br /&gt;
 pip install paramiko&lt;br /&gt;
&lt;br /&gt;
 mkdir -p ~/.src ; cd ~/.src&lt;br /&gt;
 wget http://www.lag.net/paramiko/download/paramiko-1.7.7.1.zip&lt;br /&gt;
 unzip paramiko-1.7.7.1.zip&lt;br /&gt;
 cd paramiko-1.7.7.1&lt;br /&gt;
 python setup.py install&lt;br /&gt;
&lt;br /&gt;
SFTP Methods:&lt;br /&gt;
* chdir&lt;br /&gt;
* chmod&lt;br /&gt;
* chown&lt;br /&gt;
* close&lt;br /&gt;
* file&lt;br /&gt;
* from_transport&lt;br /&gt;
* get&lt;br /&gt;
* get_channel&lt;br /&gt;
* getcwd&lt;br /&gt;
* listdir&lt;br /&gt;
* listdir_attr&lt;br /&gt;
* logger&lt;br /&gt;
* lstat&lt;br /&gt;
* mkdir&lt;br /&gt;
* normalize&lt;br /&gt;
* open&lt;br /&gt;
* put&lt;br /&gt;
* readlink&lt;br /&gt;
* remove&lt;br /&gt;
* rename&lt;br /&gt;
* request_number&lt;br /&gt;
* rmdir&lt;br /&gt;
* sock&lt;br /&gt;
* stat&lt;br /&gt;
* symlink&lt;br /&gt;
* truncate&lt;br /&gt;
* ultra_debug&lt;br /&gt;
* unlink&lt;br /&gt;
* utime&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import paramiko&lt;br /&gt;
&lt;br /&gt;
host = &amp;quot;THEHOST.com&amp;quot;                    #hard-coded&lt;br /&gt;
port = 22&lt;br /&gt;
transport = paramiko.Transport((host, port))&lt;br /&gt;
&lt;br /&gt;
password = &amp;quot;THEPASSWORD&amp;quot;                #hard-coded&lt;br /&gt;
username = &amp;quot;THEUSERNAME&amp;quot;                #hard-coded&lt;br /&gt;
transport.connect(username = username, password = password)&lt;br /&gt;
&lt;br /&gt;
sftp = paramiko.SFTPClient.from_transport(transport)&lt;br /&gt;
&lt;br /&gt;
import sys&lt;br /&gt;
path = &#039;./THETARGETDIRECTORY/&#039; + sys.argv[1]    #hard-coded&lt;br /&gt;
localpath = sys.argv[1]&lt;br /&gt;
sftp.put(localpath, path)&lt;br /&gt;
&lt;br /&gt;
sftp.close()&lt;br /&gt;
transport.close()&lt;br /&gt;
print &#039;Upload done.&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
VMware Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
&lt;br /&gt;
import paramiko&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
host = &amp;quot;sftp2.engx.vmware.com&amp;quot;&lt;br /&gt;
port = 443&lt;br /&gt;
transport = paramiko.Transport((host, port))&lt;br /&gt;
&lt;br /&gt;
username = &amp;quot;xxxx&amp;quot;&lt;br /&gt;
password = &amp;quot;xxx&amp;quot;&lt;br /&gt;
transport.connect(username = username, password = password)&lt;br /&gt;
&lt;br /&gt;
sftp = paramiko.SFTPClient.from_transport(transport)&lt;br /&gt;
&lt;br /&gt;
print dir(sftp)&lt;br /&gt;
&lt;br /&gt;
print sftp.chdir(&amp;quot;build-uploader&amp;quot;)&lt;br /&gt;
print sftp.listdir()&lt;br /&gt;
&lt;br /&gt;
sftp.close()&lt;br /&gt;
transport.close()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== paramiko ===&lt;br /&gt;
&lt;br /&gt;
See [[Python/paramiko]]&lt;br /&gt;
&lt;br /&gt;
=== [http://docs.python.org/library/getpass.html Get Password] ===&lt;br /&gt;
&lt;br /&gt;
Prompt for password:&lt;br /&gt;
 getpass.getpass(prompt=&#039;Password: &#039;)&lt;br /&gt;
&lt;br /&gt;
 import getpass&lt;br /&gt;
 user = raw_input(&amp;quot;Enter your remote account: &amp;quot;)&lt;br /&gt;
 password = getpass.getpass()&lt;br /&gt;
&lt;br /&gt;
=== [http://docs.python.org/library/configparser.html ini files] ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ini_filename = &#039;my.ini&#039;&lt;br /&gt;
&lt;br /&gt;
import ConfigParser&lt;br /&gt;
parser = ConfigParser.SafeConfigParser()&lt;br /&gt;
parser.read(ini_filename)&lt;br /&gt;
&lt;br /&gt;
sections = parser.sections() # get sections&lt;br /&gt;
for section in sections:&lt;br /&gt;
  print &amp;quot;[&amp;quot; + section + &amp;quot;]&amp;quot;&lt;br /&gt;
  for name, value in parser.items(section):&lt;br /&gt;
    print name + &amp;quot; = &amp;quot; + value&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if parser.has_option(section, option):&lt;br /&gt;
  print( parser.get(section, option) )&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To have the option names not convert to lower case:&lt;br /&gt;
 parser.optionxform = str&lt;br /&gt;
&lt;br /&gt;
Ignore section: [http://stackoverflow.com/questions/2885190/using-pythons-configparser-to-read-a-file-without-section-name]&lt;br /&gt;
 ini_str = &#039;[root]\n&#039; + open(ini_path, &#039;r&#039;).read()&lt;br /&gt;
 ini_fp = StringIO.StringIO(ini_str)&lt;br /&gt;
 config = ConfigParser.RawConfigParser()&lt;br /&gt;
 config.readfp(ini_fp)&lt;br /&gt;
&lt;br /&gt;
Get option:&lt;br /&gt;
 config.has_option(&#039;root&#039;, &#039;some_key&#039;)&lt;br /&gt;
 config.get(&#039;root&#039;, &#039;some_key&#039;)&lt;br /&gt;
&lt;br /&gt;
 config.items(&#039;root&#039;)  # list of Key Value tuples&lt;br /&gt;
&lt;br /&gt;
=== optparse - Option Parser ===&lt;br /&gt;
&lt;br /&gt;
[http://docs.python.org/library/optparse.html - Option Parser&lt;br /&gt;
&lt;br /&gt;
Note: Deprecated since version 2.7: The optparse module is deprecated and will not be developed further; development will continue with the argparse module.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import optparse&lt;br /&gt;
parser = optparse.OptionParser()&lt;br /&gt;
&lt;br /&gt;
parser.add_option(&#039;--name&#039;, default=None)&lt;br /&gt;
&lt;br /&gt;
parser.add_option(&lt;br /&gt;
    &#039;-l&#039;, &#039;--loglevel&#039;,&lt;br /&gt;
    help=&#039;Log Level (default: info)&#039;,&lt;br /&gt;
    default=&amp;quot;info&amp;quot;, action=&#039;store&#039;, type=&#039;string&#039;)&lt;br /&gt;
&lt;br /&gt;
(options, args) = parser.parse_args()&lt;br /&gt;
&lt;br /&gt;
# if no parameters passed show help&lt;br /&gt;
if len(sys.argv) == 1:&lt;br /&gt;
    parser.print_help()&lt;br /&gt;
    sys.exit(1)&lt;br /&gt;
&lt;br /&gt;
# if a stand alone parameter passed, override option&lt;br /&gt;
if args:&lt;br /&gt;
  options.target = args[0]&lt;br /&gt;
&lt;br /&gt;
# show option:&lt;br /&gt;
print(options.loglevel)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: Order is important when listing add_options!&lt;br /&gt;
&lt;br /&gt;
Pretty Description:&lt;br /&gt;
 parser = optparse.OptionParser(description=&amp;quot;Purpose: to do something&amp;quot;)&lt;br /&gt;
 # or&lt;br /&gt;
 parser.description = &amp;quot;Purpose: to do something&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Parse arguments:&lt;br /&gt;
 (options, args) = parser.parse_args()&lt;br /&gt;
Note: If you like, you can pass a custom argument list to parse_args(), but that’s rarely necessary: by default it uses sys.argv[1:].&lt;br /&gt;
&lt;br /&gt;
Change Usage Message:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
usage = &amp;quot;%prog [options]&amp;quot;  # default message&lt;br /&gt;
# Usage: &amp;lt;prog&amp;gt; [options]&amp;quot;  # where &amp;lt;prog&amp;gt; is replaced with the script name&lt;br /&gt;
&lt;br /&gt;
parser = OptionParser(usage=usage)&lt;br /&gt;
# or&lt;br /&gt;
parser.usage = usage  # default message&lt;br /&gt;
# or&lt;br /&gt;
parser.set_usage(usage)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Remove option: (does not remove default value from &#039;options&#039; variable!!! - stupid!)&lt;br /&gt;
 parser.remove_option(&#039;--loglevel&#039;)&lt;br /&gt;
&lt;br /&gt;
Modify an option: (changes are saved to parser automatically, unless in an option group)&lt;br /&gt;
 option = parser.get_option(&#039;--loglevel&#039;)&lt;br /&gt;
 option.help = &#039;something else&#039;&lt;br /&gt;
 option.default = &#039;debug&#039;&lt;br /&gt;
&lt;br /&gt;
 # or&lt;br /&gt;
 parser.remove_option(&amp;quot;--loglevel&amp;quot;)&lt;br /&gt;
 parser.add_option(&amp;quot;--loglevel&amp;quot;, help=&amp;quot;something else&amp;quot;, default=&amp;quot;info&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Modify an option in an option group:&lt;br /&gt;
 opt_group = parser.get_option_group(&amp;quot;--loglevel&amp;quot;)&lt;br /&gt;
 opt_group.remove_option(&amp;quot;--loglevel&amp;quot;)&lt;br /&gt;
 opt_group.add_option(&amp;quot;--loglevel&amp;quot;, help=&amp;quot;something else&amp;quot;, default=&amp;quot;info&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Types: &amp;quot;string&amp;quot;, &amp;quot;int&amp;quot;, &amp;quot;long&amp;quot;, &amp;quot;choice&amp;quot;, &amp;quot;float&amp;quot; and &amp;quot;complex&amp;quot; [http://docs.python.org/library/optparse.html#optparse-standard-option-types]&lt;br /&gt;
Defaults:&lt;br /&gt;
* Default actions is &#039;store&#039;.&lt;br /&gt;
* Default type is &#039;string&#039;.&lt;br /&gt;
* Default dest is the long name of the parameter (or short name if no long name provided)&lt;br /&gt;
* Default value is None&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from optparse import OptionParser&lt;br /&gt;
[...]&lt;br /&gt;
parser = OptionParser()&lt;br /&gt;
&lt;br /&gt;
# string&lt;br /&gt;
parser.add_option(&amp;quot;-f&amp;quot;, &amp;quot;--file&amp;quot;, dest=&amp;quot;filename&amp;quot;,&lt;br /&gt;
                  help=&amp;quot;write report to FILE&amp;quot;, metavar=&amp;quot;FILE&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
# boolean - action is what to do when flag found&lt;br /&gt;
parser.add_option(&amp;quot;-q&amp;quot;, &amp;quot;--quiet&amp;quot;,&lt;br /&gt;
                  action=&amp;quot;store_true&amp;quot;, dest=&amp;quot;verbose&amp;quot;, default=False,&lt;br /&gt;
                  help=&amp;quot;don&#039;t print status messages to stdout&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
# integer&lt;br /&gt;
parser.add_option(&lt;br /&gt;
    &amp;quot;-m&amp;quot;, &amp;quot;--minutes&amp;quot;,&lt;br /&gt;
    help=&amp;quot;Minutes (default: 60)&amp;quot;,&lt;br /&gt;
    default=60, type=&#039;int&#039;)&lt;br /&gt;
&lt;br /&gt;
(options, args) = parser.parse_args()&lt;br /&gt;
&lt;br /&gt;
print &amp;quot;Filename: &amp;quot; + options.filename&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
fake handling of required option:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if not option.filename:&lt;br /&gt;
    parser.print_help()&lt;br /&gt;
    parser.error(&amp;quot;filename is required&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
change default usage:&lt;br /&gt;
  parser = OptionParser(usage=&amp;quot;Usage: %prog [args] arg1 arg2&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Really ugly way to print help usage  :-(&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def Usage():&lt;br /&gt;
    pname = sys.argv[0]&lt;br /&gt;
    cmd=&#039;%s -h&#039; % (pname)&lt;br /&gt;
    os.system(cmd)&lt;br /&gt;
&lt;br /&gt;
if (len(sys.argv) &amp;lt; 2):&lt;br /&gt;
    Usage()&lt;br /&gt;
    sys.exit(1)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Groups:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#  OptionGroup(parser, title, description=None)&lt;br /&gt;
group = OptionGroup(parser, &amp;quot;Dangerous Options&amp;quot;,&lt;br /&gt;
                    &amp;quot;Caution: use these options at your own risk.  &amp;quot;&lt;br /&gt;
                    &amp;quot;It is believed that some of them bite.&amp;quot;)&lt;br /&gt;
group.add_option(&amp;quot;-g&amp;quot;, action=&amp;quot;store_true&amp;quot;, help=&amp;quot;Group option.&amp;quot;)&lt;br /&gt;
parser.add_option_group(group)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hide an option:&lt;br /&gt;
* Option.help&lt;br /&gt;
: &amp;quot;Help text to print for this option when listing all available options after the user supplies a help option (such as --help). If no help text is supplied, the option will be listed without help text. To hide this option, use the special value optparse.SUPPRESS_HELP.&amp;quot;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
parser.add_option(&amp;quot;--secret&amp;quot;, help=SUPPRESS_HELP)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Issues with Option Parser:&lt;br /&gt;
* No handling for positional arguments&lt;br /&gt;
* No adding help for positional arguments&lt;br /&gt;
* No handling for required field&lt;br /&gt;
&lt;br /&gt;
=== argparse ===&lt;br /&gt;
&lt;br /&gt;
argparse - http://docs.python.org/library/argparse.html&lt;br /&gt;
&lt;br /&gt;
argparse — Parser for command-line options, arguments and sub-commands&lt;br /&gt;
&lt;br /&gt;
NOTE: MUCH MORE POWERFUL THAN OPTION PARSER!&lt;br /&gt;
&lt;br /&gt;
Note: New in version 2.7.&lt;br /&gt;
&lt;br /&gt;
Installation on &amp;lt;= 2.6&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Install argparse: - http://code.google.com/p/argparse/&lt;br /&gt;
# REQUIRES SETUPTOOLS&lt;br /&gt;
mkdir -p ~/.src ; cd ~/.src&lt;br /&gt;
wget http://argparse.googlecode.com/files/argparse-1.2.1.tar.gz&lt;br /&gt;
tar -zvxf argparse-1.2.1.tar.gz&lt;br /&gt;
cd argparse-1.2.1&lt;br /&gt;
sudo python setup.py install&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The argparse module makes it easy to write user-friendly command-line interfaces. The program defines what arguments it requires, and argparse will figure out how to parse those out of sys.argv. The argparse module also automatically generates help and usage messages and issues errors when users give the program invalid arguments.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import argparse&lt;br /&gt;
&lt;br /&gt;
parser = argparse.ArgumentParser(description=&#039;Process some integers.&#039;)&lt;br /&gt;
parser.add_argument(&#039;integers&#039;, metavar=&#039;N&#039;, type=int, nargs=&#039;+&#039;,&lt;br /&gt;
                   help=&#039;an integer for the accumulator&#039;)&lt;br /&gt;
parser.add_argument(&#039;--sum&#039;, dest=&#039;accumulate&#039;, action=&#039;store_const&#039;,&lt;br /&gt;
                   const=sum, default=max,&lt;br /&gt;
                   help=&#039;sum the integers (default: find the max)&#039;)&lt;br /&gt;
&lt;br /&gt;
args = parser.parse_args()&lt;br /&gt;
print args.accumulate(args.integers)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import argparse&lt;br /&gt;
&lt;br /&gt;
argparser = demoproject.util.argparse.ArgumentParser(&lt;br /&gt;
    usage=&#039;Kick off demoproject benchmarks.&#039;)&lt;br /&gt;
argparser.add_argument(&lt;br /&gt;
    &#039;--card&#039;,&lt;br /&gt;
    help=&#039;What cards to run on.  Depends on Jenkins NODE_LABEL environment&#039;&lt;br /&gt;
        &#039;variable for correct mappings.&#039;)&lt;br /&gt;
argparser.add_argument(&lt;br /&gt;
    &#039;--suite&#039;, metavar=&#039;SUITE&#039;,&lt;br /&gt;
    help=&#039;Specify the appropriate benchmark suite as defined in &#039;&lt;br /&gt;
        &#039;the benchmark ini file.  Defaults to standard_perf&#039;,&lt;br /&gt;
    default=&#039;standard_perf&#039;)&lt;br /&gt;
args = argparser.parse_args()&lt;br /&gt;
&lt;br /&gt;
print args.card&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Remove an argument: [http://stackoverflow.com/questions/32807319/disable-remove-argument-in-argparse]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def remove_options(parser, options):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot; remove_options(parser, [&#039;--some-option&#039;, &#039;--some-option2&#039;]) &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    for option in options:&lt;br /&gt;
        for action in parser._actions:&lt;br /&gt;
            if vars(action)[&#039;option_strings&#039;][0] == option:&lt;br /&gt;
                parser._handle_conflict_resolve(None,[(option,action)])&lt;br /&gt;
                break&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [http://docs.python.org/library/commands.html commands] ===&lt;br /&gt;
&lt;br /&gt;
35.16. commands — Utilities for running commands — Python v2.7.1 documentation - http://docs.python.org/library/commands.html&lt;br /&gt;
&lt;br /&gt;
Note: Deprecated since version 2.6: The commands module has been removed in Python 3.0. Use the subprocess module instead.&lt;br /&gt;
&lt;br /&gt;
The commands module contains wrapper functions for os.popen() which take a system command as a string and return any output generated by the command and, optionally, the exit status.&lt;br /&gt;
&lt;br /&gt;
Get status and output:&lt;br /&gt;
 status, output = commands.getstatusoutput(cmd)&lt;br /&gt;
&lt;br /&gt;
Get output ignoring status:&lt;br /&gt;
 output = commands.getoutput(cmd)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
NOTE: DO NOT USE getstatus() AS IT DOES NOT DO WHAT YOU THINK IT DOES!&lt;br /&gt;
 status = commands.getstatus(file)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import commands&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; commands.getstatusoutput(&#039;ls /bin/ls&#039;)&lt;br /&gt;
(0, &#039;/bin/ls&#039;)&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; commands.getstatusoutput(&#039;cat /bin/junk&#039;)&lt;br /&gt;
(256, &#039;cat: /bin/junk: No such file or directory&#039;)&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; commands.getstatusoutput(&#039;/bin/junk&#039;)&lt;br /&gt;
(256, &#039;sh: /bin/junk: not found&#039;)&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; commands.getoutput(&#039;ls /bin/ls&#039;)&lt;br /&gt;
&#039;/bin/ls&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; commands.getstatus(&#039;/bin/ls&#039;)&lt;br /&gt;
&#039;-rwxr-xr-x  1 root        13352 Oct 14  1994 /bin/ls&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [http://docs.python.org/library/_winreg.html Windows Registry] ===&lt;br /&gt;
&lt;br /&gt;
Note: The _winreg module has been renamed to winreg in Python 3.0.&lt;br /&gt;
&lt;br /&gt;
* 32.3. winreg – Windows registry access — Python v3.2 documentation - http://docs.python.org/py3k/library/winreg.html&lt;br /&gt;
* 34.3. _winreg – Windows registry access — Python v2.7.1 documentation - http://docs.python.org/library/_winreg.html&lt;br /&gt;
&lt;br /&gt;
Read from registry:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from _winreg import *&lt;br /&gt;
key = OpenKey(HKEY_LOCAL_MACHINE, r&#039;Software\Microsoft\Outlook Express&#039;, 0, KEY_ALL_ACCESS)&lt;br /&gt;
QueryValueEx(key, &amp;quot;InstallRoot&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Write to registry:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
keyVal = r&#039;Software\Microsoft\Internet Explorer\Main&#039;&lt;br /&gt;
try:&lt;br /&gt;
    key = OpenKey(HKEY_CURRENT_USER, keyVal, 0, KEY_ALL_ACCESS)&lt;br /&gt;
except:&lt;br /&gt;
    key = CreateKey(HKEY_CURRENT_USER, keyVal)&lt;br /&gt;
SetValueEx(key, &amp;quot;Start Page&amp;quot;, 0, REG_SZ, &amp;quot;http://www.blog.pythonlibrary.org/&amp;quot;)&lt;br /&gt;
CloseKey(key)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Enumerate registry keys:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from _winreg import EnumKey, HKEY_USERS&lt;br /&gt;
 &lt;br /&gt;
try:&lt;br /&gt;
    i = 0&lt;br /&gt;
    while True:&lt;br /&gt;
        subkey = EnumKey(HKEY_USERS, i)&lt;br /&gt;
        print subkey&lt;br /&gt;
        i += 1&lt;br /&gt;
except WindowsError:&lt;br /&gt;
    # WindowsError: [Errno 259] No more data is available    &lt;br /&gt;
    pass&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Another enumeration example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# File: winreg-example-1.py&lt;br /&gt;
&lt;br /&gt;
import _winreg&lt;br /&gt;
&lt;br /&gt;
explorer = _winreg.OpenKey(&lt;br /&gt;
    _winreg.HKEY_CURRENT_USER,&lt;br /&gt;
    &amp;quot;Software\\Microsoft\\Windows\\CurrentVersion\\Explorer&amp;quot;&lt;br /&gt;
    )&lt;br /&gt;
&lt;br /&gt;
# list values owned by this registry key&lt;br /&gt;
try:&lt;br /&gt;
    i = 0&lt;br /&gt;
    while 1:&lt;br /&gt;
        name, value, type = _winreg.EnumValue(explorer, i)&lt;br /&gt;
        print repr(name),&lt;br /&gt;
        i += 1&lt;br /&gt;
except WindowsError:&lt;br /&gt;
    print&lt;br /&gt;
&lt;br /&gt;
value, type = _winreg.QueryValueEx(explorer, &amp;quot;Logon User Name&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
print&lt;br /&gt;
print &amp;quot;user is&amp;quot;, repr(value)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Enable Remote Desktop Example: (by Kenneth)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from _winreg import *&lt;br /&gt;
key = OpenKey(HKEY_LOCAL_MACHINE, r&#039;SYSTEM\CurrentControlSet\Control\Terminal Server&#039;, 0, KEY_ALL_ACCESS)&lt;br /&gt;
SetValueEx(key, &amp;quot;fDenyTSConnections&amp;quot;, 0, REG_DWORD, 0)&lt;br /&gt;
ValueTypeTuple = QueryValueEx(key, &amp;quot;fDenyTSConnections&amp;quot;)   # (0, 4)&lt;br /&gt;
print(&amp;quot;Please reboot the system to complete the changes&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* Python’s _winreg: Editing the Windows Registry « The Mouse Vs. The Python - http://www.blog.pythonlibrary.org/2010/03/20/pythons-_winreg-editing-the-windows-registry/&lt;br /&gt;
&lt;br /&gt;
=== JSON ===&lt;br /&gt;
&lt;br /&gt;
JSON - http://docs.python.org/library/json.html&lt;br /&gt;
&lt;br /&gt;
ENCODING TO JSON STRING (type str)&lt;br /&gt;
&lt;br /&gt;
 import json&lt;br /&gt;
 json.dumps([&#039;foo&#039;, {&#039;bar&#039;: (&#039;baz&#039;, None, 1.0, 2)}])&lt;br /&gt;
 # &#039;[&amp;quot;foo&amp;quot;, {&amp;quot;bar&amp;quot;: [&amp;quot;baz&amp;quot;, null, 1.0, 2]}]&#039;&lt;br /&gt;
&lt;br /&gt;
compact encoding:&lt;br /&gt;
 import json&lt;br /&gt;
 json.dumps([1,2,3,{&#039;4&#039;: 5, &#039;6&#039;: 7}], separators=(&#039;,&#039;,&#039;:&#039;))&lt;br /&gt;
 # &#039;[1,2,3,{&amp;quot;4&amp;quot;:5,&amp;quot;6&amp;quot;:7}]&#039;&lt;br /&gt;
&lt;br /&gt;
Pretty printing:&lt;br /&gt;
 import json&lt;br /&gt;
 print json.dumps({&#039;4&#039;: 5, &#039;6&#039;: 7}, sort_keys=True, indent=4)&lt;br /&gt;
 # {&lt;br /&gt;
 #     &amp;quot;4&amp;quot;: 5,&lt;br /&gt;
 #     &amp;quot;6&amp;quot;: 7&lt;br /&gt;
 # }&lt;br /&gt;
&lt;br /&gt;
DECODING JSON STRING TO PYTHON LIST OR DICTIONARY OBJECT&lt;br /&gt;
&lt;br /&gt;
 import json&lt;br /&gt;
 json.loads(&#039;[&amp;quot;foo&amp;quot;, {&amp;quot;bar&amp;quot;:[&amp;quot;baz&amp;quot;, null, 1.0, 2]}]&#039;)&lt;br /&gt;
 # [u&#039;foo&#039;, {u&#039;bar&#039;: [u&#039;baz&#039;, None, 1.0, 2]}]&lt;br /&gt;
&lt;br /&gt;
Load from file:&lt;br /&gt;
 f = open(filename)&lt;br /&gt;
 j = json.load(f)&lt;br /&gt;
 print j[&amp;quot;kind&amp;quot;]  # &amp;quot;dual-controller-adapter&amp;quot;&lt;br /&gt;
 #{&lt;br /&gt;
 #   &amp;quot;kind&amp;quot;: &amp;quot;dual-controller-adapter&amp;quot;,&lt;br /&gt;
 #}&lt;br /&gt;
&lt;br /&gt;
From Command Line:&lt;br /&gt;
 echo &#039;{&amp;quot;foo&amp;quot;: &amp;quot;lorem&amp;quot;, &amp;quot;bar&amp;quot;: &amp;quot;ipsum&amp;quot;}&#039; | python -mjson.tool&lt;br /&gt;
&lt;br /&gt;
 # get value&lt;br /&gt;
 echo &#039;{&amp;quot;test&amp;quot;:1,&amp;quot;test2&amp;quot;:2}&#039; | python -c &#039;import sys,json;data=json.loads(sys.stdin.read()); print data[&amp;quot;test&amp;quot;]&#039;&lt;br /&gt;
&lt;br /&gt;
 # read large file&lt;br /&gt;
 python -c &amp;quot;import json;f=open(&#039;file.json&#039;);data=json.load(f);print json.dumps(data,indent=2)&amp;quot;&lt;br /&gt;
 python -c &amp;quot;import json;print json.dumps(json.load(open(&#039;file.json&#039;)),indent=2)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Load from web:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import httplib&lt;br /&gt;
import json&lt;br /&gt;
&lt;br /&gt;
def get_http_json(server, path):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot; This performs an HTTP GET against a server and path and returns the&lt;br /&gt;
        resulting page data.&lt;br /&gt;
&lt;br /&gt;
        server The server we&#039;re hitting, e.g. demo.com&lt;br /&gt;
        path   The path we&#039;re hitting, e.g. api/part/MA12345/&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    connection = httplib.HTTPConnection(server)&lt;br /&gt;
    try:&lt;br /&gt;
        url = &#039;http://%s/%s&#039; % (server, path)&lt;br /&gt;
        print &#039;Querying url %s&#039; % url&lt;br /&gt;
        connection.request(&#039;GET&#039;, url)&lt;br /&gt;
        response = connection.getresponse()&lt;br /&gt;
        if response.status == httplib.OK:&lt;br /&gt;
            return json.loads(response.read())&lt;br /&gt;
        else:&lt;br /&gt;
            print &#039;Unable to get %s. %s %s&#039; % (url, response.reason,&lt;br /&gt;
                    response.status)&lt;br /&gt;
            return None&lt;br /&gt;
    finally:&lt;br /&gt;
        connection.close()&lt;br /&gt;
&lt;br /&gt;
j = get_http_json(server, path)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pretty printing from the command line:&lt;br /&gt;
 echo &#039;{&amp;quot;json&amp;quot;:&amp;quot;obj&amp;quot;}&#039; | python -mjson.tool&lt;br /&gt;
 #{&lt;br /&gt;
 #   &amp;quot;json&amp;quot;: &amp;quot;obj&amp;quot;&lt;br /&gt;
 #}&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* 18.2. json — JSON encoder and decoder — Python v2.7.1 documentation - http://docs.python.org/library/json.html&lt;br /&gt;
&lt;br /&gt;
=== Sockets ===&lt;br /&gt;
&lt;br /&gt;
See [[Python/Sockets]]&lt;br /&gt;
&lt;br /&gt;
=== [http://docs.python.org/library/base64.html base64] ===&lt;br /&gt;
&lt;br /&gt;
 import base64&lt;br /&gt;
&lt;br /&gt;
Encode:&lt;br /&gt;
 encoded = base64.b64encode(&#039;data to be encoded&#039;)&lt;br /&gt;
&lt;br /&gt;
Decode:&lt;br /&gt;
 base64.b64decode(encoded)&lt;br /&gt;
&lt;br /&gt;
=== daemonize ===&lt;br /&gt;
&lt;br /&gt;
Creating a daemon the Python way « Python recipes « ActiveState Code - http://code.activestate.com/recipes/278731-creating-a-daemon-the-python-way/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import os&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
try:&lt;br /&gt;
    pid = os.fork()&lt;br /&gt;
except OSError, e:&lt;br /&gt;
    raise Exception, &amp;quot;%s [%d]&amp;quot; % (e.strerror, e.errno)&lt;br /&gt;
&lt;br /&gt;
if (pid != 0):  # parent&lt;br /&gt;
    os._exit(0)&lt;br /&gt;
&lt;br /&gt;
# create new process session&lt;br /&gt;
os.setsid()&lt;br /&gt;
&lt;br /&gt;
# redirect stdin, stdout, stderr&lt;br /&gt;
os.open(&#039;/dev/null&#039;, os.O_RDWR)&lt;br /&gt;
os.dup2(0, 1)&lt;br /&gt;
os.dup2(0, 2)&lt;br /&gt;
&lt;br /&gt;
#... tasks ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
My Solution:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import os&lt;br /&gt;
import sys&lt;br /&gt;
import signal&lt;br /&gt;
import syslog&lt;br /&gt;
&lt;br /&gt;
HUP = False&lt;br /&gt;
&lt;br /&gt;
def log(msg):&lt;br /&gt;
    syslog.syslog(str(msg))&lt;br /&gt;
syslog.openlog(&#039;[WATER]&#039;)&lt;br /&gt;
&lt;br /&gt;
def kill_signal_handler(signal, frame):&lt;br /&gt;
    log(&amp;quot;Being killed off: {0} {1}&amp;quot;.format(signal, frame))&lt;br /&gt;
    log(&amp;quot;Shutting Down!&amp;quot;)&lt;br /&gt;
    sys.exit(0)&lt;br /&gt;
signal.signal(signal.SIGTERM, kill_signal_handler)&lt;br /&gt;
signal.signal(signal.SIGALRM, kill_signal_handler)&lt;br /&gt;
&lt;br /&gt;
def hup_signal_handler(signal, frame):&lt;br /&gt;
    global HUP&lt;br /&gt;
    log(&amp;quot;Signal reload received: {0} {1}&amp;quot;.format(signal, frame))&lt;br /&gt;
    HUP=True&lt;br /&gt;
signal.signal(signal.SIGHUP, hup_signal_handler)&lt;br /&gt;
&lt;br /&gt;
def main_loop():&lt;br /&gt;
    global HUP&lt;br /&gt;
&lt;br /&gt;
    while True:&lt;br /&gt;
        #  ... handle HUP=True ...&lt;br /&gt;
&lt;br /&gt;
        # ... main code ...&lt;br /&gt;
&lt;br /&gt;
        # wait 60 seconds before we start the next loop&lt;br /&gt;
        time.sleep(60)  # signals will interrupt this&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
    log(&amp;quot;Starting Daemon...&amp;quot;)&lt;br /&gt;
    child_id = os.fork()&lt;br /&gt;
    if child_id:&lt;br /&gt;
        log(&amp;quot;Daemonized!&amp;quot;)&lt;br /&gt;
        sys.exit(0)&lt;br /&gt;
    os.setsid()&lt;br /&gt;
    # redirect stdin, stdout, stderr&lt;br /&gt;
    os.open(&#039;/dev/null&#039;, os.O_RDWR)&lt;br /&gt;
    os.dup2(0, 1)&lt;br /&gt;
    os.dup2(0, 2)&lt;br /&gt;
&lt;br /&gt;
    # write pid&lt;br /&gt;
    with open(&amp;quot;water.pid&amp;quot;, &amp;quot;w&amp;quot;) as f:&lt;br /&gt;
        f.write(str(os.getpid()))&lt;br /&gt;
&lt;br /&gt;
    while True:&lt;br /&gt;
        try:&lt;br /&gt;
            main_loop()&lt;br /&gt;
        except Exception as e:&lt;br /&gt;
            log(&amp;quot;Critical Failure Caught: %s&amp;quot; % str(e))&lt;br /&gt;
            log(&amp;quot;Critical Failure - Restarting!&amp;quot;)&lt;br /&gt;
            time.sleep(30)&lt;br /&gt;
            #raise e&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 ln -s /opt/pyton27/bin/python pyton-water&lt;br /&gt;
 ./python-water water.py&lt;br /&gt;
 killall python-water&lt;br /&gt;
&lt;br /&gt;
==== fork ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import os&lt;br /&gt;
import sys&lt;br /&gt;
import time&lt;br /&gt;
&lt;br /&gt;
child_id = os.fork()&lt;br /&gt;
if child_id:&lt;br /&gt;
  print &amp;quot;parent exiting&amp;quot;&lt;br /&gt;
  sys.exit(0)&lt;br /&gt;
&lt;br /&gt;
while True:&lt;br /&gt;
    time.sleep(3)&lt;br /&gt;
    print &amp;quot;child&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For windows, to hide the console, see [[#Hide Console]]&lt;br /&gt;
&lt;br /&gt;
=== csv ===&lt;br /&gt;
&lt;br /&gt;
13.1. csv — CSV File Reading and Writing — Python v2.7.2 documentation - http://docs.python.org/library/csv.html&lt;br /&gt;
&lt;br /&gt;
Read:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import csv&lt;br /&gt;
spamReader = csv.reader(open(&#039;eggs.csv&#039;, &#039;rb&#039;), delimiter=&#039; &#039;, quotechar=&#039;|&#039;)&lt;br /&gt;
for row in spamReader:&lt;br /&gt;
  print &#039;, &#039;.join(row)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Write:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import csv&lt;br /&gt;
spamWriter = csv.writer(open(&#039;eggs.csv&#039;, &#039;wb&#039;), delimiter=&#039; &#039;,&lt;br /&gt;
    quotechar=&#039;|&#039;, quoting=csv.QUOTE_MINIMAL)&lt;br /&gt;
spamWriter.writerow([&#039;Spam&#039;] * 5 + [&#039;Baked Beans&#039;])&lt;br /&gt;
spamWriter.writerow([&#039;Spam&#039;, &#039;Lovely Spam&#039;, &#039;Wonderful Spam&#039;])&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== SQLite ===&lt;br /&gt;
&lt;br /&gt;
11.13. sqlite3 — DB-API 2.0 interface for SQLite databases — Python v2.7.2 documentation - http://docs.python.org/library/sqlite3.html&lt;br /&gt;
&lt;br /&gt;
sqlite3 - New in version 2.5.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import sqlite3&lt;br /&gt;
&lt;br /&gt;
conn = sqlite3.connect(&#039;/tmp/example&#039;)&lt;br /&gt;
&lt;br /&gt;
c = conn.cursor()&lt;br /&gt;
&lt;br /&gt;
# Create table&lt;br /&gt;
c.execute(&#039;&#039;&#039;create table stocks&lt;br /&gt;
(date text, trans text, symbol text,&lt;br /&gt;
 qty real, price real)&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
# Insert a row of data&lt;br /&gt;
c.execute(&amp;quot;&amp;quot;&amp;quot;insert into stocks&lt;br /&gt;
          values (&#039;2006-01-05&#039;,&#039;BUY&#039;,&#039;RHAT&#039;,100,35.14)&amp;quot;&amp;quot;&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
# Show affected row count&lt;br /&gt;
print c.rowcount&lt;br /&gt;
&lt;br /&gt;
# Save (commit) the changes&lt;br /&gt;
conn.commit()&lt;br /&gt;
&lt;br /&gt;
# We can also close the cursor if we are done with it&lt;br /&gt;
c.close()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
parameter substitution:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Never do this -- insecure!&lt;br /&gt;
symbol = &#039;IBM&#039;&lt;br /&gt;
c.execute(&amp;quot;... where symbol = &#039;%s&#039;&amp;quot; % symbol)&lt;br /&gt;
&lt;br /&gt;
# Do this instead&lt;br /&gt;
t = (symbol,)&lt;br /&gt;
c.execute(&#039;select * from stocks where symbol=?&#039;, t)&lt;br /&gt;
c.execute(&#039;select * from stocks where symbol=?&#039;, (symbol,))&lt;br /&gt;
&lt;br /&gt;
# Larger example&lt;br /&gt;
for t in [(&#039;2006-03-28&#039;, &#039;BUY&#039;, &#039;IBM&#039;, 1000, 45.00),&lt;br /&gt;
          (&#039;2006-04-05&#039;, &#039;BUY&#039;, &#039;MSOFT&#039;, 1000, 72.00),&lt;br /&gt;
          (&#039;2006-04-06&#039;, &#039;SELL&#039;, &#039;IBM&#039;, 500, 53.00),&lt;br /&gt;
         ]:&lt;br /&gt;
    c.execute(&#039;insert into stocks values (?,?,?,?,?)&#039;, t)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
select results:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
c = conn.cursor()&lt;br /&gt;
c.execute(&#039;select * from stocks order by price&#039;)&lt;br /&gt;
&lt;br /&gt;
for row in c:&lt;br /&gt;
  print row  # row is a tuple&lt;br /&gt;
&lt;br /&gt;
# OR (but not both)&lt;br /&gt;
&lt;br /&gt;
rows = c.fetchall()    # rows is list of tuples&lt;br /&gt;
print len(rows)&lt;br /&gt;
for row in rows:&lt;br /&gt;
  print row&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Show which version of sqlite3: [http://zetcode.com/db/sqlitepythontutorial/]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/python&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&lt;br /&gt;
import sqlite3 as lite&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
con = None&lt;br /&gt;
&lt;br /&gt;
try:&lt;br /&gt;
    con = lite.connect(&#039;test.db&#039;)&lt;br /&gt;
&lt;br /&gt;
    cur = con.cursor()&lt;br /&gt;
    cur.execute(&#039;SELECT SQLITE_VERSION()&#039;)&lt;br /&gt;
&lt;br /&gt;
    data = cur.fetchone()&lt;br /&gt;
&lt;br /&gt;
    print &amp;quot;SQLite version: %s&amp;quot; % data&lt;br /&gt;
&lt;br /&gt;
except lite.Error, e:&lt;br /&gt;
&lt;br /&gt;
    print &amp;quot;Error %s:&amp;quot; % e.args[0]&lt;br /&gt;
    sys.exit(1)&lt;br /&gt;
&lt;br /&gt;
finally:&lt;br /&gt;
&lt;br /&gt;
    if con:&lt;br /&gt;
        con.close()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Or simply: [http://stackoverflow.com/questions/1545479/force-python-to-forego-native-sqlite3-and-use-the-installed-latest-sqlite3-ver]&lt;br /&gt;
 # echo -e &amp;quot;import sqlite3\nprint sqlite3.sqlite_version_info&amp;quot; | python&lt;br /&gt;
 (3, 3, 6)&lt;br /&gt;
&lt;br /&gt;
=== MySQL Database ===&lt;br /&gt;
&lt;br /&gt;
Ubuntu packages:&lt;br /&gt;
* python-mysqldb - Python interface to MySQL&lt;br /&gt;
* python-mysql.connector - pure Python implementation of MySQL Client/Server protocol&lt;br /&gt;
&lt;br /&gt;
 apt-get install python-mysqldb&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; import _mysql&lt;br /&gt;
&lt;br /&gt;
 apt-get install python-mysql.connector&lt;br /&gt;
 &lt;br /&gt;
PIP:&lt;br /&gt;
* https://pypi.python.org/pypi/MySQL-python&lt;br /&gt;
* https://pypi.python.org/pypi/mysqlclient&lt;br /&gt;
&lt;br /&gt;
 pip install MySQL-python&lt;br /&gt;
&lt;br /&gt;
 pip install mysqlclient&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
_mysql - http://mysql-python.sourceforge.net/MySQLdb.html&lt;br /&gt;
&lt;br /&gt;
 apt-get install python-mysqldb&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import _mysql&lt;br /&gt;
&lt;br /&gt;
db=_mysql.connect(host=&amp;quot;localhost&amp;quot;,user=&amp;quot;user&amp;quot;,&lt;br /&gt;
                  passwd=&amp;quot;pass&amp;quot;,db=&amp;quot;db&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
db.query(&amp;quot;&amp;quot;&amp;quot;SELECT spam, eggs, sausage FROM breakfast&lt;br /&gt;
         WHERE price &amp;lt; 5&amp;quot;&amp;quot;&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
r=db.store_result()&lt;br /&gt;
# ...or...&lt;br /&gt;
r=db.use_result()&lt;br /&gt;
&lt;br /&gt;
row = r.fetch_row()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== couchdb ===&lt;br /&gt;
&lt;br /&gt;
Getting started with couchdb-python — couchdb-python v0.8 documentation - http://packages.python.org/CouchDB/getting-started.html&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
couch = couchdb.Server(&#039;http://127.0.0.1:5984/&#039;)&lt;br /&gt;
&lt;br /&gt;
# database&lt;br /&gt;
db = couch.create(&#039;test&#039;) # create new&lt;br /&gt;
db = couch[&#039;mydb&#039;] # or get existing&lt;br /&gt;
&lt;br /&gt;
# print databases:&lt;br /&gt;
for db in couch:&lt;br /&gt;
  print db&lt;br /&gt;
&lt;br /&gt;
doc = {&#039;foo&#039;: &#039;bar&#039;}&lt;br /&gt;
doc_id, doc_rev = db.save(doc)&lt;br /&gt;
# (u&#039;9278f7691c3421227a9f8436540008f9&#039;, u&#039;1-4c6114c65e295552ab1019e2b046b10e&#039;)&lt;br /&gt;
# note: this also updates doc with _rev and _id&lt;br /&gt;
doc = db[&#039;9278f7691c3421227a9f8436540008f9&#039;]&lt;br /&gt;
&lt;br /&gt;
# better to create a document using an id you want, instead of the randomly generated one&lt;br /&gt;
db[doc.id] = doc  # this will write immediately to the database&lt;br /&gt;
&lt;br /&gt;
# print all docs:&lt;br /&gt;
for id in db:&lt;br /&gt;
  print id&lt;br /&gt;
&lt;br /&gt;
# delete doc&lt;br /&gt;
db.delete(doc)&lt;br /&gt;
&lt;br /&gt;
# delete database&lt;br /&gt;
couch.delete(&#039;test&#039;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Search database:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# show all records&lt;br /&gt;
map_fun = &#039;&#039;&#039;function(doc) { emit(doc.name, null); }&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
# row = &amp;lt;Row id=u&#039;12341234123412341234&#039;, key=None, value=None&amp;gt;&lt;br /&gt;
# emit(key, value) - returns the values for key and value&lt;br /&gt;
&lt;br /&gt;
map_fun = &#039;&#039;&#039;&lt;br /&gt;
function(doc) {&lt;br /&gt;
  if (doc.username == &#039;virt-01&#039;)&lt;br /&gt;
     emit(doc.username, null);&lt;br /&gt;
}&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
# row = &amp;lt;Row id=u&#039;12341234123412341234&#039;, key=None, value=None&amp;gt;&lt;br /&gt;
for row in db.query(map_fun):&lt;br /&gt;
  print row.id&lt;br /&gt;
&lt;br /&gt;
for row in db.query(map_fun, descending=True):&lt;br /&gt;
  print row.id&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
couchdb-python - CouchDB Python Library - Google Project Hosting - http://code.google.com/p/couchdb-python/&lt;br /&gt;
&lt;br /&gt;
Installation:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir -p ~/.src ; cd ~/.src&lt;br /&gt;
wget http://pypi.python.org/packages/source/C/CouchDB/CouchDB-0.8.tar.gz#md5=e32b39e459e1fa2586ea252712a11a59&lt;br /&gt;
tar -zvxf CouchDB-0.8.tar.gz&lt;br /&gt;
cd CouchDB-0.8&lt;br /&gt;
python setup.py install&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Test:&lt;br /&gt;
 echo &amp;quot;import couchdb&amp;quot; | python&lt;br /&gt;
&lt;br /&gt;
=== nose ===&lt;br /&gt;
&lt;br /&gt;
nose: nose extends unittest to make testing easier&lt;br /&gt;
&lt;br /&gt;
nose : Python Package Index - http://pypi.python.org/pypi/nose&lt;br /&gt;
&lt;br /&gt;
Install:&lt;br /&gt;
 mkdir -p ~/.src ; cd ~/.src&lt;br /&gt;
 wget http://pypi.python.org/packages/source/n/nose/nose-1.1.2.tar.gz#md5=144f237b615e23f21f6a50b2183aa817&lt;br /&gt;
 tar -zvxf nose-1.1.2.tar.gz&lt;br /&gt;
 cd nose-1.1.2&lt;br /&gt;
 sudo python setup.py install&lt;br /&gt;
&lt;br /&gt;
skeleton:&lt;br /&gt;
 mkdir skeleton&lt;br /&gt;
 cd skeleton&lt;br /&gt;
 mkdir bin NAME tests docs&lt;br /&gt;
 touch NAME/__init__.py&lt;br /&gt;
 touch tests/__init__.py&lt;br /&gt;
 touch tests/NAME_tests.py&lt;br /&gt;
&lt;br /&gt;
nose test skeleton:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# tests/NAME_tests.py&lt;br /&gt;
from nose.tools import *&lt;br /&gt;
import klib&lt;br /&gt;
&lt;br /&gt;
def setup():&lt;br /&gt;
    print &amp;quot;SETUP!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
def teardown():&lt;br /&gt;
    print &amp;quot;TEAR DOWN!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
def test_basic():&lt;br /&gt;
    print &amp;quot;I RAN!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# def test_something_else():&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
 nosetests&lt;br /&gt;
&lt;br /&gt;
See Also:&lt;br /&gt;
* [[#doctest]]&lt;br /&gt;
* [[#unittest]]&lt;br /&gt;
&lt;br /&gt;
=== pydoc ===&lt;br /&gt;
&lt;br /&gt;
25.1. pydoc — Documentation generator and online help system — Python v2.7.2 documentation - http://docs.python.org/library/pydoc.html&lt;br /&gt;
&lt;br /&gt;
pydoc - The pydoc module automatically generates documentation from Python modules.&lt;br /&gt;
&lt;br /&gt;
pydoc - same as &#039;import [library], help([library])&#039;&lt;br /&gt;
 $ pydoc [library]&lt;br /&gt;
&lt;br /&gt;
Note: lists some special &#039;module metadata variables&#039; separately (e.g. version, author).&lt;br /&gt;
&lt;br /&gt;
special pydoc recognized metadata sections:&lt;br /&gt;
 __version__&lt;br /&gt;
 __author__&lt;br /&gt;
 __credits__&lt;br /&gt;
 __date__&lt;br /&gt;
&lt;br /&gt;
==== pydoc function module ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Help on package klib:&lt;br /&gt;
&lt;br /&gt;
NAME&lt;br /&gt;
    klib - This is the name&lt;br /&gt;
&lt;br /&gt;
FILE&lt;br /&gt;
    /root/klib/klib/__init__.py&lt;br /&gt;
&lt;br /&gt;
DESCRIPTION&lt;br /&gt;
    These are module doc strings&lt;br /&gt;
        that give helpful details&lt;br /&gt;
&lt;br /&gt;
PACKAGE CONTENTS&lt;br /&gt;
    markone&lt;br /&gt;
&lt;br /&gt;
FUNCTIONS&lt;br /&gt;
    func1()&lt;br /&gt;
        This is a doc string&lt;br /&gt;
        for func1&lt;br /&gt;
&lt;br /&gt;
DATA&lt;br /&gt;
    PI = 3.141&lt;br /&gt;
    __all__ = [&#039;func1&#039;, &#039;PI&#039;]&lt;br /&gt;
    __author__ = &#039;Kenneth &amp;lt;kenneth@oeey.com&amp;gt;&#039;&lt;br /&gt;
    __copyright__ = &#039;Copyright 2007, The Project&#039;&lt;br /&gt;
    __credits__ = &#039;Credits go to me&#039;&lt;br /&gt;
    __date__ = &#039;26 February 2001&#039;&lt;br /&gt;
    __email__ = &#039;ken@oeey.com&#039;&lt;br /&gt;
    __license__ = &#039;GPL&#039;&lt;br /&gt;
    __maintainer__ = &#039;Ken&#039;&lt;br /&gt;
    __status__ = &#039;Production&#039;&lt;br /&gt;
    __version__ = &#039;$Revision: 83492 $&#039;&lt;br /&gt;
&lt;br /&gt;
VERSION&lt;br /&gt;
    83492&lt;br /&gt;
&lt;br /&gt;
DATE&lt;br /&gt;
    26 February 2001&lt;br /&gt;
&lt;br /&gt;
AUTHOR&lt;br /&gt;
    Kenneth &amp;lt;kenneth@oeey.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
CREDITS&lt;br /&gt;
    Credits go to me&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Source:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
This is the name&lt;br /&gt;
&lt;br /&gt;
These are module doc strings&lt;br /&gt;
    that give helpful details&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#__version__ = &amp;quot;1.0&amp;quot;&lt;br /&gt;
__version__ = &amp;quot;$Revision: 83492 $&amp;quot;&lt;br /&gt;
__author__ = &amp;quot;Kenneth &amp;lt;kenneth@oeey.com&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
__date__ = &amp;quot;26 February 2001&amp;quot;&lt;br /&gt;
__credits__ = &amp;quot;Credits go to me&amp;quot;&lt;br /&gt;
&lt;br /&gt;
__all__ = [&#039;func1&#039;, &#039;PI&#039;]&lt;br /&gt;
&lt;br /&gt;
PI = 3.141&lt;br /&gt;
&lt;br /&gt;
__copyright__ = &#039;hello license&#039;&lt;br /&gt;
__license__ = &amp;quot;GPL&amp;quot;&lt;br /&gt;
__copyright__ = &amp;quot;Copyright 2007, The Project&amp;quot;&lt;br /&gt;
__maintainer__ = &amp;quot;Ken&amp;quot;&lt;br /&gt;
__email__ = &amp;quot;ken@oeey.com&amp;quot;&lt;br /&gt;
__status__ = &amp;quot;Production&amp;quot;&lt;br /&gt;
&lt;br /&gt;
def func1():&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    This is a doc string&lt;br /&gt;
    for func1&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== pydoc class module ====&lt;br /&gt;
&lt;br /&gt;
Sample:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Help on module class_pydoc:&lt;br /&gt;
&lt;br /&gt;
NAME&lt;br /&gt;
    class_pydoc - This is the name&lt;br /&gt;
&lt;br /&gt;
FILE&lt;br /&gt;
    /root/class_pydoc.py&lt;br /&gt;
&lt;br /&gt;
DESCRIPTION&lt;br /&gt;
    These are module doc strings&lt;br /&gt;
        that give helpful details&lt;br /&gt;
&lt;br /&gt;
CLASSES&lt;br /&gt;
    Toad&lt;br /&gt;
&lt;br /&gt;
    class Toad&lt;br /&gt;
     |  doc string for object&lt;br /&gt;
     |&lt;br /&gt;
     |  Methods defined here:&lt;br /&gt;
     |&lt;br /&gt;
     |  __init___(self, name)&lt;br /&gt;
     |      Constructor&lt;br /&gt;
     |&lt;br /&gt;
     |  instance_function(self)&lt;br /&gt;
     |      Instance Function&lt;br /&gt;
     |&lt;br /&gt;
     |  ----------------------------------------------------------------------&lt;br /&gt;
     |  Class methods defined here:&lt;br /&gt;
     |&lt;br /&gt;
     |  class_function(cls) from __builtin__.classobj&lt;br /&gt;
     |      Class Function&lt;br /&gt;
     |&lt;br /&gt;
     |  ----------------------------------------------------------------------&lt;br /&gt;
     |  Data and other attributes defined here:&lt;br /&gt;
     |&lt;br /&gt;
     |  my_class_attribute = &#039;sample class attribute&#039;&lt;br /&gt;
&lt;br /&gt;
DATA&lt;br /&gt;
    PI = 3.141&lt;br /&gt;
    __author__ = &#039;Kenneth &amp;lt;kenneth@oeey.com&amp;gt;&#039;&lt;br /&gt;
    __copyright__ = &#039;Copyright 2007, The Project&#039;&lt;br /&gt;
    __credits__ = &#039;Credits go to me&#039;&lt;br /&gt;
    __date__ = &#039;26 February 2001&#039;&lt;br /&gt;
    __email__ = &#039;ken@oeey.com&#039;&lt;br /&gt;
    __license__ = &#039;GPL&#039;&lt;br /&gt;
    __maintainer__ = &#039;Ken&#039;&lt;br /&gt;
    __status__ = &#039;Production&#039;&lt;br /&gt;
    __version__ = &#039;1.0&#039;&lt;br /&gt;
&lt;br /&gt;
VERSION&lt;br /&gt;
    1.0&lt;br /&gt;
&lt;br /&gt;
DATE&lt;br /&gt;
    26 February 2001&lt;br /&gt;
&lt;br /&gt;
AUTHOR&lt;br /&gt;
    Kenneth &amp;lt;kenneth@oeey.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
CREDITS&lt;br /&gt;
    Credits go to me&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Code:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
This is the name&lt;br /&gt;
&lt;br /&gt;
These are module doc strings&lt;br /&gt;
    that give helpful details&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
__version__ = &amp;quot;1.0&amp;quot;&lt;br /&gt;
#__version__ = &amp;quot;$Revision: 83492 $&amp;quot;&lt;br /&gt;
__author__ = &amp;quot;Kenneth &amp;lt;kenneth@oeey.com&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
__date__ = &amp;quot;26 February 2001&amp;quot;&lt;br /&gt;
__credits__ = &amp;quot;Credits go to me&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#__all__ = [&#039;func1&#039;, &#039;PI&#039;]&lt;br /&gt;
&lt;br /&gt;
PI = 3.141&lt;br /&gt;
&lt;br /&gt;
__copyright__ = &#039;hello license&#039;&lt;br /&gt;
__license__ = &amp;quot;GPL&amp;quot;&lt;br /&gt;
__copyright__ = &amp;quot;Copyright 2007, The Project&amp;quot;&lt;br /&gt;
__maintainer__ = &amp;quot;Ken&amp;quot;&lt;br /&gt;
__email__ = &amp;quot;ken@oeey.com&amp;quot;&lt;br /&gt;
__status__ = &amp;quot;Production&amp;quot;&lt;br /&gt;
&lt;br /&gt;
class Toad:&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot; doc string for object &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    my_class_attribute = &#039;sample class attribute&#039;&lt;br /&gt;
&lt;br /&gt;
    def __init___(self, name):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot; Constructor &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    def instance_function(self):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot; Instance Function &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    @classmethod&lt;br /&gt;
    def class_function(cls):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot; Class Function &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== username ===&lt;br /&gt;
&lt;br /&gt;
User ID:&lt;br /&gt;
 os.getuid()&lt;br /&gt;
&lt;br /&gt;
User Name:&lt;br /&gt;
 # fails it stdin piped to program&lt;br /&gt;
 os.getlogin()&lt;br /&gt;
&lt;br /&gt;
User Name:&lt;br /&gt;
 import sys&lt;br /&gt;
 import pwd&lt;br /&gt;
 def get_username():&lt;br /&gt;
     return pwd.getpwuid( os.getuid() )[ 0 ]&lt;br /&gt;
&lt;br /&gt;
Environment:&lt;br /&gt;
 os.environ[&#039;USER&#039;]&lt;br /&gt;
&lt;br /&gt;
=== hostname ===&lt;br /&gt;
&lt;br /&gt;
 import socket&lt;br /&gt;
 print(socket.gethostname())&lt;br /&gt;
&lt;br /&gt;
 os.uname()[1]&lt;br /&gt;
&lt;br /&gt;
 hostname = os.system(&#039;hostname&#039;)&lt;br /&gt;
&lt;br /&gt;
=== Networking ===&lt;br /&gt;
&lt;br /&gt;
==== Get Hostname ====&lt;br /&gt;
&lt;br /&gt;
 import socket&lt;br /&gt;
 print(socket.gethostname())&lt;br /&gt;
&lt;br /&gt;
==== Convert hostname to ip address ====&lt;br /&gt;
&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; socket.gethostbyaddr(&#039;demo&#039;)&lt;br /&gt;
 (&#039;demo.oeey.com&#039;, [], [&#039;10.10.10.10&#039;])&lt;br /&gt;
&lt;br /&gt;
/usr/local/bin/whatip: (or nametoip)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
# whatip - convert hostname to ip address&lt;br /&gt;
# author: Kenneth Burgener &amp;lt;kenneth@oeey.com&amp;gt; (FEB 2012)&lt;br /&gt;
#&lt;br /&gt;
&lt;br /&gt;
import socket&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
if len(sys.argv) != 2:&lt;br /&gt;
  print &amp;quot;Convert Hostname to IP Address&amp;quot;&lt;br /&gt;
  print &amp;quot;Usage: %s HOSTNAME&amp;quot; % sys.argv[0].split(&#039;/&#039;)[-1]&lt;br /&gt;
  sys.exit(1)&lt;br /&gt;
&lt;br /&gt;
hostname = sys.argv[1]&lt;br /&gt;
try:&lt;br /&gt;
  result = socket.gethostbyaddr(hostname)&lt;br /&gt;
  print result[2][0]&lt;br /&gt;
except (socket.gaierror, socket.herror) as e:&lt;br /&gt;
  print &amp;quot;Error: Unable to resolve &#039;%s&#039;&amp;quot; % hostname&lt;br /&gt;
  sys.exit(1)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Get Public IP Address ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)&lt;br /&gt;
s.connect((&amp;quot;gmail.com&amp;quot;,80))&lt;br /&gt;
print(s.getsockname()[0])&lt;br /&gt;
s.close()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
networking - Finding local IP addresses using Python&#039;s stdlib - Stack Overflow - http://stackoverflow.com/questions/166506/finding-local-ip-addresses-using-pythons-stdlib&lt;br /&gt;
&lt;br /&gt;
==== Python Network Server ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/python           # This is server.py file&lt;br /&gt;
&lt;br /&gt;
import socket               # Import socket module&lt;br /&gt;
&lt;br /&gt;
s = socket.socket()         # Create a socket object&lt;br /&gt;
host = socket.gethostname() # Get local machine name&lt;br /&gt;
port = 12345                # Reserve a port for your service.&lt;br /&gt;
s.bind((host, port))        # Bind to the port&lt;br /&gt;
&lt;br /&gt;
s.listen(5)                 # Now wait for client connection.&lt;br /&gt;
while True:&lt;br /&gt;
   c, addr = s.accept()     # Establish connection with client.&lt;br /&gt;
   print &#039;Got connection from&#039;, addr&lt;br /&gt;
   c.send(&#039;Thank you for connecting&#039;)&lt;br /&gt;
   c.close()                # Close the connection&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Source: http://www.tutorialspoint.com/python/python_networking.htm&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* 17.2. socket — Low-level networking interface — Python v2.7.5 documentation - http://docs.python.org/2/library/socket.html&lt;br /&gt;
&lt;br /&gt;
==== Python Network Client ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/python           # This is client.py file&lt;br /&gt;
&lt;br /&gt;
import socket               # Import socket module&lt;br /&gt;
&lt;br /&gt;
s = socket.socket()         # Create a socket object&lt;br /&gt;
host = socket.gethostname() # Get local machine name&lt;br /&gt;
port = 12345                # Reserve a port for your service.&lt;br /&gt;
&lt;br /&gt;
s.connect((host, port))&lt;br /&gt;
print s.recv(1024)&lt;br /&gt;
s.close                     # Close the socket when done&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Source: http://www.tutorialspoint.com/python/python_networking.htm&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* 17.2. socket — Low-level networking interface — Python v2.7.5 documentation - http://docs.python.org/2/library/socket.html&lt;br /&gt;
&lt;br /&gt;
=== Run Library Module as Script ===&lt;br /&gt;
&lt;br /&gt;
Run python with -m option:&lt;br /&gt;
 -m mod : run library module as a script (terminates option list)&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
 cat [json_file] | python -m json.tool&lt;br /&gt;
 # same as:&lt;br /&gt;
 cat [json_file] | python /opt/python26/lib/python2.6/json/tool.py&lt;br /&gt;
&lt;br /&gt;
Good for when library is buried deep in the library directories&lt;br /&gt;
&lt;br /&gt;
=== Hex ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hex(10)  # print integer as hex string&lt;br /&gt;
&#039;0xa&#039;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; sys.hexversion  # python version as integer&lt;br /&gt;
33817584&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hex(sys.hexversion)  # python version as hex&lt;br /&gt;
&#039;0x20403f0&#039;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; print &amp;quot;0x%08x&amp;quot; % sys.hexversion  # python version as hex&lt;br /&gt;
&#039;0x20403f0&#039;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; int(&#039;0xa&#039;, 16)  # hex string to integer&lt;br /&gt;
10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; int(&#039;0a&#039;, 16)  # hex string to integer&lt;br /&gt;
10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; int(&#039;0xa&#039;, 0)  # hex string to integer auto detected du to &#039;0x&#039;&lt;br /&gt;
10&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Binary ===&lt;br /&gt;
&lt;br /&gt;
Integer to Binary String with Negative Number Support: (2&#039;s complement)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# source: http://www.gossamer-threads.com/lists/python/python/645216&lt;br /&gt;
def bin(x):&lt;br /&gt;
    if x &amp;lt; -32768 or x &amp;gt; 65535:&lt;br /&gt;
        raise Exception(&amp;quot;Out of Range Error: %d&amp;quot; % x)&lt;br /&gt;
    if x &amp;lt; 0:&lt;br /&gt;
        x = 65535 + x + 1&lt;br /&gt;
    bin_str = &#039;&#039;&lt;br /&gt;
    bin_str += &#039;&#039;.join(x &amp;amp; (1 &amp;lt;&amp;lt; i) and &#039;1&#039; or &#039;0&#039; for i in range(15, 11, -1))&lt;br /&gt;
    bin_str += &#039; &#039;&lt;br /&gt;
    bin_str += &#039;&#039;.join(x &amp;amp; (1 &amp;lt;&amp;lt; i) and &#039;1&#039; or &#039;0&#039; for i in range(11, 7, -1))&lt;br /&gt;
    bin_str += &#039; &#039;&lt;br /&gt;
    bin_str += &#039;&#039;.join(x &amp;amp; (1 &amp;lt;&amp;lt; i) and &#039;1&#039; or &#039;0&#039; for i in range(7, 3, -1))&lt;br /&gt;
    bin_str += &#039; &#039;&lt;br /&gt;
    bin_str += &#039;&#039;.join(x &amp;amp; (1 &amp;lt;&amp;lt; i) and &#039;1&#039; or &#039;0&#039; for i in range(3, -1, -1))&lt;br /&gt;
    return bin_str&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Integer to Binary String:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# source: http://www.gossamer-threads.com/lists/python/python/645216&lt;br /&gt;
def bin(x):&lt;br /&gt;
    if x &amp;lt; 0 or x &amp;gt; 65535:&lt;br /&gt;
        raise Exception(&amp;quot;Out of Range Error: %d&amp;quot; % x)&lt;br /&gt;
    bin_str = &#039;&#039;&lt;br /&gt;
    bin_str = &#039;&#039;.join(x &amp;amp; (1 &amp;lt;&amp;lt; i) and &#039;1&#039; or &#039;0&#039; for i in range(15, 7, -1))&lt;br /&gt;
    bin_str = bin_str + &#039; &#039;&lt;br /&gt;
    bin_str = bin_str + &#039;&#039;.join(x &amp;amp; (1 &amp;lt;&amp;lt; i) and &#039;1&#039; or &#039;0&#039; for i in range(7, -1, -1))&lt;br /&gt;
    return bin_str&lt;br /&gt;
&lt;br /&gt;
print bin(0)      # &#039;00000000 00000000&#039;&lt;br /&gt;
print bin(1)      # &#039;00000000 00000001&#039;&lt;br /&gt;
print bin(255)    # &#039;00000000 11111111&#039;&lt;br /&gt;
print bin(256)    # &#039;00000001 00000000&#039;&lt;br /&gt;
print bin(43690)  # &#039;10101010 10101010&#039;&lt;br /&gt;
print bin(65535)  # &#039;11111111 11111111&#039;&lt;br /&gt;
print bin(65536)  # &#039;00000000 00000000&#039; - rolled over to next set!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Integer to Binary:&lt;br /&gt;
 bin(170)  # &#039;0b10101010&#039;&lt;br /&gt;
&lt;br /&gt;
Binary to Integer:&lt;br /&gt;
 int(&#039;10101010&#039;, 2)  # 170&lt;br /&gt;
&lt;br /&gt;
=== bitwise ===&lt;br /&gt;
&lt;br /&gt;
See [[#Binary]]&lt;br /&gt;
&lt;br /&gt;
BitwiseOperators - Python Wiki - http://wiki.python.org/moin/BitwiseOperators&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
The Operators:&lt;br /&gt;
&lt;br /&gt;
x &amp;lt;&amp;lt; y&lt;br /&gt;
    Returns x with the bits shifted to the left by y places (and new bits on the right-hand-side are zeros). This is the same as multiplying x by 2**y. &lt;br /&gt;
x &amp;gt;&amp;gt; y&lt;br /&gt;
    Returns x with the bits shifted to the right by y places. This is the same as //&#039;ing x by 2**y. &lt;br /&gt;
x &amp;amp; y&lt;br /&gt;
    AND - Does a &amp;quot;bitwise and&amp;quot;. Each bit of the output is 1 if the corresponding bit of x AND of y is 1, otherwise it&#039;s 0. &lt;br /&gt;
x | y&lt;br /&gt;
    OR - Does a &amp;quot;bitwise or&amp;quot;. Each bit of the output is 0 if the corresponding bit of x AND of y is 0, otherwise it&#039;s 1. &lt;br /&gt;
~ x&lt;br /&gt;
    Returns the complement of x - the number you get by switching each 1 for a 0 and each 0 for a 1. This is the same as -x - 1. &lt;br /&gt;
x ^ y&lt;br /&gt;
    XOR - Does a &amp;quot;bitwise exclusive or&amp;quot;. Each bit of the output is the same as the corresponding bit in x if that bit in y is 0, and it&#039;s the complement of the bit in x if that bit in y is 1. &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Script Path ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
    # Change directory to where this script lives so we can find relative&lt;br /&gt;
    # paths from here regardless of where the working directory was when we&lt;br /&gt;
    # ran the script.&lt;br /&gt;
    # APP_DIR = os.path.dirname(sys.argv[0])&lt;br /&gt;
    APP_DIR = os.path.dirname(os.path.abspath(sys.argv[0))&lt;br /&gt;
    if APP_DIR:&lt;br /&gt;
        os.chdir(APP_DIR)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 normpath(path)  # Normalize path, eliminating double slashes, etc.&lt;br /&gt;
 abspath(path)   # Return an absolute path&lt;br /&gt;
&lt;br /&gt;
Path to a module: [http://stackoverflow.com/questions/247770/retrieving-python-module-path] (couldn&#039;t fine a_module)&lt;br /&gt;
 import a_module&lt;br /&gt;
 import os&lt;br /&gt;
 path = os.path.dirname(a_module.__file__)&lt;br /&gt;
&lt;br /&gt;
Path to module: [http://stackoverflow.com/questions/50499/in-python-how-do-i-get-the-path-and-name-of-the-file-that-is-currently-executin]&lt;br /&gt;
 import inspect, os&lt;br /&gt;
 print inspect.getfile(inspect.currentframe()) # script filename (usually with path)&lt;br /&gt;
 print os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) # script directory&lt;br /&gt;
&lt;br /&gt;
Even better:&lt;br /&gt;
 print os.path.realpath(__file__)&lt;br /&gt;
 print os.path.dirname(__file__)&lt;br /&gt;
 print os.path.basename(__file__)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
references:&lt;br /&gt;
* http://stackoverflow.com/questions/595305/python-path-of-script&lt;br /&gt;
&lt;br /&gt;
keywords: scriptpath script path program path pathname&lt;br /&gt;
&lt;br /&gt;
=== Singleton ===&lt;br /&gt;
&lt;br /&gt;
GLOBAL OBJECT!&lt;br /&gt;
&lt;br /&gt;
None is a singleton (Python only has one copy of None in the interpreter).&lt;br /&gt;
&lt;br /&gt;
Make your own singleton:&lt;br /&gt;
&lt;br /&gt;
override the new method like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Singleton(object):&lt;br /&gt;
    _instance = None&lt;br /&gt;
    def __new__(cls, *args, **kwargs):&lt;br /&gt;
        if not cls._instance:&lt;br /&gt;
            cls._instance = super(Singleton, cls).__new__(&lt;br /&gt;
                                cls, *args, **kwargs)&lt;br /&gt;
        return cls._instance&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
if __name__ == &#039;__main__&#039;:&lt;br /&gt;
    s1=Singleton()&lt;br /&gt;
    s2=Singleton()&lt;br /&gt;
    if(id(s1)==id(s2)):&lt;br /&gt;
        print &amp;quot;Same&amp;quot;&lt;br /&gt;
    else:&lt;br /&gt;
        print &amp;quot;Different&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Using decorator -implementation from PEP318? Implementing the singleton pattern with a decorator:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def singleton(cls):&lt;br /&gt;
    instances = {}&lt;br /&gt;
    def getinstance():&lt;br /&gt;
        if cls not in instances:&lt;br /&gt;
            instances[cls] = cls()&lt;br /&gt;
        return instances[cls]&lt;br /&gt;
    return getinstance&lt;br /&gt;
&lt;br /&gt;
@singleton&lt;br /&gt;
class MyClass:&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Python and the Singleton Pattern - Stack Overflow - http://stackoverflow.com/questions/42558/python-and-the-singleton-pattern&lt;br /&gt;
&lt;br /&gt;
=== XML ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from xml.dom.minidom import parse, parseString&lt;br /&gt;
&lt;br /&gt;
dom1 = parse(&#039;c:\\temp\\mydata.xml&#039;) # parse an XML file by name&lt;br /&gt;
&lt;br /&gt;
datasource = open(&#039;c:\\temp\\mydata.xml&#039;)&lt;br /&gt;
dom2 = parse(datasource)   # parse an open file&lt;br /&gt;
&lt;br /&gt;
dom3 = parseString(&#039;&amp;lt;myxml&amp;gt;Some data&amp;lt;empty/&amp;gt; some more data&amp;lt;/myxml&amp;gt;&#039;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pretty Print: [http://stackoverflow.com/questions/749796/pretty-printing-xml-in-python]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import xml.dom.minidom&lt;br /&gt;
&lt;br /&gt;
xml = xml.dom.minidom.parse(xml_fname) # or xml.dom.minidom.parseString(xml_string)&lt;br /&gt;
pretty_xml_as_string = xml.toprettyxml()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pretty Print with etree [http://stackoverflow.com/questions/749796/pretty-printing-xml-in-python]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import lxml.etree as etree&lt;br /&gt;
&lt;br /&gt;
x = etree.parse(&amp;quot;filename&amp;quot;)&lt;br /&gt;
print etree.tostring(x, pretty_print = True)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* 19.7. xml.dom.minidom — Lightweight DOM implementation — Python v2.7.3 documentation - http://docs.python.org/library/xml.dom.minidom.html&lt;br /&gt;
* Pretty printing XML in python - Stack Overflow - http://stackoverflow.com/questions/749796/pretty-printing-xml-in-python&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
Simply don&#039;t include self.output.startElement and self.output.endElement for elements you don&#039;t want:&lt;br /&gt;
&lt;br /&gt;
simple_filter_parser.py: (my version of [http://freegeographytools.com/2010/removin-time-data-out-of-a-gpx-or-kml-file-to-make-it-work-right-in-google-earth])&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# this parses out the time element of a gpx for Google Earth&lt;br /&gt;
import os&lt;br /&gt;
import sys&lt;br /&gt;
import optparse&lt;br /&gt;
import fnmatch&lt;br /&gt;
from sys import argv&lt;br /&gt;
import xml.sax, xml.sax.saxutils&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
class my_filter_xml(xml.sax.ContentHandler):&lt;br /&gt;
    def __init__(self, outfile, verbose=False):&lt;br /&gt;
        self.output = xml.sax.saxutils.XMLGenerator(outfile, &#039;utf-8&#039;)&lt;br /&gt;
        self.indent = 0&lt;br /&gt;
        self.ignore = False&lt;br /&gt;
        self.output.startDocument()&lt;br /&gt;
&lt;br /&gt;
    def startElement(self, name, attrs):&lt;br /&gt;
        print &amp;quot; &amp;quot; * self.indent + &amp;quot;start: &amp;quot; + name&lt;br /&gt;
        if attrs.keys():&lt;br /&gt;
            keys = &amp;quot; &amp;quot; * (self.indent + 2) + &amp;quot;attrs:&amp;quot;&lt;br /&gt;
            for key in attrs.keys():&lt;br /&gt;
                keys = keys + &amp;quot; &amp;quot; + key + &amp;quot;=&amp;quot; + attrs[key]&lt;br /&gt;
            print keys&lt;br /&gt;
        self.indent = self.indent + 2&lt;br /&gt;
        #self.output.startElement(name, {})&lt;br /&gt;
        if name == &amp;quot;time&amp;quot;:&lt;br /&gt;
            self.ignore = True&lt;br /&gt;
        #if not self.ignore:&lt;br /&gt;
        self.output.startElement(name, attrs)&lt;br /&gt;
&lt;br /&gt;
    def characters(self, ch):&lt;br /&gt;
        if ch.strip():&lt;br /&gt;
            print &amp;quot; &amp;quot; * self.indent + &amp;quot;ch: &amp;quot; + ch.strip()&lt;br /&gt;
            if not self.ignore:&lt;br /&gt;
                self.output.characters(ch)&lt;br /&gt;
        else:&lt;br /&gt;
            if not self.ignore:&lt;br /&gt;
                self.output.characters(&amp;quot;\n&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    def endElement(self, name):&lt;br /&gt;
        self.indent = self.indent - 2&lt;br /&gt;
        print &amp;quot; &amp;quot; * self.indent + &amp;quot;/end: &amp;quot; + name&lt;br /&gt;
        #if not self.ignore:&lt;br /&gt;
        self.output.endElement(name)&lt;br /&gt;
        if name == &amp;quot;time&amp;quot;:&lt;br /&gt;
            self.ignore = False&lt;br /&gt;
&lt;br /&gt;
if __name__ == &#039;__main__&#039;:&lt;br /&gt;
    source = open(&amp;quot;tracks.gpx&amp;quot;)&lt;br /&gt;
    dest = open(&amp;quot;tracks_out.gpx&amp;quot;, &#039;w+&#039;)&lt;br /&gt;
    xml.sax.parse(source, my_filter_xml(dest, True))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
fixdescriptor.py:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import os&lt;br /&gt;
import sys&lt;br /&gt;
import optparse&lt;br /&gt;
import fnmatch&lt;br /&gt;
from sys import argv&lt;br /&gt;
import xml.sax, xml.sax.saxutils&lt;br /&gt;
&lt;br /&gt;
class fix_descriptor(xml.sax.ContentHandler):&lt;br /&gt;
    def __init__(self, outfile, verbose=False):&lt;br /&gt;
        self._outfile = outfile&lt;br /&gt;
        self._verbose = verbose&lt;br /&gt;
        self.output = xml.sax.saxutils.XMLGenerator(outfile, &#039;utf-8&#039;)&lt;br /&gt;
        self._filter = [ &#039;payload&#039;,&lt;br /&gt;
                         &#039;payloads&#039;,&lt;br /&gt;
                         &#039;file-list&#039;,&lt;br /&gt;
                         &#039;file&#039;,&lt;br /&gt;
                         &#039;checksum&#039; ]&lt;br /&gt;
        self._keep = [ &#039;vib&#039;,&lt;br /&gt;
                       &#039;maintenance-mode&#039; ]&lt;br /&gt;
        self._inside = None&lt;br /&gt;
&lt;br /&gt;
    def startElement(self, name, attrs):&lt;br /&gt;
        # Certain elements are kept unchanged&lt;br /&gt;
        if name in self._keep:&lt;br /&gt;
            if self._verbose:&lt;br /&gt;
                print &#039;%s element start found&#039; % (name)&lt;br /&gt;
            self.output.startElement(name, {})&lt;br /&gt;
            if name == &#039;maintenance-mode&#039;:&lt;br /&gt;
                if self._verbose:&lt;br /&gt;
                    print &#039;inside maintenance-mode&#039;&lt;br /&gt;
                self._inside = name&lt;br /&gt;
            return&lt;br /&gt;
        # Other elements are filtered (removed)&lt;br /&gt;
        elif name in self._filter:&lt;br /&gt;
            if self._verbose:&lt;br /&gt;
                print &#039;%s element start found&#039; % (name)&lt;br /&gt;
            self._inside = name&lt;br /&gt;
            return&lt;br /&gt;
        self.output.startElement(name, attrs)&lt;br /&gt;
&lt;br /&gt;
    def characters(self, ch):&lt;br /&gt;
        if self._inside == &#039;maintenance-mode&#039;:&lt;br /&gt;
            if self._verbose:&lt;br /&gt;
                print &#039;new content for maintenance-mode&#039;&lt;br /&gt;
            self.output.characters(&#039;false&#039;)&lt;br /&gt;
        elif self._inside not in self._filter:&lt;br /&gt;
            self.output.characters(ch)&lt;br /&gt;
&lt;br /&gt;
    def endElement(self, name):&lt;br /&gt;
        # If it&#039;s not a checksum element, only print it&lt;br /&gt;
        if name in self._filter + self._keep:&lt;br /&gt;
            self._inside = None&lt;br /&gt;
            if self._verbose:&lt;br /&gt;
                print &#039;%s element end found&#039; % (name)&lt;br /&gt;
            if name in self._filter:&lt;br /&gt;
                return&lt;br /&gt;
        self.output.endElement(name)&lt;br /&gt;
&lt;br /&gt;
if __name__ == &#039;__main__&#039;:&lt;br /&gt;
    #&lt;br /&gt;
    parser = optparse.OptionParser(usage=&#039;%prog ...&#039;)&lt;br /&gt;
    parser.add_option(&#039;-v&#039;, &#039;--verbose&#039;,&lt;br /&gt;
                       action=&#039;store_true&#039;, default=False,&lt;br /&gt;
                       help=&#039;Print more information.&#039;)&lt;br /&gt;
    parser.add_option(&#039;--input-xml&#039;,&lt;br /&gt;
                       type=&#039;str&#039;, default=&#039;descriptor.xml&#039;,&lt;br /&gt;
                       help=&#039;Name of input XML [default: %default]&#039;)&lt;br /&gt;
    parser.add_option(&#039;--output-xml&#039;,&lt;br /&gt;
                       type=&#039;str&#039;, default=&#039;fixed_descriptor.xml&#039;,&lt;br /&gt;
                       help=&#039;Name of output XML [default: %default]&#039;)&lt;br /&gt;
    opts, args = parser.parse_args(argv[1:])&lt;br /&gt;
    source = open(opts.input_xml)&lt;br /&gt;
    dest = open(opts.output_xml, &#039;w+&#039;)&lt;br /&gt;
    xml.sax.parse(source, fix_descriptor(dest, opts.verbose))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--&lt;br /&gt;
&lt;br /&gt;
Simple read and output parsing:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import os&lt;br /&gt;
import sys&lt;br /&gt;
import optparse&lt;br /&gt;
import fnmatch&lt;br /&gt;
from sys import argv&lt;br /&gt;
import xml.sax, xml.sax.saxutils&lt;br /&gt;
&lt;br /&gt;
class fix_descriptor(xml.sax.ContentHandler):&lt;br /&gt;
    def __init__(self, outfile, verbose=False):&lt;br /&gt;
        self._outfile = outfile&lt;br /&gt;
        self._verbose = verbose&lt;br /&gt;
        self.output = xml.sax.saxutils.XMLGenerator(outfile, &#039;utf-8&#039;)&lt;br /&gt;
        self._inside = None&lt;br /&gt;
&lt;br /&gt;
    def startElement(self, name, attrs):&lt;br /&gt;
        # attrs.items() is a list of tuples (name, value)&lt;br /&gt;
        print &amp;quot;start:&amp;quot;, name, &amp;quot;/&amp;quot;, attrs.items()&lt;br /&gt;
        self.output.startElement(name, attrs)&lt;br /&gt;
&lt;br /&gt;
    def characters(self, ch):&lt;br /&gt;
        print &amp;quot;char:&amp;quot;, self._inside, &amp;quot;/&amp;quot;, ch&lt;br /&gt;
        self.output.characters(ch)&lt;br /&gt;
&lt;br /&gt;
    def endElement(self, name):&lt;br /&gt;
        print &amp;quot;end:&amp;quot;, name&lt;br /&gt;
        self.output.endElement(name)&lt;br /&gt;
&lt;br /&gt;
if __name__ == &#039;__main__&#039;:&lt;br /&gt;
    parser = optparse.OptionParser(usage=&#039;%prog ...&#039;)&lt;br /&gt;
    parser.add_option(&#039;-v&#039;, &#039;--verbose&#039;,&lt;br /&gt;
                       action=&#039;store_true&#039;, default=False,&lt;br /&gt;
                       help=&#039;Print more information.&#039;)&lt;br /&gt;
    parser.add_option(&#039;--input-xml&#039;,&lt;br /&gt;
                       type=&#039;str&#039;, default=&#039;descriptor.xml&#039;,&lt;br /&gt;
                       help=&#039;Name of input XML [default: %default]&#039;)&lt;br /&gt;
    parser.add_option(&#039;--output-xml&#039;,&lt;br /&gt;
                       type=&#039;str&#039;, default=&#039;fixed_descriptor.xml&#039;,&lt;br /&gt;
                       help=&#039;Name of output XML [default: %default]&#039;)&lt;br /&gt;
    opts, args = parser.parse_args(argv[1:])&lt;br /&gt;
    source = open(opts.input_xml)&lt;br /&gt;
    dest = open(opts.output_xml, &#039;w+&#039;)&lt;br /&gt;
    xml.sax.parse(source, fix_descriptor(dest, opts.verbose))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Unicode ===&lt;br /&gt;
&lt;br /&gt;
Unicode string:&lt;br /&gt;
 u&#039;Hello World !&#039;&lt;br /&gt;
&lt;br /&gt;
Raw Unicode string:&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; ur&#039;Hello\u0020World !&#039;&lt;br /&gt;
 u&#039;Hello World !&#039;&lt;br /&gt;
&lt;br /&gt;
Convert:&lt;br /&gt;
 u = u&#039;hello\xe4&#039;&lt;br /&gt;
 str(u)  # UnicodeEncodeError: &#039;ascii&#039; codec can&#039;t encode character u&#039;\xe4&#039; in position 5: ordinal not in range(128)&lt;br /&gt;
 s = u.encode(&#039;utf8&#039;)  # &#039;s&#039; is now type str&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* Introduction to Unicode Strings - http://docs.python.org/tutorial/introduction.html#unicode-strings&lt;br /&gt;
&lt;br /&gt;
=== Zip ===&lt;br /&gt;
&lt;br /&gt;
See [[Python/Zip]]&lt;br /&gt;
&lt;br /&gt;
=== signals ===&lt;br /&gt;
&lt;br /&gt;
 signal.SIGTERM  : kill  [pid]&lt;br /&gt;
 signal.SIGALRM  : kill -ALRM  [pid]&lt;br /&gt;
 signal.SIGHUP   : kill -HUP  [pid]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import signal, os&lt;br /&gt;
&lt;br /&gt;
def handler(signum, frame):&lt;br /&gt;
    print &#039;Signal handler called with signal&#039;, signum&lt;br /&gt;
    raise IOError(&amp;quot;Couldn&#039;t open device!&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
# Set the signal handler and a 5-second alarm&lt;br /&gt;
signal.signal(signal.SIGALRM, handler)&lt;br /&gt;
signal.alarm(5)&lt;br /&gt;
&lt;br /&gt;
# This open() may hang indefinitely&lt;br /&gt;
fd = os.open(&#039;/dev/ttyS0&#039;, os.O_RDWR)&lt;br /&gt;
&lt;br /&gt;
signal.alarm(0)          # Disable the alarm&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: use signal.SIGTERM to handle &amp;quot;kill&amp;quot; command&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* 17.4. signal — Set handlers for asynchronous events — Python v2.7.5 documentation - http://docs.python.org/2/library/signal.html&lt;br /&gt;
&lt;br /&gt;
==== Ctrl+C ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
import signal&lt;br /&gt;
import sys&lt;br /&gt;
def signal_handler(signal, frame):&lt;br /&gt;
        print &#039;You pressed Ctrl+C!&#039;&lt;br /&gt;
        sys.exit(0)&lt;br /&gt;
signal.signal(signal.SIGINT, signal_handler)&lt;br /&gt;
print &#039;Press Ctrl+C&#039;&lt;br /&gt;
&lt;br /&gt;
# linux only:&lt;br /&gt;
signal.pause()&lt;br /&gt;
&lt;br /&gt;
# windows alternative:&lt;br /&gt;
#import time&lt;br /&gt;
#time.sleep(60)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* control - How do I capture SIGINT in Python? - Stack Overflow - http://stackoverflow.com/questions/1112343/how-do-i-capture-sigint-in-python&lt;br /&gt;
&lt;br /&gt;
==== Non-blocking raw_input for Python ====&lt;br /&gt;
&lt;br /&gt;
Non-blocking raw_input for Python:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# source: http://www.garyrobinson.net/2009/10/non-blocking-raw_input-for-python.html&lt;br /&gt;
&lt;br /&gt;
import signal&lt;br /&gt;
&lt;br /&gt;
class AlarmException(Exception):&lt;br /&gt;
    pass&lt;br /&gt;
&lt;br /&gt;
def alarmHandler(signum, frame):&lt;br /&gt;
    raise AlarmException&lt;br /&gt;
&lt;br /&gt;
def nonBlockingRawInput(prompt=&#039;&#039;, timeout=20):&lt;br /&gt;
    signal.signal(signal.SIGALRM, alarmHandler)&lt;br /&gt;
    signal.alarm(timeout)&lt;br /&gt;
    try:&lt;br /&gt;
        text = raw_input(prompt)&lt;br /&gt;
        signal.alarm(0)&lt;br /&gt;
        return text&lt;br /&gt;
    except AlarmException:&lt;br /&gt;
        print &#039;\nPrompt timeout. Continuing...&#039;&lt;br /&gt;
    signal.signal(signal.SIGALRM, signal.SIG_IGN)&lt;br /&gt;
    return &#039;&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== email ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import smtplib&lt;br /&gt;
import email.mime.text&lt;br /&gt;
&lt;br /&gt;
msg_text = &amp;quot;Hello World&amp;quot;&lt;br /&gt;
msg = email.mime.text.MIMEText(msg_text)&lt;br /&gt;
&lt;br /&gt;
# me == the sender&#039;s email address&lt;br /&gt;
# you == the recipient&#039;s email address&lt;br /&gt;
msg[&#039;Subject&#039;] = &#039;The contents of %s&#039; % textfile&lt;br /&gt;
msg[&#039;From&#039;] = me&lt;br /&gt;
msg[&#039;To&#039;] = you&lt;br /&gt;
&lt;br /&gt;
# Send the message via our own SMTP server, but don&#039;t include the&lt;br /&gt;
# envelope header.&lt;br /&gt;
s = smtplib.SMTP(&#039;localhost&#039;)&lt;br /&gt;
s.sendmail(me, [you], msg.as_string())&lt;br /&gt;
s.quit()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
my nagios fake /bin/mail:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
&lt;br /&gt;
import smtplib&lt;br /&gt;
import email.mime.text&lt;br /&gt;
import optparse&lt;br /&gt;
import os&lt;br /&gt;
import sys&lt;br /&gt;
import pwd&lt;br /&gt;
&lt;br /&gt;
os.system(&#039;logger mail called&#039;)&lt;br /&gt;
&lt;br /&gt;
parser = optparse.OptionParser()&lt;br /&gt;
parser.add_option(&lt;br /&gt;
    &#039;-s&#039;, &#039;--subject&#039;,&lt;br /&gt;
    help=&#039;Subject&#039;,&lt;br /&gt;
    default=&amp;quot;&amp;quot;)&lt;br /&gt;
parser.add_option(&lt;br /&gt;
    &#039;-t&#039;, &#039;--to&#039;,&lt;br /&gt;
    help=&#039;To&#039;,&lt;br /&gt;
    dest=&amp;quot;send_to&amp;quot;,&lt;br /&gt;
    default=None)&lt;br /&gt;
parser.add_option(&lt;br /&gt;
    &#039;-f&#039;, &#039;--from&#039;,&lt;br /&gt;
    help=&#039;From&#039;,&lt;br /&gt;
    dest=&amp;quot;send_from&amp;quot;,&lt;br /&gt;
    default=None)&lt;br /&gt;
parser.add_option(&lt;br /&gt;
    &#039;-S&#039;, &#039;--server&#039;,&lt;br /&gt;
    help=&#039;server&#039;,&lt;br /&gt;
    default=&amp;quot;prime&amp;quot;)&lt;br /&gt;
(options, args) = parser.parse_args()&lt;br /&gt;
&lt;br /&gt;
def get_username():&lt;br /&gt;
    return pwd.getpwuid( os.getuid() )[ 0 ]&lt;br /&gt;
&lt;br /&gt;
if options.send_to:&lt;br /&gt;
    send_to = options.send_to&lt;br /&gt;
else:&lt;br /&gt;
    if len(args) == 1:&lt;br /&gt;
        send_to = args[0]&lt;br /&gt;
    else:&lt;br /&gt;
        parser.print_help()&lt;br /&gt;
        sys.exit(1)&lt;br /&gt;
&lt;br /&gt;
if options.send_from:&lt;br /&gt;
    send_from = options.send_from&lt;br /&gt;
else:&lt;br /&gt;
    username = get_username()&lt;br /&gt;
    hostname = os.uname()[1]&lt;br /&gt;
    send_from = username + &amp;quot;@&amp;quot; + hostname&lt;br /&gt;
&lt;br /&gt;
msg_text = sys.stdin.read()&lt;br /&gt;
msg = email.mime.text.MIMEText(msg_text)&lt;br /&gt;
&lt;br /&gt;
msg[&#039;Subject&#039;] = options.subject&lt;br /&gt;
msg[&#039;From&#039;] = send_from&lt;br /&gt;
msg[&#039;To&#039;] = send_to&lt;br /&gt;
&lt;br /&gt;
s = smtplib.SMTP(options.server)&lt;br /&gt;
s.sendmail(send_from, [send_to], msg.as_string())&lt;br /&gt;
s.quit()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Authenticated (with gmail):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import smtplib&lt;br /&gt;
import email.mime.text&lt;br /&gt;
&lt;br /&gt;
# from_email = &amp;quot;kenneth@demo.oeey.com&amp;quot;&lt;br /&gt;
# to_email = &amp;quot;kenneth@demo.oeey.com&amp;quot;&lt;br /&gt;
from_email = &amp;quot;Kenneth Burgener &amp;lt;kenneth@demo.oeey.com&amp;gt;&amp;quot;&lt;br /&gt;
to_emails = [&amp;quot;Kenneth Burgener &amp;lt;kenneth@demo.oeey.com&amp;gt;&amp;quot;, &amp;quot;Kenneth Cell &amp;lt;xxx@xxx.com&amp;gt;&amp;quot;]&lt;br /&gt;
&lt;br /&gt;
msg_text = &amp;quot;hello world&amp;quot;&lt;br /&gt;
msg = email.mime.text.MIMEText(msg_text)&lt;br /&gt;
msg[&#039;Subject&#039;] = &#039;Test text&#039;&lt;br /&gt;
msg[&#039;From&#039;] = from_email&lt;br /&gt;
# msg[&#039;To&#039;] = to_email&lt;br /&gt;
msg[&#039;To&#039;] = &amp;quot;, &amp;quot;.join(to_emails)&lt;br /&gt;
# s = smtplib.SMTP(&#039;localhost&#039;)&lt;br /&gt;
print &amp;quot;sending...&amp;quot;&lt;br /&gt;
s = smtplib.SMTP_SSL(&#039;smtp.gmail.com&#039;, &#039;465&#039;)&lt;br /&gt;
s.login(&#039;xxx&#039;, &#039;xxx&#039;)&lt;br /&gt;
# s.sendmail(from_email, [to_email], msg.as_string())&lt;br /&gt;
s.sendmail(from_email, to_emails, msg.as_string())&lt;br /&gt;
s.quit()&lt;br /&gt;
print &amp;quot;sent!&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Source: &lt;br /&gt;
* 20.12. smtplib — SMTP protocol client — Python v2.7.5 documentation - http://docs.python.org/2/library/smtplib.html&lt;br /&gt;
* 18.1.11. email: Examples — Python v2.7.5 documentation - http://docs.python.org/2/library/email-examples.html&lt;br /&gt;
&lt;br /&gt;
=== pprint ===&lt;br /&gt;
&lt;br /&gt;
8.18. pprint — Data pretty printer — Python v2.7.5 documentation - http://docs.python.org/2/library/pprint.html&lt;br /&gt;
&lt;br /&gt;
 import pprint&lt;br /&gt;
 pprint.pprint(myVar)&lt;br /&gt;
&lt;br /&gt;
 import pprint&lt;br /&gt;
 pp = pprint.PrettyPrinter(indent=4)&lt;br /&gt;
 pp.pprint(myVar)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Note: Useless on objects!&lt;br /&gt;
&lt;br /&gt;
Dump object:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def dumpobject(obj):&lt;br /&gt;
    print &amp;quot;&amp;lt;&amp;lt;&amp;lt;---&amp;quot;&lt;br /&gt;
    print type(obj), obj.__class__.__name__&lt;br /&gt;
    for attr in dir(obj):&lt;br /&gt;
        if attr[0] == &amp;quot;_&amp;quot;: continue  # ignore under/dunder properties&lt;br /&gt;
        if str(type(getattr(obj, attr))) == &amp;quot;&amp;lt;type &#039;instancemethod&#039;&amp;gt;&amp;quot;:&lt;br /&gt;
            print attr, &amp;quot;: METHOD&amp;quot;&lt;br /&gt;
        else:&lt;br /&gt;
            print attr, &amp;quot;:&amp;quot;, type(getattr(obj, attr)), &amp;quot;:&amp;quot;, getattr(obj, attr)&lt;br /&gt;
    print &amp;quot;END ---&amp;gt;&amp;gt;&amp;gt;&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Curses ===&lt;br /&gt;
&lt;br /&gt;
Curses Programming with Python — Python v3.3.2 documentation - http://docs.python.org/3/howto/curses.html&lt;br /&gt;
&lt;br /&gt;
&amp;quot;The curses library supplies a terminal-independent screen-painting and keyboard-handling facility for text-based terminals; such terminals include VT100s, the Linux console, and the simulated terminal provided by various programs. Display terminals support various control codes to perform common operations such as moving the cursor, scrolling the screen, and erasing areas. Different terminals use widely differing codes, and often have their own minor quirks.&lt;br /&gt;
&lt;br /&gt;
In a world of graphical displays, one might ask “why bother”? It’s true that character-cell display terminals are an obsolete technology, but there are niches in which being able to do fancy things with them are still valuable. One niche is on small-footprint or embedded Unixes that don’t run an X server. Another is tools such as OS installers and kernel configurators that may have to run before any graphical support is available.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
Thread from Utah Python User&#039;s Group mailing list:&lt;br /&gt;
&lt;br /&gt;
-&lt;br /&gt;
&lt;br /&gt;
Hello, I am trying to learn more about curses in python for a desktop application. Does anybody have any recommendations on tutorials or documentation? &lt;br /&gt;
&lt;br /&gt;
-Corban&lt;br /&gt;
&lt;br /&gt;
-&lt;br /&gt;
&lt;br /&gt;
We&#039;ve use urwid at work. Seems to be a good approach if you aren&#039;t already tied to something. Learning curve can be a bit steep (well, compared to what you&#039;d think it should be). Good luck!&lt;br /&gt;
&lt;br /&gt;
 http://excess.org/urwid/&lt;br /&gt;
&lt;br /&gt;
Gabriel Gunderson&lt;br /&gt;
&lt;br /&gt;
-&lt;br /&gt;
&lt;br /&gt;
This video series looks pretty good:&lt;br /&gt;
&lt;br /&gt;
http://www.youtube.com/user/pythoncursestutorial?feature=watch&lt;br /&gt;
&lt;br /&gt;
Official HOWTOs from the python.org site:&lt;br /&gt;
&lt;br /&gt;
http://docs.python.org/2/howto/curses.html&lt;br /&gt;
http://docs.python.org/3/howto/curses.html&lt;br /&gt;
&lt;br /&gt;
As Gabe mentioned, there are other libraries that provide similar or&lt;br /&gt;
greater functionality, so if you aren&#039;t doing this specifically to&lt;br /&gt;
learn curses, it&#039;s worth at least looking at a few of them to compare.&lt;br /&gt;
&lt;br /&gt;
There&#039;s a brief comparison of three possibilities here:&lt;br /&gt;
&lt;br /&gt;
http://stackoverflow.com/questions/8349085/python-ncurses-cdk-urwid-difference&lt;br /&gt;
&lt;br /&gt;
Daniel Fackrell&lt;br /&gt;
&lt;br /&gt;
-&lt;br /&gt;
&lt;br /&gt;
Here&#039;s another option that looks promising:&lt;br /&gt;
&lt;br /&gt;
https://pypi.python.org/pypi/blessings/&lt;br /&gt;
&lt;br /&gt;
Daniel Fackrell&lt;br /&gt;
&lt;br /&gt;
=== dialog ===&lt;br /&gt;
&lt;br /&gt;
pythondialog - http://pythondialog.sourceforge.net/&lt;br /&gt;
: &amp;quot;pythondialog is a Python wrapper for the dialog utility originally written by Savio Lam, and later rewritten by Thomas E. Dickey. Its purpose is to provide an easy to use, pythonic and comprehensive Python interface to dialog. This allows one to make simple text-mode user interfaces on Unix-like systems (including Linux). &amp;quot;&lt;br /&gt;
&lt;br /&gt;
Note: The latest versions (2.12 and later) only support Python 3; users who really want to stick to Python 2 should use version 2.11 for now.&lt;br /&gt;
&lt;br /&gt;
Install:&lt;br /&gt;
 # latest:&lt;br /&gt;
 # wget http://sourceforge.net/projects/pythondialog/files/latest/download?source=dlp&lt;br /&gt;
&lt;br /&gt;
 wget http://sourceforge.net/projects/pythondialog/files/pythondialog/2.11/python2-pythondialog-2.11.tar.gz/download&lt;br /&gt;
 tar -zvxf python2-pythondialog-2.11.tar.gz&lt;br /&gt;
 cd pythondialog-2.11&lt;br /&gt;
&lt;br /&gt;
 import dialog&lt;br /&gt;
 d = dialog.Dialog()&lt;br /&gt;
 if d.yesno(&amp;quot;Continue?&amp;quot;) == d.DIALOG_OK:&lt;br /&gt;
  print &amp;quot;Continuing...&amp;quot;&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
My solution&lt;br /&gt;
&lt;br /&gt;
kiloforce / dialog / source / — Bitbucket - https://bitbucket.org/kiloforce/dialog&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot; Wrapper for Linux &#039;dialog&#039; command &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
__author__ = &amp;quot;Kenneth Burgener &amp;lt;kenneth@k.ttak.org&amp;gt;&amp;quot;&lt;br /&gt;
__copyright__ = &amp;quot;(c) 2013&amp;quot;&lt;br /&gt;
__date__ = &amp;quot;$Sep 27, 2013$&amp;quot;&lt;br /&gt;
__version__ = &amp;quot;1.0&amp;quot;&lt;br /&gt;
__credits__ = r&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
XXXXXXXXXXXXXXXXXX&lt;br /&gt;
X Dialog Wrapper #&lt;br /&gt;
##################&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
import subprocess&lt;br /&gt;
import time&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
class Dialog():&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot; Python wrapper for Linux &#039;dialog&#039; command&lt;br /&gt;
&lt;br /&gt;
    dialog - display dialog boxes from shell scripts&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import dialog&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dlg = dialog.Dialog()&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; rc = dlg.msgbox(&#039;hello world&#039;)&lt;br /&gt;
&lt;br /&gt;
    Return codes:&lt;br /&gt;
        YES = 0&lt;br /&gt;
        OK = 0&lt;br /&gt;
        EXIT = 0&lt;br /&gt;
        NO = 1&lt;br /&gt;
        CANCEL = 1&lt;br /&gt;
        ESC = 255&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    YES = 0&lt;br /&gt;
    OK = 0&lt;br /&gt;
    EXIT = 0&lt;br /&gt;
    NO = 1&lt;br /&gt;
    CANCEL = 1&lt;br /&gt;
    ESC = 255&lt;br /&gt;
&lt;br /&gt;
    def __init__(self):&lt;br /&gt;
        rc = self._exe(&#039;which dialog &amp;gt; /dev/null&#039;)[0]&lt;br /&gt;
        if rc != 0:&lt;br /&gt;
            print &amp;quot;Error: failed to find Linux dialog command&amp;quot;&lt;br /&gt;
            sys.exit(1)&lt;br /&gt;
&lt;br /&gt;
    def _exe(self, cmd, strip=True):&lt;br /&gt;
        p = subprocess.Popen(cmd, shell=True, stderr=subprocess.PIPE)&lt;br /&gt;
        output = &amp;quot;\n&amp;quot;.join(p.stderr.readlines())&lt;br /&gt;
        if strip:&lt;br /&gt;
            output = output.strip()&lt;br /&gt;
        rc = p.wait()&lt;br /&gt;
        return (rc, output)&lt;br /&gt;
&lt;br /&gt;
    def rc_to_str(self, rc):&lt;br /&gt;
        if rc == 0:&lt;br /&gt;
            return &amp;quot;YES&amp;quot;&lt;br /&gt;
        elif rc == 1:&lt;br /&gt;
            return &amp;quot;NO&amp;quot;&lt;br /&gt;
        elif rc == 255:&lt;br /&gt;
            return &amp;quot;ESX&amp;quot;&lt;br /&gt;
        else:&lt;br /&gt;
            raise Exception(&amp;quot;Unknown return code: %s&amp;quot; % rc)&lt;br /&gt;
&lt;br /&gt;
    def clear(self):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Clear screen&lt;br /&gt;
&lt;br /&gt;
        Example:&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt; dialog.clear()&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        rc, output = self._exe(&#039;clear&#039;)&lt;br /&gt;
        assert rc in (0,), &amp;quot;clear rc&amp;quot;&lt;br /&gt;
        return rc&lt;br /&gt;
&lt;br /&gt;
    def msgbox(self, msg):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Simple message box&lt;br /&gt;
&lt;br /&gt;
        @param msg (str) = display message&lt;br /&gt;
        @return: rc (int)&lt;br /&gt;
&lt;br /&gt;
        Example:&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt; rc = dialog.msgbox(&#039;hello world&#039;)&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        rc, output = self._exe(&#039;dialog --msgbox &amp;quot;{msg}&amp;quot; 0 0&#039;.format(msg=msg))&lt;br /&gt;
        assert rc in (self.YES, self.ESC), &amp;quot;msgbox rc&amp;quot;&lt;br /&gt;
        return rc&lt;br /&gt;
&lt;br /&gt;
    def yesno(self, msg):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Yes/No dialog&lt;br /&gt;
&lt;br /&gt;
        @param msg (str) = display message&lt;br /&gt;
        @return: rc (int)&lt;br /&gt;
&lt;br /&gt;
        Example:&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt; rc = dialog.yesno(&#039;continue&#039;)&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        rc, output = self._exe(&#039;dialog --yesno &amp;quot;{msg}&amp;quot; 0 0&#039;.format(msg=msg))&lt;br /&gt;
        assert rc in (self.YES, self.NO, self.ESC), &amp;quot;yesno rc&amp;quot;&lt;br /&gt;
        return rc&lt;br /&gt;
&lt;br /&gt;
    def infobox(self, msg):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Dialog that does not wait for user&#039;s response&lt;br /&gt;
        (do your own pause)&lt;br /&gt;
&lt;br /&gt;
        @param msg (str) = display message&lt;br /&gt;
        @return: rc (int) always zero&lt;br /&gt;
&lt;br /&gt;
        Example:&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt; for i in range(10):&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt;   dialog.infobox(&#039;counting: &#039; + str(i))&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt;   time.sleep(3)&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        rc, output = self._exe(&#039;dialog --infobox &amp;quot;{msg}&amp;quot; 0 0&#039;.format(msg=msg))&lt;br /&gt;
        assert rc in (self.YES,), &amp;quot;infobox rc&amp;quot;&lt;br /&gt;
        return rc&lt;br /&gt;
&lt;br /&gt;
    def inputbox(self, msg):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Get user input&lt;br /&gt;
&lt;br /&gt;
        @param msg (str) = display message&lt;br /&gt;
        @return: rc (int), output (str/None)&lt;br /&gt;
&lt;br /&gt;
        Example:&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt; rc, output = dialog.inputbox(&#039;name:&#039;)&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        rc, output = self._exe(&#039;dialog --inputbox &amp;quot;{msg}&amp;quot; 0 0&#039;.format(msg=msg))&lt;br /&gt;
        assert rc in (self.YES, self.NO, self.ESC), &amp;quot;inputbox rc&amp;quot;&lt;br /&gt;
        if not output:&lt;br /&gt;
            output = None&lt;br /&gt;
        return rc, output&lt;br /&gt;
&lt;br /&gt;
    def textbox(self, filename):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Display a file&lt;br /&gt;
&lt;br /&gt;
        @param filename (str) = file to display&lt;br /&gt;
        @return: rc (int)&lt;br /&gt;
&lt;br /&gt;
        Example:&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt; dialog.textbox(&#039;/etc/passwd&#039;)&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        rc, output = self._exe(&#039;dialog --textbox {filename} 0 0&#039;.format(filename=filename))&lt;br /&gt;
        assert rc in (self.YES, self.ESC), &amp;quot;textbox rc&amp;quot;&lt;br /&gt;
        return rc&lt;br /&gt;
&lt;br /&gt;
    def menu(self, msg, item_list):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Single selection checkbox menu&lt;br /&gt;
&lt;br /&gt;
        @param msg (str) = display message&lt;br /&gt;
        @param item_list (str list) = list of items to display&lt;br /&gt;
        @return: rc (int), selection (int/None)&lt;br /&gt;
&lt;br /&gt;
        Example:&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt; rc, selection = dialog.menu(&#039;Select multiple options:&#039;,&lt;br /&gt;
        ...     (&#039;option 1&#039;, &#039;option 2&#039;))&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        item_str = &amp;quot;&amp;quot;&lt;br /&gt;
        for i in range(len(item_list)):&lt;br /&gt;
            item_str += &amp;quot; &amp;quot; + str(i+1) + &amp;quot; \&amp;quot;&amp;quot; + item_list[i] + &amp;quot;\&amp;quot;&amp;quot;&lt;br /&gt;
        rc, output = self._exe(&#039;dialog --menu &amp;quot;{msg}&amp;quot; 0 0 0 {item_str}&#039;.format(msg=msg, item_str=item_str))&lt;br /&gt;
        if output:&lt;br /&gt;
            selection = int(output)&lt;br /&gt;
        else:&lt;br /&gt;
            selection = None&lt;br /&gt;
        assert rc in (self.YES, self.NO, self.ESC), &amp;quot;menu rc&amp;quot;&lt;br /&gt;
        return rc, selection&lt;br /&gt;
&lt;br /&gt;
    def checklist(self, msg, item_list, checked_list=None):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Multiple selection checkbox menu&lt;br /&gt;
&lt;br /&gt;
        @param msg (str) = display message&lt;br /&gt;
        @param item_list (str list) = list of items&lt;br /&gt;
        @param checked_list (int list) = default items to check&lt;br /&gt;
        @return: rc (int), selections (int list/None)&lt;br /&gt;
&lt;br /&gt;
        Example:&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt; rc, selections = dialog.checklist(&#039;Select multiple options:&#039;,&lt;br /&gt;
        ...     (&#039;option 1&#039;, &#039;option 2&#039;)&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        item_str = &amp;quot;&amp;quot;&lt;br /&gt;
        assert type(item_list) in (type(None), type(()), type([])), &amp;quot;checklist: item_list must be a list&amp;quot;&lt;br /&gt;
        assert type(checked_list) in (type(None), type(()), type([])), &amp;quot;checklist: checked_list must be a list&amp;quot;&lt;br /&gt;
        for i in range(len(item_list)):&lt;br /&gt;
            item_str += &amp;quot; &amp;quot; + str(i+1) + &amp;quot; \&amp;quot;&amp;quot; + item_list[i] + &amp;quot;\&amp;quot;&amp;quot;&lt;br /&gt;
            if checked_list and i+1 in checked_list:&lt;br /&gt;
                item_str += &amp;quot; on&amp;quot;&lt;br /&gt;
            else:&lt;br /&gt;
                item_str += &amp;quot; off&amp;quot;&lt;br /&gt;
        rc, output = self._exe(&#039;dialog --checklist &amp;quot;{msg}&amp;quot; 0 0 0 {item_str}&#039;.format(msg=msg, item_str=item_str))&lt;br /&gt;
        print item_str&lt;br /&gt;
        selections = []&lt;br /&gt;
        for choice in output.split(&#039;&amp;quot;&#039;):&lt;br /&gt;
            if choice.strip():&lt;br /&gt;
                selections.append(int(choice))&lt;br /&gt;
        if selections:&lt;br /&gt;
            selections = tuple(selections)&lt;br /&gt;
        else:&lt;br /&gt;
            selections = None&lt;br /&gt;
        assert rc in (self.YES, self.NO, self.ESC), &amp;quot;checklist rc&amp;quot;&lt;br /&gt;
        return rc, selections&lt;br /&gt;
&lt;br /&gt;
    def radiolist(self, msg, item_list, checked_item=None):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Single selection radio menu, with default&lt;br /&gt;
&lt;br /&gt;
        @param msg (str) = display message&lt;br /&gt;
        @param item_list (str list) = list of items&lt;br /&gt;
        @param checked_item (int) = default item to select&lt;br /&gt;
        @return: rc (int), selection (int)&lt;br /&gt;
&lt;br /&gt;
        Example:&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt; rc, selection = dialog.radiolist(&#039;Select one option:&#039;,&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt;     (&#039;option 1&#039;, &#039;option 2&#039;), 2)&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        item_str = &amp;quot;&amp;quot;&lt;br /&gt;
        for i in range(len(item_list)):&lt;br /&gt;
            item_str += &amp;quot; &amp;quot; + str(i+1) + &amp;quot; \&amp;quot;&amp;quot; + item_list[i] + &amp;quot;\&amp;quot;&amp;quot;&lt;br /&gt;
            if checked_item and i+1 == int(checked_item):&lt;br /&gt;
                item_str += &amp;quot; on&amp;quot;&lt;br /&gt;
            else:&lt;br /&gt;
                item_str += &amp;quot; off&amp;quot;&lt;br /&gt;
        rc, selection = self._exe(&#039;dialog --radiolist &amp;quot;{msg}&amp;quot; 0 0 0 {item_str}&#039;.format(msg=msg, item_str=item_str))&lt;br /&gt;
        if not selection:&lt;br /&gt;
            selection = None&lt;br /&gt;
        assert rc in (self.YES, self.NO, self.ESC), &amp;quot;radiolist rc&amp;quot;&lt;br /&gt;
        return rc, selection&lt;br /&gt;
&lt;br /&gt;
    def gauge(self, msg, percent):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Progress bar (does not wait for user&#039;s input)&lt;br /&gt;
&lt;br /&gt;
        @param msg (str) = display message&lt;br /&gt;
        @param percent (int) = progress&lt;br /&gt;
        @return: rc (int) always zero&lt;br /&gt;
&lt;br /&gt;
        Example:&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt; for i in range(0, 100+1, 2):&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt;   dialog.gauge(&#039;Progress:&#039;, i)&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt;   time.sleep(.1)&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        rc, output = self._exe(&#039;echo {percent} | dialog --gauge &amp;quot;{msg}&amp;quot; 0 0&#039;.format(percent=percent, msg=msg))&lt;br /&gt;
        assert rc in (self.YES,), &amp;quot;guage rc&amp;quot;&lt;br /&gt;
        return rc&lt;br /&gt;
&lt;br /&gt;
    def progress(self, msg, percent):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Alias for self.guage()&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        return self.gauge(msg=msg, percent=percent)&lt;br /&gt;
&lt;br /&gt;
    def form(self, msg, item_list):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Multiple item entry form&lt;br /&gt;
&lt;br /&gt;
        @param msg (str) = display message&lt;br /&gt;
        @param item_list (str list) = list of items&lt;br /&gt;
        @return: rc (int), answers (str list)&lt;br /&gt;
&lt;br /&gt;
        Example:&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt; rc, answers = dialog.form(&#039;Enter details&#039;,&lt;br /&gt;
        ...     (&#039;first name&#039;, &#039;last name&#039;))&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        item_str = &amp;quot;&amp;quot;&lt;br /&gt;
        name_len = 1&lt;br /&gt;
        for i in range(len(item_list)):&lt;br /&gt;
            if len(item_list[i])+3 &amp;gt; name_len:&lt;br /&gt;
                name_len = len(item_list[i])+3&lt;br /&gt;
        for i in range(len(item_list)):&lt;br /&gt;
            item_str += &amp;quot; \&amp;quot;&amp;quot; + item_list[i] + &amp;quot;:\&amp;quot; &amp;quot; + str(i+1) + &amp;quot; 1 \&amp;quot;\&amp;quot; &amp;quot; + str(i+1) +\&lt;br /&gt;
                &amp;quot; &amp;quot; + str(name_len) + &amp;quot; 40 0&amp;quot;&lt;br /&gt;
        rc, answers = self._exe(&#039;dialog --form &amp;quot;{msg}&amp;quot; 0 0 0 {item_str}&#039;.format(msg=msg, item_str=item_str),&lt;br /&gt;
                                strip=False)&lt;br /&gt;
        answers = answers.split(&#039;\n\n&#039;)&lt;br /&gt;
        if not answers:&lt;br /&gt;
            answers = None&lt;br /&gt;
        assert rc in (self.YES, self.NO, self.ESC), &amp;quot;form rc&amp;quot;&lt;br /&gt;
        return rc, answers&lt;br /&gt;
&lt;br /&gt;
    def test(self):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Test features&lt;br /&gt;
&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt; import dialog&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt; dlg = dialog.Dialog()&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt; dlg.test()&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
        def wait_user(msg):&lt;br /&gt;
            self.msgbox(&amp;quot;%s&amp;quot; % msg)&lt;br /&gt;
&lt;br /&gt;
        # rc_to_str&lt;br /&gt;
        wait_user(&amp;quot;Testing return code...&amp;quot;)&lt;br /&gt;
        print self.rc_to_str(self.YES)  # YES&lt;br /&gt;
        print self.rc_to_str(self.NO)  # NO&lt;br /&gt;
        print self.rc_to_str(self.ESC)  # ESX&lt;br /&gt;
        try:&lt;br /&gt;
            print self.rc_to_str(111)  # exception&lt;br /&gt;
            raise Exception(&amp;quot;Did not throw exception&amp;quot;)&lt;br /&gt;
        except Exception as rc:&lt;br /&gt;
            pass&lt;br /&gt;
&lt;br /&gt;
        # msgbox&lt;br /&gt;
        wait_user(&amp;quot;Testing msgbox...&amp;quot;)&lt;br /&gt;
        rc = self.msgbox(&amp;quot;msgbox&amp;quot;)&lt;br /&gt;
        if rc not in (self.YES, self.ESC):&lt;br /&gt;
            raise Exception(&amp;quot;Unknown return code for msgbox: %s&amp;quot; % rc)&lt;br /&gt;
&lt;br /&gt;
        # yesno&lt;br /&gt;
        wait_user(&amp;quot;Testing yesno...&amp;quot;)&lt;br /&gt;
        rc = self.yesno(&amp;quot;yesno&amp;quot;)&lt;br /&gt;
        if rc not in (self.YES, self.NO, self.ESC):&lt;br /&gt;
            raise Exception(&amp;quot;Unknown return code for yesno: %s&amp;quot; % rc)&lt;br /&gt;
&lt;br /&gt;
        # infobox&lt;br /&gt;
        wait_user(&amp;quot;Testing infobox...&amp;quot;)&lt;br /&gt;
        rc = self.infobox(&amp;quot;infobox sleep 1 sec&amp;quot;)&lt;br /&gt;
        if rc not in (self.YES,):&lt;br /&gt;
            raise Exception(&amp;quot;Unknown return code for infobox %s&amp;quot; % rc)&lt;br /&gt;
        time.sleep(1)&lt;br /&gt;
&lt;br /&gt;
        # inputbox&lt;br /&gt;
        wait_user(&amp;quot;Testing inputbox...&amp;quot;)&lt;br /&gt;
        rc, output = self.inputbox(&amp;quot;inputbox&amp;quot;)&lt;br /&gt;
        if rc not in (self.YES, self.NO, self.ESC):&lt;br /&gt;
            raise Exception(&amp;quot;Unknown return code for inputbox: %s&amp;quot; % rc)&lt;br /&gt;
        wait_user(&amp;quot;Result: %s&amp;quot; % output)&lt;br /&gt;
&lt;br /&gt;
        # textbox&lt;br /&gt;
        wait_user(&amp;quot;Testing textbox...&amp;quot;)&lt;br /&gt;
        rc = self.textbox(&amp;quot;/etc/passwd&amp;quot;)&lt;br /&gt;
        if rc not in (self.YES, self.ESC):&lt;br /&gt;
            raise Exception(&amp;quot;Unknown return code for textbox: %s&amp;quot; % rc)&lt;br /&gt;
&lt;br /&gt;
        # menu&lt;br /&gt;
        wait_user(&amp;quot;Testing menu...&amp;quot;)&lt;br /&gt;
        rc, selection = self.menu(&amp;quot;menu&amp;quot;, (&amp;quot;option 1&amp;quot;, &amp;quot;option 2&amp;quot;))&lt;br /&gt;
        if rc not in (self.YES, self.NO, self.ESC):&lt;br /&gt;
            raise Exception(&amp;quot;Unknown return code for menu: %s&amp;quot; % rc)&lt;br /&gt;
        wait_user(&amp;quot;Result: %s&amp;quot; % selection)&lt;br /&gt;
&lt;br /&gt;
        # checklist&lt;br /&gt;
        wait_user(&amp;quot;Testing checklist...&amp;quot;)&lt;br /&gt;
        rc, selection = self.checklist(&amp;quot;menu&amp;quot;, [&amp;quot;option 1&amp;quot;, &amp;quot;option 2&amp;quot;])&lt;br /&gt;
        if rc not in (self.YES, self.NO, self.ESC):&lt;br /&gt;
            raise Exception(&amp;quot;Unknown return code for checklist: %s&amp;quot; % rc)&lt;br /&gt;
        wait_user(&amp;quot;Result: %s&amp;quot; % str(selection))&lt;br /&gt;
        wait_user(&amp;quot;Testing checklist with default selection...&amp;quot;)&lt;br /&gt;
        rc, selection = self.checklist(&amp;quot;menu&amp;quot;, [&amp;quot;option 1&amp;quot;, &amp;quot;option 2&amp;quot;], [1, 2])&lt;br /&gt;
        if rc not in (self.YES, self.NO, self.ESC):&lt;br /&gt;
            raise Exception(&amp;quot;Unknown return code for checklist: %s&amp;quot; % rc)&lt;br /&gt;
        wait_user(&amp;quot;Result: %s&amp;quot; % str(selection))&lt;br /&gt;
&lt;br /&gt;
        # radiolist&lt;br /&gt;
        wait_user(&amp;quot;Testing radiolist...&amp;quot;)&lt;br /&gt;
        rc, selection = self.radiolist(&amp;quot;menu&amp;quot;, [&amp;quot;option 1&amp;quot;, &amp;quot;option 2&amp;quot;])&lt;br /&gt;
        if rc not in (self.YES, self.NO, self.ESC):&lt;br /&gt;
            raise Exception(&amp;quot;Unknown return code for radiolist: %s&amp;quot; % rc)&lt;br /&gt;
        wait_user(&amp;quot;Result: %s&amp;quot; % str(selection))&lt;br /&gt;
        wait_user(&amp;quot;Testing radiolist with default selection...&amp;quot;)&lt;br /&gt;
        rc, selection = self.radiolist(&amp;quot;menu&amp;quot;, [&amp;quot;option 1&amp;quot;, &amp;quot;option 2&amp;quot;], 2)&lt;br /&gt;
        if rc not in (self.YES, self.NO, self.ESC):&lt;br /&gt;
            raise Exception(&amp;quot;Unknown return code for radiolist: %s&amp;quot; % rc)&lt;br /&gt;
        wait_user(&amp;quot;Result: %s&amp;quot; % str(selection))&lt;br /&gt;
&lt;br /&gt;
        # guage&lt;br /&gt;
        wait_user(&amp;quot;Testing guage...&amp;quot;)&lt;br /&gt;
        for i in range(4+1):&lt;br /&gt;
            rc = self.gauge(&amp;quot;test guage&amp;quot;, i*25)&lt;br /&gt;
            # rc = self.progress(&amp;quot;test progress&amp;quot;, i*25)&lt;br /&gt;
            if rc not in (self.YES,):&lt;br /&gt;
                raise Exception(&amp;quot;Unknown return code for guage: %s&amp;quot; % rc)&lt;br /&gt;
            time.sleep(1)&lt;br /&gt;
&lt;br /&gt;
        # form&lt;br /&gt;
        wait_user(&amp;quot;Testing form...&amp;quot;)&lt;br /&gt;
        rc, answers = self.form(&amp;quot;form&amp;quot;, [&amp;quot;option 1&amp;quot;, &amp;quot;option 2&amp;quot;])&lt;br /&gt;
        if rc not in (self.YES, self.NO, self.ESC):&lt;br /&gt;
            raise Exception(&amp;quot;Unknown return code for form: %s&amp;quot; % rc)&lt;br /&gt;
        wait_user(&amp;quot;Result: %s&amp;quot; % str(answers))&lt;br /&gt;
&lt;br /&gt;
        # done with test, cleanup&lt;br /&gt;
        wait_user(&amp;quot;Done with tests...&amp;quot;)&lt;br /&gt;
        self.clear()&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
    # dialog = Dialog()&lt;br /&gt;
    # dialog.test()&lt;br /&gt;
    pass&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Busy Loop and Thread.yield() ===&lt;br /&gt;
&lt;br /&gt;
&amp;quot;I want to tell my Python threads to yield, and so avoid hogging the CPU unnecessarily. In Java, you could do that using the Thread.yield() function&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Solution:&lt;br /&gt;
 time.sleep(0)&lt;br /&gt;
 time.sleep(0.00001)&lt;br /&gt;
 time.sleep(epsilon)&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* multithreading - In there something similar to Java&#039;s Thread.yield() in Python? Does that even make sense? - Stack Overflow - http://stackoverflow.com/questions/1908206/in-there-something-similar-to-javas-thread-yield-in-python-does-that-even-ma&lt;br /&gt;
* multithreading - How does a threading.Thread yield the rest of its quantum in Python? - Stack Overflow - http://stackoverflow.com/questions/787803/how-does-a-threading-thread-yield-the-rest-of-its-quantum-in-python&lt;br /&gt;
&lt;br /&gt;
=== USB ===&lt;br /&gt;
&lt;br /&gt;
Programming with PyUSB 1.0 - http://pyusb.sourceforge.net/docs/1.0/tutorial.html&lt;br /&gt;
&lt;br /&gt;
PyUSB - http://pyusb.sourceforge.net/&lt;br /&gt;
&lt;br /&gt;
 git clone https://github.com/walac/pyusb&lt;br /&gt;
&lt;br /&gt;
 import usb.core&lt;br /&gt;
 dev = usb.core.find()&lt;br /&gt;
&lt;br /&gt;
 # find our device&lt;br /&gt;
 dev = usb.core.find(idVendor=0xfffe, idProduct=0x0001)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&#039;&#039;&#039;Dealing with multiple identical devices&#039;&#039;&#039; - Sometimes you may have two identical devices connected to the computer. How can you differentiate them? Device objects come with two additional attributes which are not part of the USB Spec, but are very useful: bus and address attributes. First of all, it is worth to say that these attributes come from the backend and a backend is free to not support them, in which case they are set to None. That said, these attributes represent the bus number and bus address of the device and, as you might already have imagined, can be used to differentiate two devices with the same idVendor and idProduct attributes.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Tkinter ===&lt;br /&gt;
&lt;br /&gt;
Python GUI Bitcoin: [http://bitcoin.stackexchange.com/questions/10594/simplest-way-of-obtaining-mtgox-exchange-rate-via-an-api]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import json&lt;br /&gt;
import urllib2&lt;br /&gt;
from Tkinter import *&lt;br /&gt;
&lt;br /&gt;
url=&#039;http://api.bitcoincharts.com/v1/markets.json&#039;&lt;br /&gt;
req=urllib2.Request(url)&lt;br /&gt;
response=urllib2.urlopen(req).read()&lt;br /&gt;
output=json.loads(response)&lt;br /&gt;
&lt;br /&gt;
mtusd_price = output[-10][&#039;avg&#039;]&lt;br /&gt;
mteur_price = output[31][&#039;avg&#039;]&lt;br /&gt;
mtgbp_price = output[44][&#039;avg&#039;]&lt;br /&gt;
&lt;br /&gt;
MTUSD= &#039;USD&#039; + &#039; &#039; + str(mtusd_price)&lt;br /&gt;
MTEUR= &#039;EUR&#039; + &#039; &#039; + str(mteur_price)&lt;br /&gt;
MTGBP = &#039;GBP&#039; + &#039; &#039; + str(mtgbp_price)&lt;br /&gt;
&lt;br /&gt;
root= Tk()&lt;br /&gt;
root.title(&amp;quot;Bitcoin Price&amp;quot;)&lt;br /&gt;
root.geometry(&amp;quot;250x100&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
USD = Label(root, text=MTUSD)&lt;br /&gt;
EUR = Label(root, text=MTEUR)&lt;br /&gt;
GBP = Label(root, text=MTGBP)&lt;br /&gt;
USD.pack()&lt;br /&gt;
EUR.pack()&lt;br /&gt;
GBP.pack()&lt;br /&gt;
mainloop()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== ctypes ===&lt;br /&gt;
&lt;br /&gt;
&amp;quot;ctypes is a foreign function library for Python. It provides C compatible data types, and allows calling functions in DLLs or shared libraries. It can be used to wrap these libraries in pure Python.&amp;quot;&lt;br /&gt;
:-- 15.17. ctypes — A foreign function library for Python — Python v2.7.7 documentation - https://docs.python.org/2/library/ctypes.html&lt;br /&gt;
&lt;br /&gt;
Use &amp;quot;c scope&amp;quot; to build a database of symbols to see what options are available.&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
testlib.c&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void myprint(void);&lt;br /&gt;
&lt;br /&gt;
void myprint()&lt;br /&gt;
{&lt;br /&gt;
    printf(&amp;quot;hello world\n&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Compile:&lt;br /&gt;
 gcc -shared -Wl,-soname,testlib -o testlib.so -fPIC testlib.c&lt;br /&gt;
&lt;br /&gt;
testlibwrapper.py&lt;br /&gt;
&lt;br /&gt;
Python:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import ctypes&lt;br /&gt;
&lt;br /&gt;
testlib = ctypes.CDLL(&#039;/full/path/to/testlib.so&#039;)&lt;br /&gt;
testlib.myprint()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Source: python - ctypes - Beginner - Stack Overflow - http://stackoverflow.com/questions/5081875/ctypes-beginner&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
nzjrs&#039;s Gists - https://gist.github.com/nzjrs&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int sum(double *x,int n)&lt;br /&gt;
{&lt;br /&gt;
  int i;&lt;br /&gt;
  double counter;&lt;br /&gt;
  counter = 0;&lt;br /&gt;
  for(i=0;i&amp;lt;n;i++)&lt;br /&gt;
    {&lt;br /&gt;
      counter=counter+x[i];&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
  return counter;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -c sum.c&lt;br /&gt;
gcc -shared -o sum.so sum.o&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from ctypes import *&lt;br /&gt;
my_sum=CDLL(&#039;sum.so&#039;)&lt;br /&gt;
a=numpy.array(range(10),dtype=float)&lt;br /&gt;
my_sum.sum(a.ctypes.data_as(c_void_p),int(10))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
a=(c_double*10)()&lt;br /&gt;
for i in range(10):&lt;br /&gt;
   a[i]=i&lt;br /&gt;
my_sum.sum(a,int(10))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Source: Ctypes — Numerical Computing with Sage v6.2 - http://www.sagemath.org/doc/numerical_sage/ctypes.html&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
=== Warnings ===&lt;br /&gt;
&lt;br /&gt;
 if sys.version_info &amp;gt;= (1, 0, 0):&lt;br /&gt;
   warnings.warn(&amp;quot;Danger Will Robinson: trying Phi on untested Python 3.0!&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
=== enum ===&lt;br /&gt;
&lt;br /&gt;
Python 3: https://docs.python.org/3/library/enum.html&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from enum import Enum&lt;br /&gt;
&lt;br /&gt;
# class syntax&lt;br /&gt;
class Color(Enum):&lt;br /&gt;
    RED = 1&lt;br /&gt;
    GREEN = 2&lt;br /&gt;
    BLUE = 3&lt;br /&gt;
&lt;br /&gt;
# functional syntax&lt;br /&gt;
Color = Enum(&#039;Color&#039;, [&#039;RED&#039;, &#039;GREEN&#039;, &#039;BLUE&#039;])&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
Python 2: [http://stackoverflow.com/questions/36932/how-can-i-represent-an-enum-in-python]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Enum(set):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot; Basic enumerated type&lt;br /&gt;
    &lt;br /&gt;
    Example&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt; Animals = phi.Enum([&amp;quot;DOG&amp;quot;, &amp;quot;CAT&amp;quot;, &amp;quot;HORSE&amp;quot;])&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt; Animals.DOG&lt;br /&gt;
        &#039;DOG&#039;&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt; &#039;HORSE&#039; in Animals&lt;br /&gt;
        True&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    def __getattr__(self, name):&lt;br /&gt;
        if name in self:&lt;br /&gt;
            return name&lt;br /&gt;
        raise AttributeError(&amp;quot;Missing Enum property: %s&amp;quot; % name)&lt;br /&gt;
    def __setattr__(self, name, value):  # this makes it read-only&lt;br /&gt;
        raise AttributeError(&amp;quot;Unable to modify Enum property: %s (%s)&amp;quot; % (name, value))&lt;br /&gt;
&lt;br /&gt;
Animals = Enum([&amp;quot;DOG&amp;quot;, &amp;quot;CAT&amp;quot;, &amp;quot;HORSE&amp;quot;])&lt;br /&gt;
&lt;br /&gt;
print(Animals.DOG)  # &#039;DOG&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----------&lt;br /&gt;
&lt;br /&gt;
Alternative:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Stationery:&lt;br /&gt;
    Pen, Pencil, Eraser = range(0, 3)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
One liner:&lt;br /&gt;
 class Enum(tuple): __getattr__ = tuple.index&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; State = Enum([&#039;Unclaimed&#039;, &#039;Claimed&#039;])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; State.Claimed&lt;br /&gt;
1&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; State[1]&lt;br /&gt;
&#039;Claimed&#039;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; State&lt;br /&gt;
(&#039;Unclaimed&#039;, &#039;Claimed&#039;)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; range(len(State))&lt;br /&gt;
[0, 1]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; [(k, State[k]) for k in range(len(State))]&lt;br /&gt;
[(0, &#039;Unclaimed&#039;), (1, &#039;Claimed&#039;)]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; [(k, getattr(State, k)) for k in State]&lt;br /&gt;
[(&#039;Unclaimed&#039;, 0), (&#039;Claimed&#039;, 1)]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Python 3 supports enum natively with the enum.Enum library:&lt;br /&gt;
&lt;br /&gt;
=== pySerial ===&lt;br /&gt;
&lt;br /&gt;
https://pythonhosted.org/pyserial/&lt;br /&gt;
&lt;br /&gt;
&amp;quot;This module encapsulates the access for the serial port. It provides backends for Python running on Windows, OSX, Linux, BSD (possibly any POSIX compliant system) and IronPython. The module named “serial” automatically selects the appropriate backend.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
https://github.com/pyserial/&lt;br /&gt;
&lt;br /&gt;
Intro - https://pythonhosted.org/pyserial/shortintro.html&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import serial&lt;br /&gt;
import time&lt;br /&gt;
&lt;br /&gt;
ser = serial.Serial(&lt;br /&gt;
    port=&#039;COM4&#039;,\&lt;br /&gt;
    baudrate=9600,\&lt;br /&gt;
    parity=serial.PARITY_NONE,\&lt;br /&gt;
    stopbits=serial.STOPBITS_ONE,\&lt;br /&gt;
    bytesize=serial.EIGHTBITS,\&lt;br /&gt;
        timeout=0)&lt;br /&gt;
&lt;br /&gt;
print(&amp;quot;connected to: &amp;quot; + ser.portstr)&lt;br /&gt;
&lt;br /&gt;
#this will store the line&lt;br /&gt;
seq = []&lt;br /&gt;
count = 1&lt;br /&gt;
&lt;br /&gt;
while True:&lt;br /&gt;
    for c in ser.read():&lt;br /&gt;
        seq.append(chr(c)) #convert from ANSII&lt;br /&gt;
        joined_seq = &#039;&#039;.join(str(v) for v in seq) #Make a string from array&lt;br /&gt;
&lt;br /&gt;
        if chr(c) == &#039;\n&#039;:&lt;br /&gt;
            print(&amp;quot;Line &amp;quot; + str(count) + &#039;: &#039; + joined_seq)&lt;br /&gt;
            seq = []&lt;br /&gt;
            count += 1&lt;br /&gt;
            break&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ser.close()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ref: http://stackoverflow.com/questions/16077912/python-serial-how-to-use-the-read-or-readline-function-to-read-more-than-1-char&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
I modified the code to monitor a COM port: (Windows)&lt;br /&gt;
&lt;br /&gt;
Monitor Serial:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import serial, time, sys&lt;br /&gt;
&lt;br /&gt;
logger = open(&amp;quot;serial.txt&amp;quot;, &amp;quot;w&amp;quot;)&lt;br /&gt;
timer = time.time()&lt;br /&gt;
&lt;br /&gt;
def log(msg, head=False):&lt;br /&gt;
    msg = msg.strip()&lt;br /&gt;
    if head:&lt;br /&gt;
      msg = &amp;quot;&amp;gt;&amp;gt;&amp;gt; &amp;quot; + msg&lt;br /&gt;
    logger.write(msg + &amp;quot;\n&amp;quot;)&lt;br /&gt;
    sys.stdout.write(msg + &amp;quot;\n&amp;quot;)&lt;br /&gt;
    newtime = time.time()&lt;br /&gt;
    if newtime &amp;gt; timer + 1:&lt;br /&gt;
        logger.flush()&lt;br /&gt;
        sys.stdout.flush()&lt;br /&gt;
&lt;br /&gt;
while True:&lt;br /&gt;
&lt;br /&gt;
    ser = None&lt;br /&gt;
    try:&lt;br /&gt;
        ser = serial.Serial(&lt;br /&gt;
            port=&#039;COM1&#039;,\&lt;br /&gt;
            baudrate=115200,\&lt;br /&gt;
            parity=serial.PARITY_NONE,\&lt;br /&gt;
            stopbits=serial.STOPBITS_ONE,\&lt;br /&gt;
            bytesize=serial.EIGHTBITS,\&lt;br /&gt;
                timeout=0)&lt;br /&gt;
    except serial.serialutil.SerialException as e:&lt;br /&gt;
        log(str(e), True)&lt;br /&gt;
        time.sleep(1)&lt;br /&gt;
        continue&lt;br /&gt;
&lt;br /&gt;
    log(&amp;quot;Connected to: &amp;quot; + ser.portstr, True)&lt;br /&gt;
    count=1&lt;br /&gt;
&lt;br /&gt;
    try:&lt;br /&gt;
        line = []&lt;br /&gt;
        while True:&lt;br /&gt;
            for c in ser.readline():&lt;br /&gt;
                line.append(c)&lt;br /&gt;
                if c == &amp;quot;\n&amp;quot;:&lt;br /&gt;
                    log(&amp;quot;&amp;quot;.join(line))&lt;br /&gt;
                    line = []&lt;br /&gt;
    except serial.serialutil.SerialException as e:&lt;br /&gt;
        log(str(e), True)&lt;br /&gt;
        time.sleep(1)&lt;br /&gt;
    ser.close()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== MyBool ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; class NewBool(int):&lt;br /&gt;
...    def __new__(cls, value):&lt;br /&gt;
...        return int.__new__(cls, bool(value))&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; y = NewBool(2)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; y == 1&lt;br /&gt;
True&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
https://jfine-python-classes.readthedocs.io/en/latest/subclass-int.html&lt;br /&gt;
&lt;br /&gt;
Also check out the __cmp__&lt;br /&gt;
&lt;br /&gt;
== md5 ==&lt;br /&gt;
&lt;br /&gt;
 import md5&lt;br /&gt;
 md5.new(&amp;quot;Nobody inspects the spammish repetition&amp;quot;).hexdigest()&lt;br /&gt;
 # &#039;bb649c83dd1ea5c9d9dec9a18df0ffe9&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ echo -n &amp;quot;Nobody inspects the spammish repetition&amp;quot; | md5sum&lt;br /&gt;
bb649c83dd1ea5c9d9dec9a18df0ffe9  -&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== External Libraries ==&lt;br /&gt;
&lt;br /&gt;
=== execnet ===&lt;br /&gt;
&lt;br /&gt;
Python Package Index - execnet - https://pypi.python.org/pypi/execnet&lt;br /&gt;
&lt;br /&gt;
Examples - http://codespeak.net/execnet/examples.html&lt;br /&gt;
* basic local and remote communication - http://codespeak.net/execnet/example/test_info.html&lt;br /&gt;
&lt;br /&gt;
Execute source code in subprocess, communicate through a channel:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import execnet&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; gw = execnet.makegateway()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; channel = gw.remote_exec(&amp;quot;channel.send(channel.receive()+1)&amp;quot;)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; channel.send(1)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; channel.receive()&lt;br /&gt;
2&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Compare current working directories&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import execnet, os&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; gw = execnet.makegateway()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; ch = gw.remote_exec(&amp;quot;import os; channel.send(os.getcwd())&amp;quot;)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; res = ch.receive()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; assert res == os.getcwd()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Get information from remote ssh account&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import execnet, os&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; gw = execnet.makegateway(&amp;quot;ssh=codespeak.net&amp;quot;)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; channel = gw.remote_exec(&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
...     import sys, os&lt;br /&gt;
...     channel.send((sys.platform, sys.version_info, os.getpid()))&lt;br /&gt;
... &amp;quot;&amp;quot;&amp;quot;)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; platform, version_info, remote_pid = channel.receive()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; platform&lt;br /&gt;
&#039;linux2&#039;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; version_info&lt;br /&gt;
(2, 4, 2, &#039;final&#039;, 0)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
remote-exec a function (avoiding inlined source part I)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import execnet&lt;br /&gt;
&lt;br /&gt;
def multiplier(channel, factor):&lt;br /&gt;
    while not channel.isclosed():&lt;br /&gt;
        param = channel.receive()&lt;br /&gt;
        channel.send(param * factor)&lt;br /&gt;
&lt;br /&gt;
gw = execnet.makegateway()&lt;br /&gt;
channel = gw.remote_exec(multiplier, factor=10)&lt;br /&gt;
&lt;br /&gt;
for i in range(5):&lt;br /&gt;
    channel.send(i)&lt;br /&gt;
    result = channel.receive()&lt;br /&gt;
    assert result == i * 10&lt;br /&gt;
&lt;br /&gt;
gw.exit()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
remote-exec a module (avoiding inlined source part II)&lt;br /&gt;
:&amp;quot;You can pass a module object to remote_exec in which case its source code will be sent. No dependencies will be transferred so the module must be self-contained or only use modules that are installed on the “other” side. Module code can detect if it is running in a remote_exec situation by checking for the special __name__ attribute.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# content of a module remote1.py&lt;br /&gt;
&lt;br /&gt;
if __name__ == &#039;__channelexec__&#039;:&lt;br /&gt;
    channel.send(&#039;initialization complete&#039;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import execnet, remote1&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; gw = execnet.makegateway()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; ch = gw.remote_exec(remote1)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; print (ch.receive())&lt;br /&gt;
initialization complete&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use a callback instead of receive() and wait for completion&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import execnet&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; gw = execnet.makegateway()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; channel = gw.remote_exec(&amp;quot;for i in range(10): channel.send(i)&amp;quot;)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; l = []&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; channel.setcallback(l.append, endmarker=None)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; channel.waitclose() # waits for closing, i.e. remote exec finish&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; l&lt;br /&gt;
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, None]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
a simple command loop pattern&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# contents of: remotecmd.py&lt;br /&gt;
import os&lt;br /&gt;
&lt;br /&gt;
def simple(arg):&lt;br /&gt;
    return arg + 1&lt;br /&gt;
&lt;br /&gt;
def listdir(path):&lt;br /&gt;
    return os.listdir(path)&lt;br /&gt;
    &lt;br /&gt;
if __name__ == &#039;__channelexec__&#039;:&lt;br /&gt;
    for item in channel:&lt;br /&gt;
        channel.send(eval(item))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import execnet, remotecmd&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; gw = execnet.makegateway()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; ch = gw.remote_exec(remotecmd)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; ch.send(&#039;simple(10)&#039;) # execute func-call remotely&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; ch.receive()&lt;br /&gt;
11&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== evdev ===&lt;br /&gt;
&lt;br /&gt;
Install:&lt;br /&gt;
 apt-get install python-setuptools python-dev&lt;br /&gt;
 easy_install pip&lt;br /&gt;
 pip install evdev&lt;br /&gt;
&lt;br /&gt;
Simple read usage:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from evdev import InputDevice&lt;br /&gt;
from evdev import ecodes&lt;br /&gt;
&lt;br /&gt;
# look for a /dev/input/by-id/usb...kbd or similar&lt;br /&gt;
DEVICE = &amp;quot;/dev/input/by-id/usb-ORTEK_USB_Keyboard_Hub-event-kbd&amp;quot;&lt;br /&gt;
&lt;br /&gt;
dev = InputDevice(DEVICE)&lt;br /&gt;
&lt;br /&gt;
while True:&lt;br /&gt;
    r, w, x = select([dev], [], [], 5)&lt;br /&gt;
    for event in dev.read():&lt;br /&gt;
        if event.type == 1 and event.value == 1:&lt;br /&gt;
            print event.code&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
List LED states:&lt;br /&gt;
 dev.leds()&lt;br /&gt;
 dev.leds(verbose=True)&lt;br /&gt;
&lt;br /&gt;
Inject usage: (does not appear to really work)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from evdev import InputDevice&lt;br /&gt;
from evdev import ecodes&lt;br /&gt;
from evdev import UInput&lt;br /&gt;
&lt;br /&gt;
DEVICE = &amp;quot;/dev/input/by-id/usb-ORTEK_USB_Keyboard_Hub-event-kbd&amp;quot;&lt;br /&gt;
dev = InputDevice(DEVICE)&lt;br /&gt;
&lt;br /&gt;
ui = UInput()&lt;br /&gt;
&lt;br /&gt;
ui.write(ecodes.EV_KEY, ecodes.KEY_4, 1)&lt;br /&gt;
ui.write(ecodes.EV_KEY, ecodes.KEY_4, 0)&lt;br /&gt;
ui.syn()&lt;br /&gt;
&lt;br /&gt;
ui.write(ecodes.EV_KEY, ecodes.KEY_NUMLOCK, 1)&lt;br /&gt;
ui.write(ecodes.EV_KEY, ecodes.KEY_NUMLOCK, 0)&lt;br /&gt;
ui.syn()&lt;br /&gt;
&lt;br /&gt;
ui.close()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Tutorial:&lt;br /&gt;
* evdev documentation — python-evdev 0.4.3 documentation - http://pythonhosted.org/evdev/index.html&lt;br /&gt;
References:&lt;br /&gt;
* python-evdev/doc/tutorial.rst at master · gvalkov/python-evdev · GitHub - https://github.com/gvalkov/python-evdev/blob/master/doc/tutorial.rst&lt;br /&gt;
&lt;br /&gt;
=== ldap-python ===&lt;br /&gt;
&lt;br /&gt;
python-ldap: LDAP client API for Python - http://www.python-ldap.org/&lt;br /&gt;
&lt;br /&gt;
Index of Packages : Python Package Index - https://pypi.python.org/pypi/python-ldap/&lt;br /&gt;
&lt;br /&gt;
 yum install python-devel openldap-devel&lt;br /&gt;
 pip install python-ldap&lt;br /&gt;
&lt;br /&gt;
Articles:&lt;br /&gt;
* Python LDAP Applications: Part 1 - Installing and Configuring the Python-LDAP Library and Binding to an LDAP Directory | Packt Publishing - http://www.packtpub.com/article/installing-and-configuring-the-python-ldap-library-and-binding-to-an-ldap-directory&lt;br /&gt;
&lt;br /&gt;
=== xmmp ===&lt;br /&gt;
&lt;br /&gt;
PDF:&lt;br /&gt;
* XMPP: The Definitive Guide - Oreilly - http://oriolrius.cat/blog/wp-content/uploads/2009/10/Oreilly.XMPP.The.Definitive.Guide.May.2009.pdf&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
xmmp is the Jabber protocol&lt;br /&gt;
&lt;br /&gt;
Best options:&lt;br /&gt;
&lt;br /&gt;
MIT libraries.&lt;br /&gt;
* sleekxmpp (was: sleekxmpp) is pretty popular and is used for examples in Peter Saint-Andre&#039;s XMPP book from O&#039;Reilly. It reportedly works well, and finally got an email list in April 2010, and has a chat room at sleek@conference.jabber.org.&lt;br /&gt;
&lt;br /&gt;
GPL libraries.&lt;br /&gt;
* xmpppy is used by gajim.&lt;br /&gt;
&lt;br /&gt;
LPGL libraries.&lt;br /&gt;
* pyxmpp is pretty good and uses libxml2 internally for xml parsing.&lt;br /&gt;
* pyxmpp2 is the next version of pyxmpp, runs on python 2.7 and 3.2, and removes the libxml2 requirement. Like many, it requires dnspython.&lt;br /&gt;
* jabberpy is the original and still works for a lot of tasks, but is thoroughly unmaintained.&lt;br /&gt;
&lt;br /&gt;
Other libraries.&lt;br /&gt;
* Wokkel, mentioned in another post. That&#039;s a new one for me, based on twisted.&lt;br /&gt;
&lt;br /&gt;
chat - Best python XMPP / Jabber client library? - Stack Overflow - http://stackoverflow.com/questions/1901828/best-python-xmpp-jabber-client-library&lt;br /&gt;
&lt;br /&gt;
=== xmpppy ===&lt;br /&gt;
&lt;br /&gt;
xmpppy: the jabber python project - http://xmpppy.sourceforge.net/&lt;br /&gt;
&lt;br /&gt;
&amp;quot;xmpppy is a Python library that is targeted to provide easy scripting with Jabber. Similar projects are Twisted Words and jabber.py.&lt;br /&gt;
&lt;br /&gt;
This library was not designed from scratch. It inherits some code from jabberpy and have very similar API in many places. Though it is separate project since it have almost completely different architecture and primarily aims to work with jabberd2 - the new Open Source Jabber Server.&lt;br /&gt;
&lt;br /&gt;
xmpppy is distributed under the terms of GNU General Public License and can be freely redistributed without any charge.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 wget http://sourceforge.net/projects/xmpppy/files/xmpppy/0.4.1/xmpppy-0.4.1.tar.gz/download -O xmpppy-0.4.1.tar.gz&lt;br /&gt;
 tar -zvxf xmpppy-0.4.1.tar.gz&lt;br /&gt;
 pip install pydns&lt;br /&gt;
&lt;br /&gt;
--- basic connection ---&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
 &lt;br /&gt;
import xmpp&lt;br /&gt;
 &lt;br /&gt;
user=&amp;quot;username@gmail.com&amp;quot;&lt;br /&gt;
password=&amp;quot;password&amp;quot;&lt;br /&gt;
server=&amp;quot;gmail.com&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
jid = xmpp.JID(user)&lt;br /&gt;
connection = xmpp.Client(server,debug=[])&lt;br /&gt;
connection.connect()&lt;br /&gt;
result = connection.auth(jid.getNode(), password,&amp;quot;LFY-client&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
connection.sendInitPresence()&lt;br /&gt;
 &lt;br /&gt;
while connection.Process(1):&lt;br /&gt;
    pass&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* Use XMPP to Create Your Own Google Talk Client - LINUX For You - http://www.linuxforu.com/2012/06/use-xmpp-to-create-your-own-google-talk-client/&lt;br /&gt;
&lt;br /&gt;
--- basic receive ---&lt;br /&gt;
&lt;br /&gt;
Print messages when received:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
 &lt;br /&gt;
import xmpp&lt;br /&gt;
 &lt;br /&gt;
user=&amp;quot;username@gmail.com&amp;quot;&lt;br /&gt;
password=&amp;quot;password&amp;quot;&lt;br /&gt;
server=&amp;quot;gmail.com&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
def message_handler(connect_object, message_node):&lt;br /&gt;
        message = &amp;quot;Welcome to my first Gtalk Bot :)&amp;quot;&lt;br /&gt;
        connect_object.send( xmpp.Message( message_node.getFrom() ,message))&lt;br /&gt;
 &lt;br /&gt;
jid = xmpp.JID(user)&lt;br /&gt;
connection = xmpp.Client(server)&lt;br /&gt;
connection.connect()&lt;br /&gt;
result = connection.auth(jid.getNode(), password, &amp;quot;LFY-client&amp;quot;)&lt;br /&gt;
connection.RegisterHandler(&#039;message&#039;, message_handler)&lt;br /&gt;
 &lt;br /&gt;
connection.sendInitPresence()&lt;br /&gt;
 &lt;br /&gt;
while connection.Process(1):&lt;br /&gt;
    pass&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* Use XMPP to Create Your Own Google Talk Client - LINUX For You - http://www.linuxforu.com/2012/06/use-xmpp-to-create-your-own-google-talk-client/&lt;br /&gt;
&lt;br /&gt;
--- remote-control shell bot ---&lt;br /&gt;
&lt;br /&gt;
Replace the simple bot’s message_handler() function with this new one:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def message_handler(connect_object,message_node):&lt;br /&gt;
        command = str(message_node.getBody())&lt;br /&gt;
 &lt;br /&gt;
        process = subprocess.Popen(command,shell=True,stdout=subprocess.PIPE, stderr=subprocess.PIPE)&lt;br /&gt;
        message = process.stdout.read()&lt;br /&gt;
        if message==&amp;quot;&amp;quot;:&lt;br /&gt;
            message=process.stderr.read()&lt;br /&gt;
 &lt;br /&gt;
        connect_object.send( xmpp.Message( message_node.getFrom() ,message))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* Use XMPP to Create Your Own Google Talk Client - LINUX For You - http://www.linuxforu.com/2012/06/use-xmpp-to-create-your-own-google-talk-client/&lt;br /&gt;
&lt;br /&gt;
--- roster ---&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import xmpp&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
userID   = &#039;myname@gmail.com&#039; &lt;br /&gt;
password = &#039;mypassword&#039;&lt;br /&gt;
ressource = &#039;Script&#039;&lt;br /&gt;
&lt;br /&gt;
jid  = xmpp.protocol.JID(userID)&lt;br /&gt;
jabber  = xmpp.Client(jid.getDomain(), debug=[])&lt;br /&gt;
&lt;br /&gt;
connection = jabber.connect((&#039;talk.google.com&#039;,5222))&lt;br /&gt;
auth = jabber.auth(jid.getNode(), password, ressource)&lt;br /&gt;
&lt;br /&gt;
jabber.sendInitPresence(requestRoster=1)&lt;br /&gt;
myroster = jabber.getRoster()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To get status, you have to wait for the other clients to send you their status:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
jabber.RegisterHandler(&#039;presence&#039;, myPresenceHandler)&lt;br /&gt;
&lt;br /&gt;
def myPresenceHandler(con, event):&lt;br /&gt;
  fromjid = event.getFrom().getStripped()&lt;br /&gt;
  status = myroster.getStatus(fromjid)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
python - XMPP chat: accessing contacts&#039; status messages with xmppPy&#039;s Roster - Stack Overflow - http://stackoverflow.com/questions/2381597/xmpp-chat-accessing-contacts-status-messages-with-xmpppys-roster&lt;br /&gt;
&lt;br /&gt;
--- full roster script ---&lt;br /&gt;
&lt;br /&gt;
kparal/jabber-roster · GitHub - https://github.com/kparal/jabber-roster&lt;br /&gt;
&lt;br /&gt;
A simple Python tool for listing your Jabber roster contacts. You can use it to easily backup list of your buddies.&lt;br /&gt;
&lt;br /&gt;
This program is maintained, but not further developed. Bugs will be fixed, but no new features will be added. If you want to work on this program, don&#039;t hesitate to contact me, I will gladly assign you to the development team.&lt;br /&gt;
&lt;br /&gt;
 git clone https://github.com/kparal/jabber-roster&lt;br /&gt;
 python jabber_roster.py&lt;br /&gt;
&lt;br /&gt;
https://pypi.python.org/pypi/jabber-roster&lt;br /&gt;
&lt;br /&gt;
--- vcard ---&lt;br /&gt;
&lt;br /&gt;
This information is not in the roster. You will need to query the clients individually and get their vCard by sending this IQ :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;iq from=&#039;stpeter@jabber.org/roundabout&#039;&lt;br /&gt;
    id=&#039;v1&#039;&lt;br /&gt;
    type=&#039;get&#039;&amp;gt;&lt;br /&gt;
  &amp;lt;vCard xmlns=&#039;vcard-temp&#039;/&amp;gt;&lt;br /&gt;
&amp;lt;/iq&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
My solution:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def vcard(disp, jid):&lt;br /&gt;
    msg = xmpp.protocol.Iq()&lt;br /&gt;
    msg.setType(&#039;get&#039;)&lt;br /&gt;
    msg.setTo(jid)&lt;br /&gt;
    qc = msg.addChild(&#039;vCard&#039;)&lt;br /&gt;
    qc.setAttr(&#039;xmlns&#039;, &#039;vcard-temp&#039;)&lt;br /&gt;
    rep = disp.SendAndWaitForResponse(msg)&lt;br /&gt;
    # to see what other fields are available in the XML output:&lt;br /&gt;
    # print rep&lt;br /&gt;
    userid=fname=lname=title=department=region=None&lt;br /&gt;
    for i in rep.getChildren():&lt;br /&gt;
        for j in i.getChildren():&lt;br /&gt;
            if j.getName() == &amp;quot;TITLE&amp;quot;:&lt;br /&gt;
                title = j.getData().encode(&#039;utf-8&#039;)&lt;br /&gt;
            for k in j.getChildren():&lt;br /&gt;
                if k.getName() == &amp;quot;GIVEN&amp;quot;:&lt;br /&gt;
                    fname = k.getData().encode(&#039;utf-8&#039;)&lt;br /&gt;
                if k.getName() == &amp;quot;FAMILY&amp;quot;:&lt;br /&gt;
                    lname = k.getData().encode(&#039;utf-8&#039;)&lt;br /&gt;
                if k.getName() == &amp;quot;ORGUNIT&amp;quot;:&lt;br /&gt;
                    department = k.getData().encode(&#039;utf-8&#039;)&lt;br /&gt;
                if k.getName() == &amp;quot;REGION&amp;quot;:&lt;br /&gt;
                    region = k.getData().encode(&#039;utf-8&#039;)&lt;br /&gt;
    return fname, lname, title, department, region&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* xmpppy - Retrieve gtalk nickname in python xmpp - Stack Overflow - http://stackoverflow.com/questions/4539477/retrieve-gtalk-nickname-in-python-xmpp&lt;br /&gt;
* XEP-0054: vcard-temp - http://xmpp.org/extensions/xep-0054.html&lt;br /&gt;
&lt;br /&gt;
=== google-api-python-client ===&lt;br /&gt;
&lt;br /&gt;
Google APIs Client Library for Python, which includes:&lt;br /&gt;
* google-api-python-client: The core Python library for accessing Google APIs.&lt;br /&gt;
* oauth2client: A Python client library for OAuth 2.0.&lt;br /&gt;
* Sample applications using google-api-python-client and oauth2client &lt;br /&gt;
&lt;br /&gt;
-&lt;br /&gt;
&lt;br /&gt;
https://developers.google.com/api-client-library/python/start/installation&lt;br /&gt;
* Calendar API - Python/Command Line&lt;br /&gt;
&lt;br /&gt;
-&lt;br /&gt;
Download:&lt;br /&gt;
 wget https://code.google.com/p/google-api-python-client/downloads/detail?name=google-api-python-client-1.2.zip&lt;br /&gt;
 wget https://code.google.com/p/google-api-python-client/downloads/detail?name=oauth2client-1.2.zip&lt;br /&gt;
&lt;br /&gt;
Git:&lt;br /&gt;
 git clone https://github.com/google/google-api-python-client&lt;br /&gt;
 git clone https://github.com/google/oauth2client&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* google-api-python-client - Google APIs Client Library for Python - Google Project Hosting - https://code.google.com/p/google-api-python-client/&lt;br /&gt;
&lt;br /&gt;
== Documentation Tools ==&lt;br /&gt;
&lt;br /&gt;
=== pydoc ===&lt;br /&gt;
&lt;br /&gt;
pydoc - http://docs.python.org/library/pydoc.html&lt;br /&gt;
: Documentation generator and online help system&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Doxygen and Doxypy ===&lt;br /&gt;
&lt;br /&gt;
See [[Python/Doxygen]]&lt;br /&gt;
&lt;br /&gt;
=== Sphinx ===&lt;br /&gt;
&lt;br /&gt;
Sphinx - http://sphinx.pocoo.org/&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Sphinx is a tool that makes it easy to create intelligent and beautiful documentation, written by Georg Brandl and licensed under the BSD license.&lt;br /&gt;
&lt;br /&gt;
It was originally created for the new Python documentation, and it has excellent facilities for the documentation of Python projects, but C/C++ is already supported as well, and it is planned to add special support for other languages as well. Of course, this site is also created from reStructuredText sources using Sphinx!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== epydoc ===&lt;br /&gt;
&lt;br /&gt;
epydoc - http://epydoc.sourceforge.net/&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Epydoc is a tool for generating API documentation for Python modules, based on their docstrings. For an example of epydoc&#039;s output, see the API documentation for epydoc itself (html, pdf). A lightweight markup language called epytext can be used to format docstrings, and to add information about specific fields, such as parameters and instance variables. Epydoc also understands docstrings written in reStructuredText, Javadoc, and plaintext. For a more extensive example of epydoc&#039;s output, see the API documentation for Python 2.5. &amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Python 3 ==&lt;br /&gt;
&lt;br /&gt;
=== Python 3 Wall of Superpowers ===&lt;br /&gt;
&lt;br /&gt;
Python 3 Wall of Superpowers - https://python3wos.appspot.com/&lt;br /&gt;
&lt;br /&gt;
&amp;quot;As listed on PyPI - packages in red don&#039;t support python 3, packages in green do. Hopefully one day everything will be greener. &amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== New in Python 3 ===&lt;br /&gt;
&lt;br /&gt;
==== qualnames ====&lt;br /&gt;
&lt;br /&gt;
New in 3.3&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; def f():&lt;br /&gt;
...   def g():&lt;br /&gt;
...     class H: pass&lt;br /&gt;
...     return H&lt;br /&gt;
...   return g&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; H=f()()&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; # 3.3:&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; H&lt;br /&gt;
&amp;lt;class &#039;__main__.f.&amp;lt;locals&amp;gt;.g.&amp;lt;locals&amp;gt;.H&#039;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; H.__qualname__&lt;br /&gt;
&#039;f.&amp;lt;locals&amp;gt;.g.&amp;lt;locals&amp;gt;.H&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; # 2.6:&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; H&lt;br /&gt;
&amp;lt;class __main__.H at 0x2b885044b890&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; H.__qualname__&lt;br /&gt;
AttributeError: class H has no attribute &#039;__qualname__&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Python 2 or Python 3 ==&lt;br /&gt;
&lt;br /&gt;
Python2orPython3 - PythonInfo Wiki - http://wiki.python.org/moin/Python2orPython3&lt;br /&gt;
:Short version: Python 2.x is the status quo, Python 3.x is the shiny new thing.&lt;br /&gt;
:At the time of writing (July 4, 2010), the final 2.7 release is out, with a statement of extended support for this end-of-life release. The 2.x branch will see no new major releases after that. 3.x is under active and continued development, with 3.1 already available and 3.2 due for release around the turn of the year.&lt;br /&gt;
&lt;br /&gt;
Python 2.7.1 Release - http://www.python.org/download/releases/2.7.1/&lt;br /&gt;
&lt;br /&gt;
What’s New In Python 3.0 — Python v3.0.1 documentation - http://docs.python.org/release/3.0.1/whatsnew/3.0.html&lt;br /&gt;
* print() requires parenthesis&lt;br /&gt;
* raw_input() is now input()&lt;br /&gt;
&lt;br /&gt;
== Python for Windows ==&lt;br /&gt;
&lt;br /&gt;
Python for Windows - http://www.python.org/download/windows/&lt;br /&gt;
&lt;br /&gt;
=== Windows IDEs ===&lt;br /&gt;
&lt;br /&gt;
==== PyCharm ====&lt;br /&gt;
&lt;br /&gt;
 http://www.pycharm.com/&lt;br /&gt;
&lt;br /&gt;
=== Hide Console ===&lt;br /&gt;
&lt;br /&gt;
fork() does not work on windows.  So what else can we do?&lt;br /&gt;
&lt;br /&gt;
How to hide console window in python? - http://stackoverflow.com/questions/764631/how-to-hide-console-window-in-python&lt;br /&gt;
* &amp;quot;Simply save it with a .pyw extension. This will prevent the console window from opening. Explanation at the bottom of section [http://docs.python.org/2/tutorial/interpreter.html#executable-python-scripts]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== 32bit vs 64bit ===&lt;br /&gt;
&lt;br /&gt;
IDLE:&lt;br /&gt;
&lt;br /&gt;
32bit:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
C:\Python27&amp;gt;python&lt;br /&gt;
Python 2.7.6 (default, Nov 10 2013, 19:24:18) [MSC v.1500 32 bit (Intel)] on win32&lt;br /&gt;
Type &amp;quot;help&amp;quot;, &amp;quot;copyright&amp;quot;, &amp;quot;credits&amp;quot; or &amp;quot;license&amp;quot; for more information.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
64bit: (note: default path is C:\Python27)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
C:\Python27-64bit&amp;gt;python.exe&lt;br /&gt;
Python 2.7.6 (default, Nov 10 2013, 19:24:24) [MSC v.1500 64 bit (AMD64)] on win32&lt;br /&gt;
Type &amp;quot;help&amp;quot;, &amp;quot;copyright&amp;quot;, &amp;quot;credits&amp;quot; or &amp;quot;license&amp;quot; for more information.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Task Manager:&lt;br /&gt;
 python.exe *32&lt;br /&gt;
&lt;br /&gt;
 python.exe&lt;br /&gt;
&lt;br /&gt;
Platform:&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; import platform&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; platform.python_compiler()&lt;br /&gt;
 &#039;MSC v.1500 32 bit (Intel)&#039;&lt;br /&gt;
&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; import platform&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; platform.python_compiler()&lt;br /&gt;
 &#039;MSC v.1500 64 bit (AMD64)&#039;&lt;br /&gt;
&lt;br /&gt;
Code: [http://stackoverflow.com/questions/2208828/detect-64bit-os-windows-in-python]&lt;br /&gt;
 import struct&lt;br /&gt;
 def is_python_64bit():&lt;br /&gt;
     return (struct.calcsize(&amp;quot;P&amp;quot;) == 8)&lt;br /&gt;
&lt;br /&gt;
=== Stand-Alone Executable ===&lt;br /&gt;
&lt;br /&gt;
==== Python ZIP Application ====&lt;br /&gt;
&lt;br /&gt;
Python can be run from a single bundled zip file - similar to a Java WAR!  Python has been able to (Allow interpreter to execute a zip file http://bugs.python.org/issue1739468)&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Python quietly added a new feature in 2.6 that makes it possible to bundle up a directory full of Python code into a single executable file.&amp;quot; [http://blog.ablepear.com/2012/10/bundling-python-files-into-stand-alone.html]&lt;br /&gt;
&lt;br /&gt;
When a python zip application is executed, it will execute &#039;__main__.py&#039; [http://docs.python.org/using/cmdline.html#interface-options]&lt;br /&gt;
&lt;br /&gt;
 mkdir app&lt;br /&gt;
 touch app/__main__.py&lt;br /&gt;
 cd app&lt;br /&gt;
 zip -r ../app.zip *&lt;br /&gt;
 cd ..&lt;br /&gt;
 python app.zip&lt;br /&gt;
&lt;br /&gt;
Load a resource - The easiest way to find and load a program bundle like this is to use the pkg_resources module. - http://packages.python.org/distribute/pkg_resources.html&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# file: app/__main__.py&lt;br /&gt;
&lt;br /&gt;
import pkg_resources&lt;br /&gt;
&lt;br /&gt;
def main():&lt;br /&gt;
  print(&#039;The rain in Spain falls mainly in the plain.&#039;)&lt;br /&gt;
  print(pkg_resources.resource_string(&#039;resources&#039;, &#039;inFrance.txt&#039;))&lt;br /&gt;
&lt;br /&gt;
if __name__ == &#039;__main__&#039;:&lt;br /&gt;
  main()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now use a bit of UNIX magic to turn app2.zip into an executable:&lt;br /&gt;
 echo &#039;#!/usr/bin/env python&#039; | cat - app2.zip &amp;gt; app2&lt;br /&gt;
 chmod +x app2&lt;br /&gt;
&lt;br /&gt;
&amp;quot;The zip file format is designed to allow a small executable program to be inserted at the front (that&#039;s how self-extracting zip files are created), so this is kosher and doesn&#039;t corrupt the zip file.&amp;quot; [http://blog.ablepear.com/2012/10/bundling-python-files-into-stand-alone.html]&lt;br /&gt;
&lt;br /&gt;
Now you can simply run app2 like any executable.&lt;br /&gt;
 $ ./app2&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* Able Pear Software: Bundling Python files into a stand-alone executable - http://blog.ablepear.com/2012/10/bundling-python-files-into-stand-alone.html&lt;br /&gt;
* PEP 441 -- Improving Python ZIP Application Support - http://www.python.org/dev/peps/pep-0441/&lt;br /&gt;
* Issue 1739468: Allow interpreter to execute a zip file - Python tracker - http://bugs.python.org/issue1739468&lt;br /&gt;
* Package Discovery and Resource Access using pkg_resources — Distribute documentation - http://packages.python.org/distribute/pkg_resources.html&lt;br /&gt;
&lt;br /&gt;
==== Shell Python Loader ====&lt;br /&gt;
&lt;br /&gt;
Came before the Python ZIP Application support.&lt;br /&gt;
&lt;br /&gt;
Python zip exe - Noah.org - http://www.noah.org/wiki/Python_zip_exe&lt;br /&gt;
&lt;br /&gt;
&amp;quot;This takes your Python application and packages it into a single executable shell script. You application can be made of up multiple python scripts. The executable shell script is also compressed, so the resulting script is smaller than the original. This should work on any system that has Python and a Bourne shell (works on Cygwin too). Note that this does not package the Python interpreter into the executable. This packages only you python code into a zip file, but this still allows you to distribute your application as a single shell script that will run on any system with Python installed.  In theory, you could zip the .pyc files, but the byte code is guaranteed to run only on exactly the same version Python interpreter (including minor version). It is safer to just package the .py files.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
First you need to zip all your python files:&lt;br /&gt;
 zip main.zip main.py spam.py eggs.py&lt;br /&gt;
&lt;br /&gt;
zipheader.sh:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/sh&lt;br /&gt;
# This is a self-extracting executable.&lt;br /&gt;
# Execute this like any normal executable.&lt;br /&gt;
# You may need to &amp;quot;chmod a+x&amp;quot; this file.&lt;br /&gt;
# This is a binary ZIP file with a Python loader header.&lt;br /&gt;
#&lt;br /&gt;
# Bourne shell loader:&lt;br /&gt;
PYTHON=$(which python 2&amp;gt;/dev/null)&lt;br /&gt;
if [ ! -x &amp;quot;$PYTHON&amp;quot; ] ; then&lt;br /&gt;
    echo &amp;quot;Python not found!&amp;quot;&lt;br /&gt;
    exit 1&lt;br /&gt;
fi&lt;br /&gt;
exec $PYTHON -c &amp;quot;&lt;br /&gt;
# Python loader:&lt;br /&gt;
import sys, os&lt;br /&gt;
if int(sys.version[0])&amp;lt;2:&lt;br /&gt;
    print &#039;Python version 2.3 final or greater is required.&#039;&lt;br /&gt;
    print &#039;Your version is&#039;, sys.version&lt;br /&gt;
    os._exit(1)&lt;br /&gt;
major = sys.version_info[0]&lt;br /&gt;
minor = sys.version_info[1]&lt;br /&gt;
releaselevel = sys.version_info[3]&lt;br /&gt;
if (major==2 and minor&amp;lt;3) or (major==2 and minor==3 and releaselevel!=&#039;final&#039;):&lt;br /&gt;
    print &#039;Python version 2.3 final or greater is required.&#039;&lt;br /&gt;
    print &#039;Your version is&#039;, sys.version&lt;br /&gt;
    os._exit(1)&lt;br /&gt;
sys.path.insert(0, sys.argv[1])&lt;br /&gt;
del sys.argv[0:1]&lt;br /&gt;
import main&lt;br /&gt;
main.main()&lt;br /&gt;
&amp;quot; $0 $@&lt;br /&gt;
# Zip file:&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Concatinate zipheader.sh with the zip file.&lt;br /&gt;
 cat zipheader.sh main.zip &amp;gt; main&lt;br /&gt;
&lt;br /&gt;
Set main as executable.&lt;br /&gt;
 chmod +x main&lt;br /&gt;
&lt;br /&gt;
&amp;quot;This is an improvement on Joerg Raedler&#039;s Python recipe, [http://code.activestate.com/recipes/215301-binding-main-skript-and-modules-to-one-executable-/ 215301]. The original closes stdin. The herefile in the shell script redirects stdin before python gets a chance to start. This disables raw_input() and anything else that reads sys.stdin. Unfortunately, Raedler&#039;s boot script closes stdin, which is a fairly big limitation. The herefile in the shell script (END_OF_PYTHON_CODE) redirects stdin before python starts; stdin is closed at the end of the herefile. This disables raw_input() and anything else that reads sys.stdin. &amp;quot;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* Python zip exe - Noah.org - http://www.noah.org/wiki/Python_zip_exe&lt;br /&gt;
* Build a compressed self-extracting executable script on UNIX « Python recipes « ActiveState Code - http://code.activestate.com/recipes/497000-build-a-compressed-self-extracting-executable-scri/&lt;br /&gt;
* binding main skript and modules to one executable with python-2.3 under UNIX « Python recipes « ActiveState Code - http://code.activestate.com/recipes/215301-binding-main-skript-and-modules-to-one-executable-/&lt;br /&gt;
&lt;br /&gt;
==== py2exe ====&lt;br /&gt;
&lt;br /&gt;
py2exe - http://www.py2exe.org/&lt;br /&gt;
: &amp;quot;py2exe is a Python Distutils extension which converts Python scripts into executable Windows programs, able to run without requiring a Python installation. &amp;quot;&lt;br /&gt;
&lt;br /&gt;
Tutorial - http://www.py2exe.org/index.cgi/Tutorial&lt;br /&gt;
&lt;br /&gt;
Note: Install the version that matches your version of python&lt;br /&gt;
&lt;br /&gt;
Note: run installer &amp;quot;as administrator&amp;quot;&lt;br /&gt;
&lt;br /&gt;
setup.py&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from distutils.core import setup&lt;br /&gt;
import py2exe&lt;br /&gt;
&lt;br /&gt;
setup(console=[&#039;hello.py&#039;])&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
No console window version: [http://ubuntuforums.org/showthread.php?t=728170] [http://stackoverflow.com/questions/3275293/hiding-console-window-of-python-gui-app-with-py2exe]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from distutils.core import setup&lt;br /&gt;
import py2exe&lt;br /&gt;
&lt;br /&gt;
setup(windows=[&#039;hello.py&#039;])&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Build:&lt;br /&gt;
 python setup.py py2exe&lt;br /&gt;
&lt;br /&gt;
pygame is more complex: http://www.pygame.org/wiki/Pygame2exe&lt;br /&gt;
&lt;br /&gt;
==== py2app ====&lt;br /&gt;
&lt;br /&gt;
==== pyinstaller ====&lt;br /&gt;
&lt;br /&gt;
==== cx_Freeze ====&lt;br /&gt;
&lt;br /&gt;
=== Windows Libraries ===&lt;br /&gt;
&lt;br /&gt;
==== Python for Windows Extensions - PyWin32 ====&lt;br /&gt;
&lt;br /&gt;
Python for Windows Extensions - http://starship.python.net/~skippy/win32/&lt;br /&gt;
* There is a build for each python version and architecture (32bit vs 64bit)&lt;br /&gt;
&lt;br /&gt;
Follow event viewer&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import win32evtlog  # install Python for Windows Extensions - http://starship.python.net/~skippy/win32/&lt;br /&gt;
&lt;br /&gt;
# open event viewer&lt;br /&gt;
server = &amp;quot;localhost&amp;quot;&lt;br /&gt;
source = &amp;quot;System&amp;quot;&lt;br /&gt;
handle = win32evtlog.OpenEventLog(server, source)&lt;br /&gt;
&lt;br /&gt;
# seek to end of log&lt;br /&gt;
flags = win32evtlog.EVENTLOG_BACKWARDS_READ | win32evtlog.EVENTLOG_SEQUENTIAL_READ&lt;br /&gt;
events = win32evtlog.ReadEventLog(handle, flags, 0)&lt;br /&gt;
&lt;br /&gt;
# return to normal reading direction&lt;br /&gt;
flags = win32evtlog.EVENTLOG_FORWARDS_READ | win32evtlog.EVENTLOG_SEQUENTIAL_READ&lt;br /&gt;
win32evtlog.ReadEventLog(handle, flags, 0)  # ignore initial logs&lt;br /&gt;
&lt;br /&gt;
# loop through events&lt;br /&gt;
while True:&lt;br /&gt;
    events = win32evtlog.ReadEventLog(handle, flags, 0)&lt;br /&gt;
    if events:&lt;br /&gt;
        for event in events:&lt;br /&gt;
            data = event.StringInserts&lt;br /&gt;
            if data:&lt;br /&gt;
                # Example: 07/03/14 12:34:35 - MYEVENTSOURCE - 0 - 1 - 4  &amp;quot;HELLO&amp;quot;&lt;br /&gt;
                print event.TimeGenerated, &#039;-&#039;, event.SourceName, &#039;-&#039;, event.EventCategory, &#039;-&#039;, event.EventID, &#039;-&#039;, event.EventType, &#039;-&#039;, &#039;&amp;quot;%s&amp;quot;&#039; % &amp;quot; &amp;quot;.join(data)&lt;br /&gt;
    time.sleep(.5)  # yield cpu&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* PyWin32: Getting Windows Event Logs « The Mouse Vs. The Python - http://www.blog.pythonlibrary.org/2010/07/27/pywin32-getting-windows-event-logs/&lt;br /&gt;
&lt;br /&gt;
==== PyCrypto for Windows ====&lt;br /&gt;
&lt;br /&gt;
Download Install: http://www.voidspace.org.uk/python/modules.shtml#pycrypto&lt;br /&gt;
&lt;br /&gt;
Installation: [http://stackoverflow.com/questions/11405549/how-do-i-install-pycrypto-on-windows]&lt;br /&gt;
 easy_install http://www.voidspace.org.uk/downloads/pycrypto26/pycrypto-2.6.win32-py2.7.exe&lt;br /&gt;
 easy_install http://www.voidspace.org.uk/downloads/pycrypto26/pycrypto-2.6.win-amd64-py2.7.exe&lt;br /&gt;
&lt;br /&gt;
==== Paramiko for Windows ====&lt;br /&gt;
&lt;br /&gt;
# Install PyCrypto (above)&lt;br /&gt;
# pip install paramiko&lt;br /&gt;
&lt;br /&gt;
==== PyGame for Windows ====&lt;br /&gt;
&lt;br /&gt;
Download - http://www.pygame.org/download.shtml&lt;br /&gt;
* http://pygame.org/ftp/pygame-1.9.1.win32-py2.7.msi&lt;br /&gt;
&lt;br /&gt;
== Indentation ==&lt;br /&gt;
&lt;br /&gt;
Python: Myths about Indentation - http://www.secnetix.de/olli/Python/block_indentation.hawk&lt;br /&gt;
:There are quite some prejudices and myths about Python&#039;s indentation rules among people who don&#039;t really know Python. I&#039;ll try to address a few of these concerns on this page. &lt;br /&gt;
*&amp;quot;Whitespace is significant in Python source code.&amp;quot;&lt;br /&gt;
*&amp;quot;Python forces me to use a certain indentation style.&amp;quot;&lt;br /&gt;
*&amp;quot;You cannot safely mix tabs and spaces in Python.&amp;quot;&lt;br /&gt;
*&amp;quot;I just don&#039;t like it.&amp;quot;&lt;br /&gt;
*&amp;quot;How does the compiler parse the indentation?&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== PEP - Python Enhancement Proposals ==&lt;br /&gt;
&lt;br /&gt;
Python Enhancement Proposals (PEPs)&lt;br /&gt;
&lt;br /&gt;
* Index of Python Enhancement Proposals (PEPs) - http://www.python.org/dev/peps/&lt;br /&gt;
&lt;br /&gt;
== Convert Tabs to Spaces ==&lt;br /&gt;
&lt;br /&gt;
Convert tabs to 4 spaces:&lt;br /&gt;
 sed -i &#039;s/\t/    /g&#039;  script.py&lt;br /&gt;
&lt;br /&gt;
== Linting ==&lt;br /&gt;
&lt;br /&gt;
* pep8 - python style guide checker&lt;br /&gt;
* pychecker - more verbose, imports code, slower&lt;br /&gt;
* pylint - most verbose, configurable, &amp;quot;rates&amp;quot; code&lt;br /&gt;
* pyflakes - least verbose (dead/redundant code)&lt;br /&gt;
&lt;br /&gt;
rpmforge:&lt;br /&gt;
 yum install pyflakes pychecker&lt;br /&gt;
 # pylint - not sure which pacakge includes&lt;br /&gt;
&lt;br /&gt;
=== pep8 ===&lt;br /&gt;
&lt;br /&gt;
See [[Python/pep8]]&lt;br /&gt;
&lt;br /&gt;
=== pychecker ===&lt;br /&gt;
&lt;br /&gt;
See [[Python/pychecker]]&lt;br /&gt;
&lt;br /&gt;
=== pylint ===&lt;br /&gt;
&lt;br /&gt;
See [[Python/pylint]]&lt;br /&gt;
&lt;br /&gt;
== PEP8 Style Guidlines ==&lt;br /&gt;
&lt;br /&gt;
PEP 8 -- Style Guide for Python Code - http://www.python.org/dev/peps/pep-0008/&lt;br /&gt;
&lt;br /&gt;
* Use spaces - Use 4 spaces per indentation level.&lt;br /&gt;
* Never mix tabs and spaces.&lt;br /&gt;
* Limit all lines to a maximum of 79 characters.&lt;br /&gt;
* Line wrapping - The preferred way of wrapping long lines is by using Python&#039;s implied line continuation inside parentheses, brackets and braces.  Long lines can be broken over multiple lines by wrapping expressions in parentheses.&lt;br /&gt;
* Encoding - For Python 3.0 and beyond, UTF-8 is preferred over Latin-1, see PEP 3120.&lt;br /&gt;
* Imports should usually be on separate lines&lt;br /&gt;
* Avoid extraneous whitespace in most situations&lt;br /&gt;
* Always use &#039;self&#039; for the first argument to instance methods.&lt;br /&gt;
&lt;br /&gt;
=== PEP8 Style Checker ===&lt;br /&gt;
&lt;br /&gt;
See [[#pep8]]&lt;br /&gt;
&lt;br /&gt;
== Benefits of Python ==&lt;br /&gt;
&lt;br /&gt;
What is the return on investment for this group by learning Python? The list of benefits below sums up what the language has to offer:&lt;br /&gt;
* Python is designed from the ground up to encourage maintainable, readable and reusable code. It has great support for particular paradigms such as object-oriented programming.&lt;br /&gt;
* Python code is usually around a quarter of the length of code generated by C++ or Java - less typing, less debugging and less maintenance.&lt;br /&gt;
* Python does not need to be compiled or linked, which allows for a more iterative programming style and a quicker development cycle.&lt;br /&gt;
* Python is extremely portable. Code can be easily exchanged between Windows, Mac OS and Linux with little to no modification.&lt;br /&gt;
* Python comes with a staggering array of standard libraries and mature third-party projects. Web development, scientific computing, operator system access and network scripting are all supported.&lt;br /&gt;
* Python can talk with many other languages easily. It has support for invoking C and C++ code and can itself be called from libraries written in these languages. &lt;br /&gt;
&lt;br /&gt;
Source: http://quantstart.com/articles/Quant-Reading-List-Python-Programming/ - Quant Reading List Python Programming&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Benefits of Python:&lt;br /&gt;
* Python is available for most operating systems, including Windows, UNIX, Linux, and Mac OS.&lt;br /&gt;
* Python&#039;s clean object-oriented design and extensive support libraries offer two to ten fold the programmer productivity seen with languages like C, C++, C#, Java, VB, and Perl.&lt;br /&gt;
&lt;br /&gt;
Source: Python Development - Benefits of Python - Digital Mesh - http://www.digitalmesh.com/offshore-development-center/python-development/benefits-of-python.html&lt;br /&gt;
&lt;br /&gt;
== Python Package Management ==&lt;br /&gt;
&lt;br /&gt;
=== Install Module ===&lt;br /&gt;
&lt;br /&gt;
Installing Python Modules — Python v2.7.1 documentation - http://docs.python.org/install/index.html&lt;br /&gt;
&lt;br /&gt;
The new standard: Distutils&lt;br /&gt;
 python setup.py install&lt;br /&gt;
&lt;br /&gt;
Download and extract target package, then:&lt;br /&gt;
 sudo python setup.py install&lt;br /&gt;
&lt;br /&gt;
Note: Running setup.py install builds and installs all modules in one run&lt;br /&gt;
&lt;br /&gt;
Help:&lt;br /&gt;
 python setup.py --help&lt;br /&gt;
&lt;br /&gt;
Incremental method:&lt;br /&gt;
 python setup.py build&lt;br /&gt;
 python setup.py install&lt;br /&gt;
 python setup.py build --help   # help&lt;br /&gt;
&lt;br /&gt;
Force rebuild and install:&lt;br /&gt;
 python setup.py build --force    # if have to repeat&lt;br /&gt;
 python setup.py install --force  # if have to repeat&lt;br /&gt;
&lt;br /&gt;
Default installation paths:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Platform	Standard installation location		Default value&lt;br /&gt;
Unix (pure)	prefix/lib/pythonX.Y/site-packages	/usr/local/lib/pythonX.Y/site-packages&lt;br /&gt;
Unix (non-pure)	exec-prefix/lib/pythonX.Y/site-packages	/usr/local/lib/pythonX.Y/site-packages&lt;br /&gt;
Windows		prefix					C:\Python&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alternate install path:&lt;br /&gt;
 python setup.py install --home=&amp;lt;dir&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alternate base folders:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Type of file			Installation Directory	Override option&lt;br /&gt;
pure module distribution	home/lib/python		--install-purelib&lt;br /&gt;
non-pure module distribution	home/lib/python		--install-platlib&lt;br /&gt;
scripts				home/bin		--install-scripts&lt;br /&gt;
data				home/share		--install-data&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Modifying Python’s Search Path:&lt;br /&gt;
 import sys&lt;br /&gt;
 sys.path.append(&#039;/www/python/&#039;)&lt;br /&gt;
&lt;br /&gt;
=== Python Package Index ===&lt;br /&gt;
&lt;br /&gt;
user-submitted Python packages:&lt;br /&gt;
 http://pypi.python.org/pypi&lt;br /&gt;
&lt;br /&gt;
 sudo python setup.py install&lt;br /&gt;
&lt;br /&gt;
Package Site:&lt;br /&gt;
 http://pypi.python.org/pypi/[PACKAGE]&lt;br /&gt;
 http://pypi.python.org/pypi/test&lt;br /&gt;
&lt;br /&gt;
If they are on http://pypi.python.org/:&lt;br /&gt;
 pip install foo&lt;br /&gt;
&lt;br /&gt;
[http://stackoverflow.com/questions/410163/for-python-programmers-is-there-anything-equivalent-to-perls-cpan For Python programmers, is there anything equivalent to Perl&#039;s CPAN? - Stack Overflow]&lt;br /&gt;
&lt;br /&gt;
=== Easy Installation ===&lt;br /&gt;
&lt;br /&gt;
EasyInstall - The PEAK Developers&#039; Center - http://peak.telecommunity.com/DevCenter/EasyInstall&lt;br /&gt;
: Easy Install is a python module (easy_install) bundled with setuptools that lets you automatically download, build, install, and manage Python packages.&lt;br /&gt;
&lt;br /&gt;
CheeseShopTutorial - PythonInfo Wiki - http://wiki.python.org/moin/CheeseShopTutorial&lt;br /&gt;
: EasyInstall (easy_install) gives you a quick and painless way to install packages remotely by connecting to the Package Index or even other websites via HTTP. It is somewhat analogous to the CPAN and PEAR tools for Perl and PHP, respectively.&lt;br /&gt;
&lt;br /&gt;
=== pip ===&lt;br /&gt;
&lt;br /&gt;
See [[Python/pip]]&lt;br /&gt;
&lt;br /&gt;
==== Create PIP Package ====&lt;br /&gt;
&lt;br /&gt;
See [[Python/pip#Create PIP Package]]&lt;br /&gt;
&lt;br /&gt;
=== Distribute ===&lt;br /&gt;
&lt;br /&gt;
distribute - Easily download, build, install, upgrade, and uninstall Python packages&lt;br /&gt;
&lt;br /&gt;
distribute 0.6.24 : Python Package Index - http://pypi.python.org/pypi/distribute&lt;br /&gt;
&lt;br /&gt;
Installation:&lt;br /&gt;
 mkdir -p ~/.src ; cd ~/.src&lt;br /&gt;
 wget http://pypi.python.org/packages/source/d/distribute/distribute-0.6.24.tar.gz#md5=17722b22141aba8235787f79800cc452&lt;br /&gt;
 tar -zvxf distribute-0.6.24.tar.gz&lt;br /&gt;
 cd distribute-0.6.24&lt;br /&gt;
 sudo python setup.py install&lt;br /&gt;
&lt;br /&gt;
Test:&lt;br /&gt;
 echo &amp;quot;import distribute&amp;quot; | grep python&lt;br /&gt;
&lt;br /&gt;
== Named Parameters ==&lt;br /&gt;
&lt;br /&gt;
http://diveintopython.org/power_of_introspection/optional_arguments.html&lt;br /&gt;
&lt;br /&gt;
Python allows function arguments to have default values; if the function is called without the argument, the argument gets its default value. Futhermore, arguments can be specified in any order by using named arguments. Stored procedures in SQL Server Transact/SQL can do this, so if you&#039;re a SQL Server scripting guru, you can skim this part.&lt;br /&gt;
&lt;br /&gt;
Here is an example of info, a function with two optional arguments:&lt;br /&gt;
&lt;br /&gt;
 def info(object, spacing=10, collapse=1):&lt;br /&gt;
&lt;br /&gt;
spacing and collapse are optional, because they have default values defined. object is required, because it has no default value. If info is called with only one argument, spacing defaults to 10 and collapse defaults to 1. If info is called with two arguments, collapse still defaults to 1.&lt;br /&gt;
&lt;br /&gt;
Say you want to specify a value for collapse but want to accept the default value for spacing. In most languages, you would be out of luck, because you would need to call the function with three arguments. But in Python, arguments can be specified by name, in any order. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
http://www.wellho.net/mouth/1871_Optional-and-named-parameters-in-Python.html&lt;br /&gt;
&lt;br /&gt;
If you add a parameter with two asterixes (**) on the end of a function definition, that parameter is taken as being the name of a dictionary into which all otherwise unidentified parameters are stored. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def getnet(gross, taxrate=17.5, **others):&lt;br /&gt;
  net = gross / (1.0 + taxrate*0.01)&lt;br /&gt;
  for more in others.keys():&lt;br /&gt;
    print &amp;quot;GETNET:&amp;quot;,more,&amp;quot; - &amp;quot;,others[more]&lt;br /&gt;
  return neto&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Python vs other languages ==&lt;br /&gt;
&lt;br /&gt;
[http://www.strombergers.com/python/ Python is Cool (and Perl is not), Especially for C/C++ Programmers]&lt;br /&gt;
&lt;br /&gt;
==Experimenting with Memory Remanence==&lt;br /&gt;
[http://citp.princeton.edu/memory/exp/ Experimenting with Memory Remanence]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    #!/usr/bin/env python&lt;br /&gt;
&lt;br /&gt;
    # a pirate&#039;s favorite chemical element&lt;br /&gt;
    a = &amp;quot;&amp;quot;&lt;br /&gt;
    while 1: a += &amp;quot;ARGON&amp;quot; &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 sudo strings /dev/mem | less&lt;br /&gt;
&lt;br /&gt;
==UTOSC 2008 - 90 percent of the Python you need to know (in 90 minutes)==&lt;br /&gt;
See [[UTOSC 2008 - 90 percent of the Python you need to know (in 90 minutes)]]&lt;br /&gt;
&lt;br /&gt;
== Program Layout Best Practices Presentation ==&lt;br /&gt;
&lt;br /&gt;
Program layout best practices - Seth House &amp;lt;seth@eseth.com&amp;gt; - Utah Django User Group - 2011-06-23&lt;br /&gt;
* Slides - https://github.com/whiteinge/presentations/tree/master/upyug_2011-06-09_program-layout&lt;br /&gt;
* Video - http://blip.tv/utah-open-source/python-layout-best-practices-for-modules-django-cli-utah-django-user-group-5315808&lt;br /&gt;
&lt;br /&gt;
Module skeleton:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
# coding: utf-8&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;Module docstring&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
__author__ = ’Mr. Me &amp;lt;me@example.net&amp;gt;’&lt;br /&gt;
__version__ = ’1.2.3’&lt;br /&gt;
&lt;br /&gt;
if __name__==’__main__’:&lt;br /&gt;
 main()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Executing modules as scripts&lt;br /&gt;
 # PEP 338:&lt;br /&gt;
 python -m SimpleHTTPServer&lt;br /&gt;
&lt;br /&gt;
== CLI package ==&lt;br /&gt;
&lt;br /&gt;
cli — command line tools — pyCLI v1.1.1 documentation - http://packages.python.org/pyCLI/&lt;br /&gt;
&lt;br /&gt;
== Python IDE ==&lt;br /&gt;
&lt;br /&gt;
IntegratedDevelopmentEnvironments - PythonInfo Wiki - http://wiki.python.org/moin/IntegratedDevelopmentEnvironments&lt;br /&gt;
* IDEs with introspection-based code completion and integrated debugger&lt;br /&gt;
* IDEs with introspection-based code completion /or/ integrated debugger&lt;br /&gt;
* IDEs with integrated gui builder&lt;br /&gt;
* Editors&lt;br /&gt;
* Reviews&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Is there a good, free Python IDE for Windows? - Stack Overflow - http://stackoverflow.com/questions/126753/is-there-a-good-free-python-ide-for-windows&lt;br /&gt;
* Eclipse with PyDev&lt;br /&gt;
* Aptana Studio 3&lt;br /&gt;
* Active State also offers Komodo Edit&lt;br /&gt;
* WingWare - http://www.wingware.com/&lt;br /&gt;
* Eric IDE - http://www.die-offenbachs.de/eric/index.html&lt;br /&gt;
* MMM-Experts - Products - http://mmm-experts.com/Products.aspx?ProductId=4&lt;br /&gt;
** PyScripter is a Python IDE built in Python for Delphi(P4D) components and created with the ambition to become competitive in functionality with commercial Windows-based IDEs available for other languages. Being built in a compiled language is rather snappier than some of the other Python IDEs and provides an extensive blend of features that make it a productive Python development environment. &lt;br /&gt;
* ActiveState Python comes with PythonWin which is reasonably good&lt;br /&gt;
* PyCharm from JetBrains is not free in general, but has free early access program.&lt;br /&gt;
* SPE - Stani&#039;s Python Editor, is pretty awesome. See http://pythonide.blogspot.com/.&lt;br /&gt;
* You may want to take a look at the pdb module - http://docs.python.org/lib/module-pdb.html&lt;br /&gt;
* Geany (http://www.geany.org/) is a fairly light text editor that does a lot of IDE-like stuff.&lt;br /&gt;
* SciTE: http://www.scintilla.org/SciTE.html&lt;br /&gt;
* Editra: http://editra.org/ &lt;br /&gt;
* Netbeans has support for python development in their Python Early Access version. - http://www.netbeans.org/features/python/&lt;br /&gt;
* I use Notepad++ with the appropriate settings.&lt;br /&gt;
* The Eric Python IDE - http://www.die-offenbachs.de/eric/index.html&lt;br /&gt;
* BOa Constructor www.boa-constructor.sourceforge.net really nice! drag and drop stuff!&lt;br /&gt;
* DrPtyhon is also very nice, and has many plug-ins. http://drpython.sourceforge.net/&lt;br /&gt;
* Vim&lt;br /&gt;
* I will make a plug for my preference of Python development environments: SPE. SPE is an integrated development environment that provides code completion, integrated Python shell, calltips, and various helper tools like notes and todo lists. It also includes wxGlade so you can make wxPython applications easily. Plus, it includes the python debugger WinPdb.&lt;br /&gt;
* http://groups.google.com.tr/group/python_opengl this software is my sample visual python ide.its demo version.&lt;br /&gt;
* I use PyScripter, and find it pretty awesome.&lt;br /&gt;
* There is one Python IDE written in Java: jHepWork: http://jwork.org/jhepwork/ it can detect Python&#039;s indentation rules rather nicely (+ detects structure of a code and syntax)&lt;br /&gt;
* gvim built with your python version support and with this plugins:&lt;br /&gt;
** NERDTree (don&#039;t read he&#039;s blog ;)&lt;br /&gt;
** matchit (it&#039;s builtin in new versions just put a symlink or junction)&lt;br /&gt;
** pyflakes&lt;br /&gt;
** pysmell&lt;br /&gt;
* Try Python Tools for Visual Studio. Supports CPython and IronPython. - http://pytools.codeplex.com/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
PythonEditors - PythonInfo Wiki - http://wiki.python.org/moin/PythonEditors&lt;br /&gt;
* List of editors&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Python Ide - http://c2.com/cgi/wiki?PythonIde&lt;br /&gt;
: There are a lot of Ides for PythonLanguage springing up. Many of them written in Python &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Is there a better Python IDE? « Lennart Regebro: Python, Plone, Web - http://regebro.wordpress.com/2010/10/09/is-there-a-better-python-ide/&lt;br /&gt;
: I’m currently a user of WingIDE, but sometimes I feel the need for something better, mainly something that is a bit more stable. WingIDE often hangs when switching projects, sometimes the file listing decides that you must double-click on the expand arrow instead of just click on it, etc. It still doesn’t have macros despite this being a much requested feature (how hard can it be to add, really?) and I never really get the hang of the SVN integration, so I just ignore it. And they keep recommending me to use WingIDE’s separate instance of GTK instead of the System GTK, which is daft. Their designs are ugly, and it should work with the system GTK so it looks the same. Anything else is just silly.&lt;br /&gt;
&lt;br /&gt;
=== Open Komodo ===&lt;br /&gt;
&lt;br /&gt;
Open Komodo - http://www.openkomodo.com/&lt;br /&gt;
: Open Komodo is the source code repository for Komodo Edit - a free multi-language editor for dynamic languages, based on the award-winning Komodo IDE. ActiveState created the Open Komodo code repository in August 2007 and it has been used since then for building all Komodo Edit releases.&lt;br /&gt;
&lt;br /&gt;
=== Eclipse ===&lt;br /&gt;
&lt;br /&gt;
Build an Eclipse development environment for Perl, Python, and PHP - http://www.eclipse.org/resources/resource.php?id=485&lt;br /&gt;
: This tutorial shows how Eclipse&#039;s DLTK makes it possible to build development tools for scripting languages. In particular, it explains how to implement syntax coloring, user preferences, and interpreter integration in a plug-in-based project.&lt;br /&gt;
&lt;br /&gt;
See [[#PyDev]]&lt;br /&gt;
&lt;br /&gt;
=== EasyEclipse ===&lt;br /&gt;
&lt;br /&gt;
EasyEclipse - http://www.easyeclipse.org/&lt;br /&gt;
:EasyEclipse packages together Eclipse, the open-source software&lt;br /&gt;
development platform, and selected open source plugins.&lt;br /&gt;
:We select, assemble, test, patch, build installers and document&lt;br /&gt;
a full IDE, offered as reliable distributions and plugins.&lt;br /&gt;
:EasyEclipse is:&lt;br /&gt;
* Free and open-source,&lt;br /&gt;
* Easy to download and install, and&lt;br /&gt;
* Simple to maintain, without version and dependency issues.&lt;br /&gt;
&lt;br /&gt;
EasyEclipse for Python - http://www.easyeclipse.org/site/distributions/python.html&lt;br /&gt;
&lt;br /&gt;
EclipsePythonIntegration - PythonInfo Wiki - http://wiki.python.org/moin/EclipsePythonIntegration&lt;br /&gt;
: Using Eclipse as a Python editor&lt;br /&gt;
&lt;br /&gt;
=== PyDev ===&lt;br /&gt;
&lt;br /&gt;
PyDev - http://pydev.org/&lt;br /&gt;
: PyDev is a Python IDE for Eclipse, which may be used in Python, Jython and IronPython development.&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
Pydev - http://pydev.sourceforge.net/ (old link)&lt;br /&gt;
&lt;br /&gt;
How to Configure Eclipse for Python - http://www.rose-hulman.edu/class/csse/resources/Eclipse/eclipse-python-configuration.htm&lt;br /&gt;
&lt;br /&gt;
Python Development with PyDev and Eclipse - Tutorial - http://www.vogella.de/articles/Python/article.html&lt;br /&gt;
: This article describes how to write and debug Python programs with Eclipse&lt;br /&gt;
&lt;br /&gt;
PyDev Getting Started - http://pydev.org/manual_101_root.html&lt;br /&gt;
&lt;br /&gt;
Running a program - http://pydev.org/manual_101_run.html&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
Supported Task Tags:&lt;br /&gt;
* TODO:&lt;br /&gt;
* TASK:&lt;br /&gt;
* FIXME:&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
Installation:&lt;br /&gt;
# Platform Runtime Binary (download around 45-50 MB) - http://download.eclipse.org/eclipse/downloads/ or http://www.eclipse.org/downloads/&lt;br /&gt;
#* Example: Eclipse Classic 4.2.2&lt;br /&gt;
# Eclipse Software Add - PyDev: http://pydev.org/updates&lt;br /&gt;
# Eclipse Software Add - MercurialEclipse: http://cbes.javaforge.com/update  [http://javaforge.com/project/HGE] [http://mercurial.selenic.com/wiki/MercurialEclipse]&lt;br /&gt;
# Switch perspectives to PyDev&lt;br /&gt;
&lt;br /&gt;
=== The Eric Python IDE ===&lt;br /&gt;
&lt;br /&gt;
The Eric Python IDE - http://eric-ide.python-projects.org/&lt;br /&gt;
:Eric is a full featured Python and Ruby editor and IDE, written in python. It is based on the cross platform Qt gui toolkit, integrating the highly flexible Scintilla editor control. It is designed to be usable as everdays&#039; quick and dirty editor as well as being usable as a professional project management tool integrating many advanced features Python offers the professional coder. eric4 includes a plugin system, which allows easy extension of the IDE functionality with plugins downloadable from the net.&lt;br /&gt;
&lt;br /&gt;
Eric Python IDE - Wikipedia - http://en.wikipedia.org/wiki/Eric_Python_IDE&lt;br /&gt;
&lt;br /&gt;
=== Wingware Python IDE ===&lt;br /&gt;
&lt;br /&gt;
The Intelligent Development Environment for Python Programmers - Wingware Python IDE - http://www.wingware.com/&lt;br /&gt;
:Wingware&#039;s Python IDE is an Integrated Development Environment designed specifically for the Python programming language. Since 1999, Wingware has focused on Python.&lt;br /&gt;
&lt;br /&gt;
=== VIM ===&lt;br /&gt;
&lt;br /&gt;
Python .vimrc:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;quot; Kenneth&#039;s Preferences&lt;br /&gt;
&lt;br /&gt;
set nobackup            &amp;quot; don&#039;t create backup files&lt;br /&gt;
&amp;quot;set nohlsearch          &amp;quot; don&#039;t highlight search results&lt;br /&gt;
set hlsearch            &amp;quot; do highlight search results&lt;br /&gt;
set incsearch           &amp;quot; incremental search&lt;br /&gt;
set ignorecase          &amp;quot; ignore case during search&lt;br /&gt;
set smartcase           &amp;quot; do case sensitive search when upper case is typed&lt;br /&gt;
set shiftwidth=4        &amp;quot; shift blocks in 4 space increments&lt;br /&gt;
set tabstop=4           &amp;quot; the (typewriter) tab stops are every 4 spaces&lt;br /&gt;
set smarttab            &amp;quot; tab at beginning of line inserts 4 spaces (shiftwidth)&lt;br /&gt;
set showmatch           &amp;quot; briefly highlight matching bracket&lt;br /&gt;
set matchtime=1         &amp;quot; highlight match for 0.1 seconds&lt;br /&gt;
set background=dark     &amp;quot; black background&lt;br /&gt;
set shiftwidth=4        &amp;quot; shift blocks by 4 spaces&lt;br /&gt;
set shortmess=at        &amp;quot; use short messages so we don&#039;t have to hit enter&lt;br /&gt;
set expandtab           &amp;quot; expand tabs into spaces&lt;br /&gt;
set scrolloff=5         &amp;quot; always show 5 lines before &amp;amp; after cursor&lt;br /&gt;
set shell=bash          &amp;quot; use bash for the command shell&lt;br /&gt;
set shellcmdflag=-lc    &amp;quot; make bash startup as a login shell for ~/.bashrc&lt;br /&gt;
&amp;quot;set nowrap              &amp;quot; do not wrap long lines&lt;br /&gt;
set visualbell          &amp;quot; flash the screen rather than beep&lt;br /&gt;
set noerrorbells        &amp;quot; don&#039;t beep on errors&lt;br /&gt;
set wildmenu            &amp;quot; enable filename tab completion&lt;br /&gt;
set ruler               &amp;quot; display the ruler: shows cursor position&lt;br /&gt;
set cpoptions+=$        &amp;quot; display &#039;$&#039; at end of cw sequence&lt;br /&gt;
set title               &amp;quot; display filename and vim info in window title bar&lt;br /&gt;
set modelines=5         &amp;quot; search the first and last 5 lines for &amp;quot;vim:&amp;quot; modeline&lt;br /&gt;
set backspace=2         &amp;quot; backspace deletes&lt;br /&gt;
&lt;br /&gt;
set wildignore=*.o,*.class,*.pyc,*.pyo,*.a,*.so,*.dll,*.exe,core,*.jar,*.zip&lt;br /&gt;
&lt;br /&gt;
&amp;quot;let loaded_matchparen = 1 &amp;quot; don&#039;t highlight parenthesis match&lt;br /&gt;
&lt;br /&gt;
filetype indent on&lt;br /&gt;
&lt;br /&gt;
&amp;quot;if v:version &amp;gt; 700&lt;br /&gt;
&amp;quot;    set cursorline          &amp;quot; underline the current line&lt;br /&gt;
&amp;quot;endif&lt;br /&gt;
&lt;br /&gt;
if &amp;amp;t_Co &amp;gt; 2 || has( &amp;quot;gui_running&amp;quot; )&lt;br /&gt;
    syntax on&lt;br /&gt;
endif&lt;br /&gt;
&lt;br /&gt;
if has( &#039;mouse&#039; )&lt;br /&gt;
    set mouse=a &amp;quot; enable mouse&lt;br /&gt;
endif&lt;br /&gt;
&lt;br /&gt;
if has( &amp;quot;autocmd&amp;quot; )&lt;br /&gt;
    &amp;quot; open the file in the last place we were editing&lt;br /&gt;
    autocmd BufReadPost *&lt;br /&gt;
        \ if line(&amp;quot;&#039;\&amp;quot;&amp;quot;) &amp;gt; 1 &amp;amp;&amp;amp; line(&amp;quot;&#039;\&amp;quot;&amp;quot;) &amp;lt;= line(&amp;quot;$&amp;quot;) |&lt;br /&gt;
        \     exe &amp;quot;normal! g&#039;\&amp;quot;&amp;quot; |&lt;br /&gt;
        \ endif&lt;br /&gt;
endif&lt;br /&gt;
&lt;br /&gt;
&amp;quot;folding settings&lt;br /&gt;
set foldmethod=indent   &amp;quot;fold based on indent&lt;br /&gt;
set foldnestmax=10      &amp;quot;deepest fold is 10 levels&lt;br /&gt;
set nofoldenable        &amp;quot;dont fold by default&lt;br /&gt;
set foldlevel=10        &amp;quot;this is just what i use&lt;br /&gt;
&lt;br /&gt;
&amp;quot; Auto clear trailing white space in Python files&lt;br /&gt;
func! DeleteTrailingWS()&lt;br /&gt;
    exec &amp;quot;normal mz&amp;quot;&lt;br /&gt;
    %s/\s\+$//ge&lt;br /&gt;
    exe &amp;quot;normal `z&amp;quot;&lt;br /&gt;
endfunc&lt;br /&gt;
autocmd BufWrite *.py :call DeleteTrailingWS()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Older versions:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;quot; KENNETH SETTINGS&lt;br /&gt;
set nocp                &amp;quot; turn off compatibility mode&lt;br /&gt;
set nomodeline          &amp;quot; do not allow files to dictate vim behavior&lt;br /&gt;
&lt;br /&gt;
set incsearch           &amp;quot; incremental search&lt;br /&gt;
set ignorecase          &amp;quot; ignore case during search&lt;br /&gt;
&lt;br /&gt;
set visualbell          &amp;quot; flash the screen rather than beep&lt;br /&gt;
set noerrorbells        &amp;quot; don&#039;t beep on errors&lt;br /&gt;
set background=dark     &amp;quot; black background&lt;br /&gt;
syntax on               &amp;quot; turn on syntax highlighting&lt;br /&gt;
set hlsearch            &amp;quot; highligh last search pattern&lt;br /&gt;
&lt;br /&gt;
set nowrap              &amp;quot; do not wrap long lines&lt;br /&gt;
set scrolloff=5         &amp;quot; always show 5 lines before &amp;amp; after cursor&lt;br /&gt;
set ruler               &amp;quot; show the cursor position all the time&lt;br /&gt;
set backspace=2         &amp;quot; allow backspace deletion&lt;br /&gt;
set bs=indent,eol,start &amp;quot; allow backspacing over everything in insert mode&lt;br /&gt;
&lt;br /&gt;
set shiftwidth=4        &amp;quot; shift blocks in 4 space increments&lt;br /&gt;
set tabstop=4           &amp;quot; the (typewriter) tab stops are every 4 spaces&lt;br /&gt;
set expandtab           &amp;quot; expand tab into spaces&lt;br /&gt;
set smarttab            &amp;quot; tab at beginning of line inserts 4 spaces (shiftwidth)&lt;br /&gt;
filetype indent on      &amp;quot; turn on auto indent for specific file types&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Other options:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
set number              &amp;quot; show line numbers&lt;br /&gt;
set numberwidth=1       &amp;quot; remove space before largest line numbers&lt;br /&gt;
&lt;br /&gt;
set smartindent         &amp;quot; ?? - maybe included in &#039;filetype indent on&#039;&lt;br /&gt;
&lt;br /&gt;
set ai                  &amp;quot; always auto indent&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
if has( &amp;quot;autocmd&amp;quot; )&lt;br /&gt;
    &amp;quot; open the file in the last place we were editing&lt;br /&gt;
    autocmd BufReadPost *&lt;br /&gt;
        \ if line(&amp;quot;&#039;\&amp;quot;&amp;quot;) &amp;gt; 1 &amp;amp;&amp;amp; line(&amp;quot;&#039;\&amp;quot;&amp;quot;) &amp;lt;= line(&amp;quot;$&amp;quot;) |&lt;br /&gt;
        \     exe &amp;quot;normal! g&#039;\&amp;quot;&amp;quot; |&lt;br /&gt;
        \ endif&lt;br /&gt;
endif&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Kenneth&#039;s fio .vimrc:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;quot;source $VIM/mswin.vim&lt;br /&gt;
&lt;br /&gt;
set nobackup            &amp;quot; don&#039;t create backup files&lt;br /&gt;
&amp;quot;set nohlsearch          &amp;quot; don&#039;t highlight search results&lt;br /&gt;
set incsearch           &amp;quot; incremental search&lt;br /&gt;
set ignorecase          &amp;quot; ignore case during search&lt;br /&gt;
set smartcase           &amp;quot; do case sensitive search when upper case is typed&lt;br /&gt;
set shiftwidth=4        &amp;quot; shift blocks in 4 space increments&lt;br /&gt;
set tabstop=4           &amp;quot; the (typewriter) tab stops are every 4 spaces&lt;br /&gt;
set smarttab            &amp;quot; tab at beginning of line inserts 4 spaces (shiftwidth)&lt;br /&gt;
set showmatch           &amp;quot; briefly highlight matching bracket&lt;br /&gt;
set matchtime=1         &amp;quot; highlight match for 0.1 seconds&lt;br /&gt;
set background=dark     &amp;quot; black background&lt;br /&gt;
set shiftwidth=4        &amp;quot; shift blocks by 4 spaces&lt;br /&gt;
set shortmess=at        &amp;quot; use short messages so we don&#039;t have to hit enter&lt;br /&gt;
set expandtab           &amp;quot; expand tabs into spaces&lt;br /&gt;
set scrolloff=5         &amp;quot; always show 5 lines before &amp;amp; after cursor&lt;br /&gt;
set shell=bash          &amp;quot; use bash for the command shell&lt;br /&gt;
set shellcmdflag=-lc    &amp;quot; make bash startup as a login shell for ~/.bashrc&lt;br /&gt;
&amp;quot;set nowrap              &amp;quot; do not wrap long lines&lt;br /&gt;
set visualbell          &amp;quot; flash the screen rather than beep&lt;br /&gt;
set noerrorbells        &amp;quot; don&#039;t beep on errors&lt;br /&gt;
set wildmenu            &amp;quot; enable filename tab completion&lt;br /&gt;
set ruler               &amp;quot; display the ruler: shows cursor position&lt;br /&gt;
set cpoptions+=$        &amp;quot; display &#039;$&#039; at end of cw sequence&lt;br /&gt;
set title               &amp;quot; display filename and vim info in window title bar&lt;br /&gt;
set modelines=5         &amp;quot; search the first and last 5 lines for &amp;quot;vim:&amp;quot; modeline&lt;br /&gt;
&lt;br /&gt;
set wildignore=*.o,*.class,*.pyc,*.pyo,*.a,*.so,*.dll,*.exe,core,*.jar,*.zip&lt;br /&gt;
&lt;br /&gt;
&amp;quot;let loaded_matchparen = 1 &amp;quot; don&#039;t highlight parenthesis match&lt;br /&gt;
&lt;br /&gt;
filetype indent on&lt;br /&gt;
&lt;br /&gt;
if v:version &amp;gt; 700&lt;br /&gt;
    set cursorline          &amp;quot; underline the current line&lt;br /&gt;
endif&lt;br /&gt;
&lt;br /&gt;
if &amp;amp;t_Co &amp;gt; 2 || has( &amp;quot;gui_running&amp;quot; )&lt;br /&gt;
    syntax on&lt;br /&gt;
endif&lt;br /&gt;
&lt;br /&gt;
if has( &#039;mouse&#039; )&lt;br /&gt;
    set mouse=a &amp;quot; enable mouse&lt;br /&gt;
endif&lt;br /&gt;
&lt;br /&gt;
if has( &amp;quot;autocmd&amp;quot; )&lt;br /&gt;
    &amp;quot; open the file in the last place we were editing&lt;br /&gt;
    autocmd BufReadPost *&lt;br /&gt;
        \ if line(&amp;quot;&#039;\&amp;quot;&amp;quot;) &amp;gt; 1 &amp;amp;&amp;amp; line(&amp;quot;&#039;\&amp;quot;&amp;quot;) &amp;lt;= line(&amp;quot;$&amp;quot;) |&lt;br /&gt;
        \     exe &amp;quot;normal! g&#039;\&amp;quot;&amp;quot; |&lt;br /&gt;
        \ endif&lt;br /&gt;
endif&lt;br /&gt;
&lt;br /&gt;
&amp;quot;folding settings&lt;br /&gt;
set foldmethod=indent   &amp;quot;fold based on indent&lt;br /&gt;
set foldnestmax=10      &amp;quot;deepest fold is 10 levels&lt;br /&gt;
set nofoldenable        &amp;quot;dont fold by default&lt;br /&gt;
set foldlevel=10        &amp;quot;this is just what i use&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Interpreter vs Script ==&lt;br /&gt;
&lt;br /&gt;
Interpreter:&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; import os&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; os.uname()&lt;br /&gt;
 (&#039;Linux&#039;, &#039;demo.oeey.com&#039;, &#039;2.6.18-194.8.1.el5&#039;, &#039;#1 SMP Thu Jul 1 19:07:06 EDT 2010&#039;, &#039;i686&#039;)&lt;br /&gt;
&lt;br /&gt;
Script:&lt;br /&gt;
 #!/usr/bin/env python&lt;br /&gt;
 import os&lt;br /&gt;
 print os.uname()&lt;br /&gt;
&lt;br /&gt;
== Web Development ==&lt;br /&gt;
&lt;br /&gt;
WebProgramming - PythonInfo Wiki - http://wiki.python.org/moin/WebProgramming&lt;br /&gt;
: This topic guide attempts to cover every aspect of programming Web applications (both clients and servers) using Python. &lt;br /&gt;
&lt;br /&gt;
HOWTO Use Python in the web — Python v2.7.2 documentation - http://docs.python.org/howto/webservers.html&lt;br /&gt;
: This document shows how Python fits into the web. It presents some ways to integrate Python with a web server, and general practices useful for developing web sites.&lt;br /&gt;
&lt;br /&gt;
=== Plug Simple Python Web App ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
-------- Original Message --------&lt;br /&gt;
Subject: 	Re: Writing a simple python web app&lt;br /&gt;
Date: 	Mon, 25 Oct 2010 19:03:31 -0400&lt;br /&gt;
From: 	Roberto Mello &amp;lt;roberto.mello@gmail.com&amp;gt;&lt;br /&gt;
To: 	Provo Linux Users Group &amp;lt;plug@plug.org&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
On Sat, Sep 11, 2010 at 5:40 PM, Dave Smith &amp;lt;dave@thesmithfam.org&amp;gt; wrote:&lt;br /&gt;
&amp;gt; I&#039;m creating a very simple web application, and I want to use python. My first guess was that mod_python&lt;br /&gt;
would provide the easiest entry point. Boy, was I wrong. All the mod_python tutorials spend 80% of their&lt;br /&gt;
time extolling the virtues of mod_python over CGI, but they are quite lean on specific examples. It&#039;s quite&lt;br /&gt;
disappointing. A natural progression then leads me to mod_wsgi, and since that has equally poor&lt;br /&gt;
documentation, to Django. However, Django is overkill for my app (I don&#039;t even have a database).&lt;br /&gt;
&lt;br /&gt;
For something as simple as you have described, and to run on an&lt;br /&gt;
embedded platform, I would probably stay away from frameworks designed&lt;br /&gt;
to run on full hardware, and go with something more minimalistic.&lt;br /&gt;
&lt;br /&gt;
Take a look at CherryPy [1] or web.py [2].&lt;br /&gt;
&lt;br /&gt;
[1] http://www.cherrypy.org/&lt;br /&gt;
[2] http://webpy.org/&lt;br /&gt;
&lt;br /&gt;
Roberto Mello&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
See also [[web.py]]&lt;br /&gt;
&lt;br /&gt;
See also [[CherryPy]]&lt;br /&gt;
&lt;br /&gt;
See also [[Django]]&lt;br /&gt;
&lt;br /&gt;
=== Apache CGI ===&lt;br /&gt;
&lt;br /&gt;
See [[CGI]]&lt;br /&gt;
&lt;br /&gt;
Great tutorial: https://www.tutorialspoint.com/python/python_cgi_programming.htm&lt;br /&gt;
&lt;br /&gt;
My favorite option, make all .cgi files executable: (or .py)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 DirectoryIndex index.html index.php index.py&lt;br /&gt;
 &amp;lt;Location /&amp;gt;&lt;br /&gt;
   # AddHandler cgi-script .cgi&lt;br /&gt;
   AddHandler cgi-script .py&lt;br /&gt;
   Options +ExecCGI &lt;br /&gt;
 &amp;lt;/Location&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you want to allow .htaccess:&lt;br /&gt;
* see [[Apache#.htaccess]]&lt;br /&gt;
&lt;br /&gt;
To enable on Ubuntu:&lt;br /&gt;
 sudo a2enmod cgi&lt;br /&gt;
 service apache2 restart&lt;br /&gt;
&lt;br /&gt;
Directory index:&lt;br /&gt;
 DirectoryIndex index.py&lt;br /&gt;
&lt;br /&gt;
Or if you really want to go crazy, this will try to run *every* file: [http://blog.kapsobor.de/archives/2006/09/05/apache_addhandler_multiple_extensions/]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    # this has problems with / directory being run as a script, instead of index too!&lt;br /&gt;
    #&amp;lt;Location /&amp;gt;&lt;br /&gt;
    #    SetHandler cgi-script&lt;br /&gt;
    #    Options +ExecCGI&lt;br /&gt;
    #&amp;lt;/Location&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;Files ~ &amp;quot;.&amp;quot;&amp;gt;&lt;br /&gt;
        SetHandler cgi-script&lt;br /&gt;
        Options +ExecCGI&lt;br /&gt;
    &amp;lt;/Files&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    &amp;lt;Files ~ &amp;quot;^.[a-zA-Z]*$&amp;quot;&amp;gt;&lt;br /&gt;
        SetHandler cgi-script&lt;br /&gt;
        Options +ExecCGI&lt;br /&gt;
    &amp;lt;/Files&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Or just have index file:&lt;br /&gt;
    &amp;lt;Files &amp;quot;index&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: Place within a &amp;lt;VirtualHost&amp;gt; section if needed.&lt;br /&gt;
&lt;br /&gt;
Note: Make sure to &#039;chmod +x&#039; the files.&lt;br /&gt;
&lt;br /&gt;
Start all HTML output with:&lt;br /&gt;
 print &amp;quot;Content-Type: text/html\n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If you want just text output:&lt;br /&gt;
 print &amp;quot;Content-Type: text/plain\n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
GET (from Environment):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
print &amp;quot;&amp;amp;lt;pre&amp;gt;&amp;quot;&lt;br /&gt;
for env in os.environ:&lt;br /&gt;
    print &amp;quot;%s = %s&amp;quot; % (env, os.environ[env])&lt;br /&gt;
print &amp;quot;&amp;amp;lt;/pre&amp;gt;&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# sample for: http://oeey.com/py/test.py/test?var1=ken&amp;amp;var2=barbie&lt;br /&gt;
&lt;br /&gt;
REQUEST_URI = /py/index.py/test?var1=ken&amp;amp;var2=barbie&lt;br /&gt;
QUERY_STRING = var1=ken&amp;amp;var2=barbie&lt;br /&gt;
PATH_INFO = /test&lt;br /&gt;
REQUEST_METHOD = GET&lt;br /&gt;
&lt;br /&gt;
SCRIPT_NAME = /py/test.py&lt;br /&gt;
SERVER_NAME = oeey.com&lt;br /&gt;
REMOTE_ADDR = 216.51.42.66&lt;br /&gt;
SERVER_ADDR = 192.168.108.4&lt;br /&gt;
DOCUMENT_ROOT = /www/py&lt;br /&gt;
SCRIPT_FILENAME = /www/py/test.py&lt;br /&gt;
HTTP_HOST = cgi.oeey.com&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
POST (from stdin):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
post = sys.stdin.readline()&lt;br /&gt;
if post:&lt;br /&gt;
    print post&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CONTENT_TYPE = application/x-www-form-urlencoded&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
yin=one+two+three&amp;amp;yang=four+five+six&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
cgi helper class:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import cgi&lt;br /&gt;
&lt;br /&gt;
print &amp;quot;Content-Type: text/html\n\n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
form = cgi.FieldStorage()&lt;br /&gt;
&lt;br /&gt;
# field keys&lt;br /&gt;
print &amp;quot;fields keys: &amp;quot;, form.keys()  # list of field keys&lt;br /&gt;
&lt;br /&gt;
# fild values&lt;br /&gt;
if &amp;quot;name&amp;quot; in form:  # if form.has_key(&#039;name&#039;):&lt;br /&gt;
    print &amp;quot;field &#039;name&#039; is: &amp;quot;, form[&amp;quot;name&amp;quot;].value&lt;br /&gt;
    print &amp;quot;field &#039;name&#039; is: &amp;quot;, form.getvalue(&#039;name&#039;)&lt;br /&gt;
&lt;br /&gt;
# headers&lt;br /&gt;
print &amp;quot;dictionary of headers: &amp;quot;, form.headers&lt;br /&gt;
print form.type&lt;br /&gt;
print form.headers[&#039;content-type&#039;]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To prevent XSS escape the characters:&lt;br /&gt;
  print cgi.escape(form.getvalue(&#039;name&#039;))&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import cgi&lt;br /&gt;
&lt;br /&gt;
print &amp;quot;Content-Type: text/html\n\n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
form = cgi.FieldStorage()&lt;br /&gt;
if (form.has_key(&amp;quot;action&amp;quot;) and form.has_key(&amp;quot;name&amp;quot;) \&lt;br /&gt;
        and form.has_key(&amp;quot;age&amp;quot;)):&lt;br /&gt;
    if (form[&amp;quot;action&amp;quot;].value == &amp;quot;display&amp;quot;):&lt;br /&gt;
        print &amp;quot;%s = %s&amp;quot; % (form[&amp;quot;name&amp;quot;].value form[&amp;quot;age&amp;quot;].value)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: cgi helper class also does sessions and cookies.&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* CGI Tutorial | Web Python - http://webpython.codepoint.net/cgi_tutorial&lt;br /&gt;
* Python CGI: An Interactive Instruction - http://www.cs.virginia.edu/~lab2q/&lt;br /&gt;
&lt;br /&gt;
See also:&lt;br /&gt;
* Web Python - http://webpython.codepoint.net/&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
REST Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import os, re&lt;br /&gt;
def get_rest():&lt;br /&gt;
    if not &amp;quot;PATH_INFO&amp;quot; in os.environ:&lt;br /&gt;
        return ()&lt;br /&gt;
    # filter for garbage&lt;br /&gt;
    #print os.environ[&amp;quot;PATH_INFO&amp;quot;]&lt;br /&gt;
    path_info = re.findall(&#039;[/A-Za-z0-9_-]*&#039;, os.environ[&amp;quot;PATH_INFO&amp;quot;])&lt;br /&gt;
    if not path_info:&lt;br /&gt;
        return ()&lt;br /&gt;
    path_info = &#039;&#039;.join(path_info)&lt;br /&gt;
    # collapse empty paths&lt;br /&gt;
    paths = path_info.split(&#039;/&#039;)&lt;br /&gt;
    final_paths = []&lt;br /&gt;
    for path in paths:&lt;br /&gt;
        if path:&lt;br /&gt;
            final_paths.append(path)&lt;br /&gt;
    return tuple(final_paths)&lt;br /&gt;
rest = get_rest();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== mod_python ===&lt;br /&gt;
&lt;br /&gt;
AVOID! AVOID! AVOID! - if you want this simple, just use CGI!&lt;br /&gt;
&lt;br /&gt;
See [[Apache mod_python]]&lt;br /&gt;
&lt;br /&gt;
mod_python - http://docs.python.org/howto/webservers.html#mod-python&lt;br /&gt;
&lt;br /&gt;
Install:&lt;br /&gt;
 yum install mod_python&lt;br /&gt;
&lt;br /&gt;
Config:&lt;br /&gt;
 /etc/httpd/conf.d/python.conf&lt;br /&gt;
&lt;br /&gt;
Simple:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;quot;People coming from PHP often find it hard to grasp how to use Python in the web. Their first thought is mostly mod_python, because they think that this is the equivalent to mod_php. Actually, there are many differences. What mod_python does is embed the interpreter into the Apache process, thus speeding up requests by not having to start a Python interpreter for each request. On the other hand, it is not “Python intermixed with HTML” in the way that PHP is often intermixed with HTML. The Python equivalent of that is a template engine. mod_python itself is much more powerful and provides more access to Apache internals. It can emulate CGI, work in a “Python Server Pages” mode (similar to JSP) which is “HTML intermingled with Python”, and it has a “Publisher” which designates one file to accept all requests and decide what to do with them.&lt;br /&gt;
&lt;br /&gt;
:mod_python does have some problems. Unlike the PHP interpreter, the Python interpreter uses caching when executing files, so changes to a file will require the web server to be restarted. Another problem is the basic concept – Apache starts child processes to handle the requests, and unfortunately every child process needs to load the whole Python interpreter even if it does not use it. This makes the whole web server slower. Another problem is that, because mod_python is linked against a specific version of libpython, it is not possible to switch from an older version to a newer (e.g. 2.4 to 2.5) without recompiling mod_python. mod_python is also bound to the Apache web server, so programs written for mod_python cannot easily run on other web servers.&lt;br /&gt;
&lt;br /&gt;
:These are the reasons why mod_python should be avoided when writing new programs. In some circumstances it still might be a good idea to use mod_python for deployment, but WSGI makes it possible to run WSGI programs under mod_python as well.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== WSGI ===&lt;br /&gt;
&lt;br /&gt;
WSGI - http://docs.python.org/howto/webservers.html#mod-wsgi&lt;br /&gt;
&lt;br /&gt;
: &amp;quot;The Web Server Gateway Interface, or WSGI for short, is defined in PEP 333 and is currently the best way to do Python web programming. While it is great for programmers writing frameworks, a normal web developer does not need to get in direct contact with it. When choosing a framework for web development it is a good idea to choose one which supports WSGI.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
See [[mod_wsgi]]&lt;br /&gt;
&lt;br /&gt;
=== Django ===&lt;br /&gt;
&lt;br /&gt;
See [[Django]]&lt;br /&gt;
&lt;br /&gt;
=== CherryPy ===&lt;br /&gt;
&lt;br /&gt;
See [[CherryPy]]&lt;br /&gt;
&lt;br /&gt;
=== web.py ===&lt;br /&gt;
&lt;br /&gt;
web.py: makes web apps&lt;br /&gt;
&lt;br /&gt;
Think about the ideal way to write a web app. Write the code to make it happen.&lt;br /&gt;
&lt;br /&gt;
web.py : Python Package Index - http://pypi.python.org/pypi/web.py&lt;br /&gt;
&lt;br /&gt;
Home Page: http://webpy.org/&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Django lets you write web apps in Django. TurboGears lets you write web apps in TurboGears. Web.py lets you write web apps in Python.&amp;quot;&lt;br /&gt;
:—  Adam Atlas&lt;br /&gt;
&lt;br /&gt;
NOTE: Can modify source code without having to restart app!  :-)&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
PIP Install:&lt;br /&gt;
 pip install web.py&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
Hello World: [http://webpy.org/]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import web&lt;br /&gt;
        &lt;br /&gt;
urls = (&lt;br /&gt;
    &#039;/(.*)&#039;, &#039;hello&#039;&lt;br /&gt;
)&lt;br /&gt;
app = web.application(urls, globals())&lt;br /&gt;
&lt;br /&gt;
class hello:        &lt;br /&gt;
    def GET(self, name):&lt;br /&gt;
        if not name: &lt;br /&gt;
            name = &#039;World&#039;&lt;br /&gt;
        return &#039;Hello, &#039; + name + &#039;!&#039;&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
    app.run()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: app.py can be renamed.&lt;br /&gt;
&lt;br /&gt;
Running:&lt;br /&gt;
 python app.py&lt;br /&gt;
&lt;br /&gt;
Note: You can add an IP address/port after the &amp;quot;app.py&amp;quot; bit to control where web.py launches the server. You can also tell it to run a fastcgi or scgi server.&lt;br /&gt;
 python app.py 1234&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
Templates&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# templates/hello.html&lt;br /&gt;
$def with (name)&lt;br /&gt;
&lt;br /&gt;
$if name:&lt;br /&gt;
    I just wanted to say &amp;lt;em&amp;gt;hello&amp;lt;/em&amp;gt; to $name.&lt;br /&gt;
$else:&lt;br /&gt;
    &amp;lt;em&amp;gt;Hello&amp;lt;/em&amp;gt;, world!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 app = ...&lt;br /&gt;
 render = web.template.render(&#039;templates/&#039;)&lt;br /&gt;
&lt;br /&gt;
index.GET:&lt;br /&gt;
 name = &#039;Bob&#039;    &lt;br /&gt;
 return render.hello(name)  # render.[TEMPLATE_NAME](vars)&lt;br /&gt;
&lt;br /&gt;
get variable: (/?name=Joe)&lt;br /&gt;
 i = web.input(name=None)&lt;br /&gt;
 return render.hello(i.name)&lt;br /&gt;
&lt;br /&gt;
variable in url:&lt;br /&gt;
 urls = (&#039;/(.*)&#039;, &#039;hello&#039;)&lt;br /&gt;
&lt;br /&gt;
 class index:&lt;br /&gt;
     def GET(self, name):&lt;br /&gt;
        return render.hello(name)&lt;br /&gt;
&lt;br /&gt;
 # visit: /Joe&lt;br /&gt;
&lt;br /&gt;
multiple variables in url:&lt;br /&gt;
 urls = (&#039;/(.*)/(.*)&#039;, &#039;hello&#039;)&lt;br /&gt;
&lt;br /&gt;
  class hello:&lt;br /&gt;
    def GET(self, fname, lname):&lt;br /&gt;
        return render.hello(fname, lname)&lt;br /&gt;
&lt;br /&gt;
 # visit: /Joe/Smith&lt;br /&gt;
&lt;br /&gt;
=== lpthw.web ===&lt;br /&gt;
&lt;br /&gt;
lpthw.web: a fork of web.py for Learn Python The Hard Way&lt;br /&gt;
&lt;br /&gt;
Locks web.py at a specific version and removes some magic. Thanks to Aaron Swartz for making it originally.&lt;br /&gt;
&lt;br /&gt;
lpthw.web: a fork of web.py for Learn Python The Hard Way - http://pypi.python.org/pypi/lpthw.web&lt;br /&gt;
&lt;br /&gt;
Home Page: http://learnpythonthehardway.org/&lt;br /&gt;
&lt;br /&gt;
This conflicts with web.py, so only install one.&lt;br /&gt;
&lt;br /&gt;
=== web ===&lt;br /&gt;
&lt;br /&gt;
web - Web modules for CGI and WSGI web programming&lt;br /&gt;
&lt;br /&gt;
web : Python Package Index - http://pypi.python.org/pypi/web&lt;br /&gt;
&lt;br /&gt;
Warning: This is an alpha release for those who are interested in&lt;br /&gt;
    checking progress. No documentation and not for production use.&lt;br /&gt;
&lt;br /&gt;
Auth, session, mail, form and templating tools for writing CGI scripts or WSGI web applications.&lt;br /&gt;
&lt;br /&gt;
This version incompatible with previous versions becuase large portions of the code have been refactored into separate components.&lt;br /&gt;
&lt;br /&gt;
== Issues ==&lt;br /&gt;
&lt;br /&gt;
=== Hide DeprecationWarning ===&lt;br /&gt;
&lt;br /&gt;
==== Import DeprecationWarning ====&lt;br /&gt;
&lt;br /&gt;
Error:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/opt/xmpppy-0.4.1/xmpp/auth.py:24: DeprecationWarning: the sha module is deprecated; use the hashlib module instead&lt;br /&gt;
  import sha,base64,random,dispatcher,re&lt;br /&gt;
/opt/xmpppy-0.4.1/xmpp/auth.py:26: DeprecationWarning: the md5 module is deprecated; use hashlib instead&lt;br /&gt;
  import md5&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hide deprecation warnings with code: [http://stackoverflow.com/questions/879173/how-to-ignore-deprecation-warnings-in-python]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import warnings&lt;br /&gt;
&lt;br /&gt;
with warnings.catch_warnings():&lt;br /&gt;
    warnings.filterwarnings(&amp;quot;ignore&amp;quot;,category=DeprecationWarning)&lt;br /&gt;
    import md5, sha&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hide with header:&lt;br /&gt;
 #!/usr/bin/env python -W ignore::DeprecationWarning&lt;br /&gt;
&lt;br /&gt;
Hide from command line:&lt;br /&gt;
 python -W ignore::DeprecationWarning script.py&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* How to ignore deprecation warnings in Python - Stack Overflow - http://stackoverflow.com/questions/879173/how-to-ignore-deprecation-warnings-in-python&lt;br /&gt;
&lt;br /&gt;
==== Funciton DeprecationWarning ====&lt;br /&gt;
&lt;br /&gt;
Error:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/opt/xmpppy-0.4.1/xmpp/transports.py:307: DeprecationWarning: socket.ssl() is deprecated.  Use ssl.wrap_socket() instead.&lt;br /&gt;
  tcpsock._sslObj    = socket.ssl(tcpsock._sock, None, None)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hide with header:&lt;br /&gt;
 #!/usr/bin/env python -W ignore::DeprecationWarning&lt;br /&gt;
&lt;br /&gt;
Hide from command line:&lt;br /&gt;
 python -W ignore::DeprecationWarning script.py&lt;br /&gt;
&lt;br /&gt;
==== Ubuntu 24 pip packages ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
error: externally-managed-environment&lt;br /&gt;
&lt;br /&gt;
× This environment is externally managed&lt;br /&gt;
╰─&amp;gt; To install Python packages system-wide, try apt install&lt;br /&gt;
    python3-xyz, where xyz is the package you are trying to&lt;br /&gt;
    install.&lt;br /&gt;
&lt;br /&gt;
    If you wish to install a non-Debian-packaged Python package,&lt;br /&gt;
    create a virtual environment using python3 -m venv path/to/venv.&lt;br /&gt;
    Then use path/to/venv/bin/python and path/to/venv/bin/pip. Make&lt;br /&gt;
    sure you have python3-full installed.&lt;br /&gt;
&lt;br /&gt;
    If you wish to install a non-Debian packaged Python application,&lt;br /&gt;
    it may be easiest to use pipx install xyz, which will manage a&lt;br /&gt;
    virtual environment for you. Make sure you have pipx installed.&lt;br /&gt;
&lt;br /&gt;
    See /usr/share/doc/python3.12/README.venv for more information.&lt;br /&gt;
&lt;br /&gt;
note: If you believe this is a mistake, please contact your Python installation or OS distribution provider. You can override this, at the risk of breaking your Python installation or OS, by passing --break-system-packages.&lt;br /&gt;
hint: See PEP 668 for the detailed specification.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== keywords ==&lt;br /&gt;
&lt;br /&gt;
[[Category:Programming]]&lt;br /&gt;
[[Category:Python]]&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=Python&amp;diff=9870</id>
		<title>Python</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=Python&amp;diff=9870"/>
		<updated>2026-04-27T20:28:18Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: /* doc strings */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{subtop}}&lt;br /&gt;
&lt;br /&gt;
== Python ==&lt;br /&gt;
&lt;br /&gt;
Python (programming language) - Wikipedia - http://en.wikipedia.org/wiki/Python_(programming_language)&lt;br /&gt;
: Python is an interpreted, general-purpose high-level programming language whose design philosophy emphasizes code readability. Python aims to combine &amp;quot;remarkable power with very clear syntax&amp;quot;, and its standard library is large and comprehensive. Its use of indentation for block delimiters is unique among popular programming languages.&lt;br /&gt;
: Python supports multiple programming paradigms, primarily but not limited to object-oriented, imperative and, to a lesser extent, functional programming styles. It features a fully dynamic type system and automatic memory management, similar to that of Scheme, Ruby, Perl, and Tcl. Like other dynamic languages, Python is often used as a scripting language, but is also used in a wide range of non-scripting contexts.&lt;br /&gt;
: The reference implementation of Python ([http://en.wikipedia.org/wiki/CPython CPython]) is free and open source software and has a community-based development model, as do all or nearly all of its alternative implementations. CPython is managed by the non-profit Python Software Foundation.&lt;br /&gt;
: Python interpreters are available for many operating systems, and Python programs can be packaged into stand-alone executable code for many systems using various tools.&lt;br /&gt;
&lt;br /&gt;
Author:&lt;br /&gt;
:&amp;quot;Python was conceived in the late 1980s and its implementation was started in December 1989 by &#039;&#039;&#039;[http://www.python.org/~guido/ Guido van Rossum]&#039;&#039;&#039; at CWI in the Netherlands as a successor to the ABC programming language (itself inspired by SETL) capable of exception handling and interfacing with the Amoeba operating system. Van Rossum is Python&#039;s principal author, and his continuing central role in deciding the direction of Python is reflected in the title given to him by the Python community, Benevolent Dictator for Life (BDFL).&amp;quot; [http://en.wikipedia.org/wiki/Python_(programming_language)]&lt;br /&gt;
&lt;br /&gt;
Name:&lt;br /&gt;
:&amp;quot;The language is named after the BBC show “Monty Python’s Flying Circus” and has nothing to do with reptiles. Making references to Monty Python skits in documentation is not only allowed, it is encouraged!&amp;quot; [http://docs.python.org/py3k/tutorial/appetite.html]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
We as people are &amp;quot;Pythonites&amp;quot; [http://raspi.tv/2013/how-to-use-interrupts-with-python-on-the-raspberry-pi-and-rpi-gpio-part-2]&lt;br /&gt;
&lt;br /&gt;
== [http://www.python.org/dev/peps/pep-0020/ The Zen of Python] ==&lt;br /&gt;
&lt;br /&gt;
&amp;quot;The core philosophy of the language is summarized by the document &#039;PEP 20 (The Zen of Python)&#039;&amp;quot; [http://en.wikipedia.org/wiki/Python_%28programming_language%29]&lt;br /&gt;
* PEP 20 -- The Zen of Python - http://www.python.org/dev/peps/pep-0020/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Abstract&lt;br /&gt;
&lt;br /&gt;
    Long time Pythoneer Tim Peters succinctly channels the BDFL&#039;s&lt;br /&gt;
    guiding principles for Python&#039;s design into 20 aphorisms, only 19&lt;br /&gt;
    of which have been written down.&lt;br /&gt;
&lt;br /&gt;
The Zen of Python&lt;br /&gt;
&lt;br /&gt;
    Beautiful is better than ugly.&lt;br /&gt;
    Explicit is better than implicit.&lt;br /&gt;
    Simple is better than complex.&lt;br /&gt;
    Complex is better than complicated.&lt;br /&gt;
    Flat is better than nested.&lt;br /&gt;
    Sparse is better than dense.&lt;br /&gt;
    Readability counts.&lt;br /&gt;
    Special cases aren&#039;t special enough to break the rules.&lt;br /&gt;
    Although practicality beats purity.&lt;br /&gt;
    Errors should never pass silently.&lt;br /&gt;
    Unless explicitly silenced.&lt;br /&gt;
    In the face of ambiguity, refuse the temptation to guess.&lt;br /&gt;
    There should be one-- and preferably only one --obvious way to do it.&lt;br /&gt;
    Although that way may not be obvious at first unless you&#039;re Dutch.&lt;br /&gt;
    Now is better than never.&lt;br /&gt;
    Although never is often better than *right* now.&lt;br /&gt;
    If the implementation is hard to explain, it&#039;s a bad idea.&lt;br /&gt;
    If the implementation is easy to explain, it may be a good idea.&lt;br /&gt;
    Namespaces are one honking great idea -- let&#039;s do more of those!&lt;br /&gt;
&lt;br /&gt;
Easter Egg&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import this&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Other Sources:&lt;br /&gt;
* http://www.python.org/doc/humor/&lt;br /&gt;
* The Zen of Python – as a Poster « CODE POETRY - http://codepoetry.wordpress.com/2010/03/23/the-zen-of-python-as-a-poster/&lt;br /&gt;
** Zen of Python (PDF) http://codepoetry.files.wordpress.com/2010/03/zen-of-python.pdf&lt;br /&gt;
&lt;br /&gt;
== Documentation ==&lt;br /&gt;
&lt;br /&gt;
* Overview — Python v2.7.1 documentation - http://docs.python.org/index.html&lt;br /&gt;
** Download — Python v2.7.1 documentation - http://docs.python.org/download.html&lt;br /&gt;
&lt;br /&gt;
* Overview — Python v3.2 documentation - http://docs.python.org/py3k/&lt;br /&gt;
**  Download — Python v3.2 documentation - http://docs.python.org/py3k/download.html&lt;br /&gt;
&lt;br /&gt;
* PEP 8 -- Style Guide for Python Code - http://www.python.org/dev/peps/pep-0008/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Tutorials ==&lt;br /&gt;
&lt;br /&gt;
* The Python Tutorial — Python v2.7.1 documentation - http://docs.python.org/tutorial/&lt;br /&gt;
&lt;br /&gt;
* Python 101 -- Introduction to Python - http://www.rexx.com/~dkuhlman/python_101/python_101.html&lt;br /&gt;
&lt;br /&gt;
* 4. More Control Flow Tools — Python v2.7.1 documentation - http://docs.python.org/tutorial/controlflow.html&lt;br /&gt;
&lt;br /&gt;
== Linux Installation ==&lt;br /&gt;
&lt;br /&gt;
RHEL Distribution installation:&lt;br /&gt;
 yum -y install python python-setuptools&lt;br /&gt;
&lt;br /&gt;
Ubuntu Distribution installation: [https://help.ubuntu.com/community/Mercurial]&lt;br /&gt;
 # enable &#039;universe&#039; in the sources.list&lt;br /&gt;
 # &amp;quot;Mercurial is included in the Universe repository - activate this repo first&amp;quot;&lt;br /&gt;
 sudo apt-get install mercurial&lt;br /&gt;
&lt;br /&gt;
CentOS 5 Option Recommended Dependencies:&lt;br /&gt;
 yum -y install gcc make sudo readline-devel openssl-devel ncurses-devel zlib-devel gdbm-devel sqlite-devel bzip2-devel tk-devel tcl-devel&lt;br /&gt;
&lt;br /&gt;
 # this leaves: 2.6.6: _bsddb, bsddb185, dl, imageop, sunaudiodev&lt;br /&gt;
 # this leaves: 2.7.1: _bsddb, bsddb185, dl, imageop, sunaudiodev&lt;br /&gt;
 # this leaves: 3.2: none&lt;br /&gt;
&lt;br /&gt;
CentOS 9 Option Recommended Dependencies:&lt;br /&gt;
 # gdbm-devel not found in centos9?&lt;br /&gt;
 yum -y install gcc make sudo readline-devel openssl-devel ncurses-devel zlib-devel sqlite-devel bzip2-devel tk-devel tcl-devel&lt;br /&gt;
&lt;br /&gt;
Ubuntu 12.04 LTS 64bit dependencies:&lt;br /&gt;
 apt-get install gcc make sudo lib64bz2-dev tcl-dev lib64ncurses5-dev libssl-dev libreadline-dev tk-dev libsqlite3-dev libgdbm-dev&lt;br /&gt;
&lt;br /&gt;
 # maybe: lib64readline-dev libsqlite3-dev tk-dev&lt;br /&gt;
&lt;br /&gt;
 # this leaves: 2.7: _bsddb, bsddb185, dl, imageop, sunaudiodev&lt;br /&gt;
&lt;br /&gt;
=== 2.x ===&lt;br /&gt;
&lt;br /&gt;
CentOS dependencies:&lt;br /&gt;
 sudo yum -y install gcc make sudo readline-devel openssl-devel ncurses-devel zlib-devel gdbm-devel sqlite-devel bzip2-devel tk-devel tcl-devel&lt;br /&gt;
&lt;br /&gt;
Ubuntu 12.04 LTS 64bit dependencies:&lt;br /&gt;
 sudo apt-get update&lt;br /&gt;
 sudo apt-get install gcc make sudo lib64bz2-dev tcl-dev lib64ncurses5-dev libssl-dev libreadline-dev tk-dev libsqlite3-dev libgdbm-dev&lt;br /&gt;
&lt;br /&gt;
Ubuntu 24.04 LTS 64bit dependencies:&lt;br /&gt;
 sudo apt-get update&lt;br /&gt;
 sudo apt-get install gcc make sudo libbz2-dev tcl-dev libncurses-dev libssl-dev libreadline-dev tk-dev libsqlite3-dev libgdbm-dev libffi-dev&lt;br /&gt;
 # optional install&lt;br /&gt;
 sudo apt-get install checkinstall&lt;br /&gt;
&lt;br /&gt;
2.7.15:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#  PYVER=2.6.6&lt;br /&gt;
#  PYVER=2.7.5&lt;br /&gt;
#  PYVER=2.7.6&lt;br /&gt;
#  PYVER=2.7.9&lt;br /&gt;
#  PYVER=2.7.10&lt;br /&gt;
#  PYVER=2.7.15&lt;br /&gt;
PYVER=2.7.18&lt;br /&gt;
mkdir -p ~/.src ; cd ~/.src&lt;br /&gt;
wget --no-check-certificate http://www.python.org/ftp/python/$PYVER/Python-$PYVER.tgz&lt;br /&gt;
tar -zvxf Python-$PYVER.tgz&lt;br /&gt;
cd Python-$PYVER&lt;br /&gt;
#  ./configure --prefix=/opt/python-$PYVER&lt;br /&gt;
#  make clean &amp;amp;&amp;amp; make&lt;br /&gt;
./configure --prefix=/opt/python-$PYVER &amp;amp;&amp;amp; make clean &amp;amp;&amp;amp; make&lt;br /&gt;
sudo make install&lt;br /&gt;
&lt;br /&gt;
sudo /opt/python-$PYVER/bin/python -m ensurepip --upgrade&lt;br /&gt;
sudo /opt/python-$PYVER/bin/pip install --upgrade pip&lt;br /&gt;
sudo /opt/python-$PYVER/bin/pip install requests&lt;br /&gt;
&lt;br /&gt;
export PATH=/opt/python-$PYVER/bin:$PATH&lt;br /&gt;
echo -e &amp;quot;\n\nexport PATH=/opt/python-$PYVER/bin:\$PATH\n&amp;quot; &amp;gt;&amp;gt; ~/.bash_profile&lt;br /&gt;
#  echo -e &amp;quot;\n\nexport PATH=/opt/python27/bin:\$PATH\n&amp;quot; &amp;gt;&amp;gt; ~/.bashrc&lt;br /&gt;
&lt;br /&gt;
#  NOTE: remove any old versions from your .bash_profile&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Bootstrapping the pip installer - https://docs.python.org/2/library/ensurepip.html&lt;br /&gt;
&lt;br /&gt;
=== 3.x ===&lt;br /&gt;
&lt;br /&gt;
3.8.16:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#VER=3.7.0&lt;br /&gt;
#VER=3.8.15&lt;br /&gt;
#VER=3.10.9&lt;br /&gt;
VER=3.8.16&lt;br /&gt;
mkdir -p ~/.src ; cd ~/.src&lt;br /&gt;
wget http://www.python.org/ftp/python/${VER}/Python-${VER}.tgz&lt;br /&gt;
tar -zvxf Python-${VER}.tgz&lt;br /&gt;
cd Python-${VER}&lt;br /&gt;
./configure --prefix=/opt/python${VER}&lt;br /&gt;
make&lt;br /&gt;
&lt;br /&gt;
sudo make install&lt;br /&gt;
&lt;br /&gt;
## OPTIONAL alternative install path:&lt;br /&gt;
sudo checkinstall&lt;br /&gt;
## note: &#039;checkinstall&#039; makes a .deb, which you can uninstall with easier, but if you are using --prefix, you do need to&lt;br /&gt;
##       premake the folders&lt;br /&gt;
sudo mkdir -p /opt/python${VER}/bin&lt;br /&gt;
sudo mkdir -p /opt/python${VER}/lib&lt;br /&gt;
shortVER=`echo $VER | cut -d &#039;.&#039; -f 1-2`  # get short version eg. 3.10 from 3.10.9&lt;br /&gt;
sudo mkdir -p /opt/python${VER}/lib/python${shortVER}&lt;br /&gt;
sudo mkdir -p /opt/python${VER}/lib/python${shortVER}/test&lt;br /&gt;
# sudo checkinstall    # hit Y, and enter twice&lt;br /&gt;
## note: older versions have problems with the virtualization of the file system, so do FS Translation = no&lt;br /&gt;
checkinstall --fstrans=no&lt;br /&gt;
&lt;br /&gt;
export PATH=/opt/python${VER}/bin:$PATH&lt;br /&gt;
echo -e &amp;quot;\n\nexport PATH=/opt/python${VER}/bin:\$PATH\n&amp;quot; &amp;gt;&amp;gt; ~/.bash_profile&lt;br /&gt;
&lt;br /&gt;
# have to manually update version&lt;br /&gt;
rm /opt/python${VER}/bin/python&lt;br /&gt;
ln -sfn python3.8 /opt/python${VER}/bin/python&lt;br /&gt;
#cp /opt/python${VER}/bin/python3.8 /opt/python${VER}/bin/python&lt;br /&gt;
&lt;br /&gt;
# DEPENDENCIES&lt;br /&gt;
sudo apt install ...&lt;br /&gt;
yum install libffi-devel openssl-devel&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note, if you want the libraries to be shared (like python-dev):&lt;br /&gt;
 ./configure --enable-shared&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
 VER=3.6.9&lt;br /&gt;
&lt;br /&gt;
 VER=3.6.8&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
3.2.0:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir -p ~/src ; cd ~/src&lt;br /&gt;
wget http://www.python.org/ftp/python/3.2/Python-3.2.tgz&lt;br /&gt;
tar -zvxf Python-3.2.tgz&lt;br /&gt;
cd Python-3.2&lt;br /&gt;
./configure --prefix=/opt/python32&lt;br /&gt;
make&lt;br /&gt;
sudo make install&lt;br /&gt;
&lt;br /&gt;
export PATH=/opt/python32/bin:$PATH&lt;br /&gt;
echo -e &amp;quot;\n\nexport PATH=/opt/python32/bin:\$PATH\n&amp;quot; &amp;gt;&amp;gt; ~/.bash_profile&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3.3.0:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir -p ~/src ; cd ~/src&lt;br /&gt;
wget http://www.python.org/ftp/python/3.3.0/Python-3.3.0.tgz&lt;br /&gt;
tar -zvxf Python-3.3.0.tgz&lt;br /&gt;
cd Python-3.3.0&lt;br /&gt;
./configure --prefix=/opt/python3.3.0&lt;br /&gt;
make&lt;br /&gt;
sudo make install&lt;br /&gt;
&lt;br /&gt;
export PATH=/opt/python3.3.0/bin:$PATH&lt;br /&gt;
echo -e &amp;quot;\n\nexport PATH=/opt/python3.3.0/bin:\$PATH\n&amp;quot; &amp;gt;&amp;gt; ~/.bash_profile&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3.3.4:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir -p ~/.src ; cd ~/.src&lt;br /&gt;
wget http://www.python.org/ftp/python/3.3.4/Python-3.3.4.tgz&lt;br /&gt;
tar -zvxf Python-3.3.4.tgz&lt;br /&gt;
cd Python-3.3.4&lt;br /&gt;
./configure --prefix=/opt/python3.3.4&lt;br /&gt;
make clean&lt;br /&gt;
make&lt;br /&gt;
sudo make install&lt;br /&gt;
&lt;br /&gt;
export PATH=/opt/python3.3.4/bin:$PATH&lt;br /&gt;
echo -e &amp;quot;\n\nexport PATH=/opt/python3.3.4/bin:\$PATH\n&amp;quot; &amp;gt;&amp;gt; ~/.bash_profile&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3.4.0:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir -p ~/.src ; cd ~/.src&lt;br /&gt;
wget http://www.python.org/ftp/python/3.4.0/Python-3.4.0.tgz&lt;br /&gt;
tar -zvxf Python-3.4.0.tgz&lt;br /&gt;
cd Python-3.4.0&lt;br /&gt;
./configure --prefix=/opt/python3.4.0&lt;br /&gt;
make&lt;br /&gt;
sudo make install&lt;br /&gt;
&lt;br /&gt;
export PATH=/opt/python3.4.0/bin:$PATH&lt;br /&gt;
echo -e &amp;quot;\n\nexport PATH=/opt/python3.4.0/bin:\$PATH\n&amp;quot; &amp;gt;&amp;gt; ~/.bash_profile&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== setuptools ===&lt;br /&gt;
&lt;br /&gt;
Purpose: to install pip&lt;br /&gt;
&lt;br /&gt;
Note: required for several &#039;python setup.py install&#039; installations.&lt;br /&gt;
&lt;br /&gt;
Python Package Index : setuptools 0.6c11 - http://pypi.python.org/pypi/setuptools&lt;br /&gt;
&lt;br /&gt;
By Package Manager:&lt;br /&gt;
 yum install python-setuptools&lt;br /&gt;
&lt;br /&gt;
By Source:&lt;br /&gt;
 #VER=2.0.1&lt;br /&gt;
 #VER=2.2&lt;br /&gt;
 VER=3.4.4&lt;br /&gt;
 mkdir -p ~/.src ; cd ~/.src&lt;br /&gt;
 wget --no-check-certificate http://pypi.python.org/packages/source/s/setuptools/setuptools-$VER.tar.gz&lt;br /&gt;
 tar -zvxf setuptools-$VER.tar.gz&lt;br /&gt;
 cd setuptools-$VER&lt;br /&gt;
 # sudo python setup.py install&lt;br /&gt;
 sudo /opt/python-2.7.9/bin/python setup.py install&lt;br /&gt;
&lt;br /&gt;
Fix header:&lt;br /&gt;
 # Only needed on older versions&lt;br /&gt;
 sed -i &#039;s#!/usr/bin/python#!/usr/bin/env python#g&#039; /opt/python279/bin/easy_install&lt;br /&gt;
&lt;br /&gt;
Install pip:&lt;br /&gt;
 sudo /opt/python-2.7.9/bin/easy_install pip&lt;br /&gt;
&lt;br /&gt;
Sample pip usage:&lt;br /&gt;
 sudo /opt/python-2.7.9/bin/pip install paramiko&lt;br /&gt;
&lt;br /&gt;
== IDLE and Interactive Mode ==&lt;br /&gt;
&lt;br /&gt;
Interactive Mode - &amp;quot;When commands are read from a tty, the interpreter is said to be in interactive mode. In this mode it prompts for the next command with the primary prompt, usually three greater-than signs (&amp;gt;&amp;gt;&amp;gt;); for continuation lines it prompts with the secondary prompt, by default three dots (...).&amp;quot; [http://docs.python.org/2/tutorial/interpreter.html#invoking-the-interpreter]&lt;br /&gt;
&lt;br /&gt;
Can use &#039;_&#039; to reference last output:&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; 5 + 6&lt;br /&gt;
 11&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; print _&lt;br /&gt;
 11&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* 2. Using the Python Interpreter — Python v2.7.3 documentation - http://docs.python.org/2/tutorial/interpreter.html&lt;br /&gt;
&lt;br /&gt;
== Python 2.7 EOL ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
DEPRECATION: Python 2.7 will reach the end of its life on January 1st, 2020. Please upgrade your Python as Python 2.7 won&#039;t be maintained after that date. A future version of pip will drop support for Python 2.7.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Show All Python in Path ==&lt;br /&gt;
&lt;br /&gt;
 compgen -c | grep -i &amp;quot;python&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
&lt;br /&gt;
=== Hello World ===&lt;br /&gt;
&lt;br /&gt;
[http://en.wikipedia.org/wiki/Shebang_%28Unix%29 shebang] (also called a hashbang) of Python:&lt;br /&gt;
 #!/usr/bin/env python&lt;br /&gt;
 print &amp;quot;Hello World&amp;quot;&lt;br /&gt;
&lt;br /&gt;
NOTE: can also just use &amp;quot;#!/usr/bin/python&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Standard Script ===&lt;br /&gt;
&lt;br /&gt;
Standard Script:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def main(args):&lt;br /&gt;
  # do logic&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
  sys.exit(main(sys.argv))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Needed for things like pylint&lt;br /&gt;
&lt;br /&gt;
=== White Space ===&lt;br /&gt;
&lt;br /&gt;
Python uses white space to indicate code blocks.  Instead of &#039;&#039;{&#039;&#039; use a &#039;&#039;:&#039;&#039; and indent consistently (4 spaces).&lt;br /&gt;
&lt;br /&gt;
 if a == b:&lt;br /&gt;
     print &#039;equal&#039;&lt;br /&gt;
&lt;br /&gt;
Convert tabs to spaces:&lt;br /&gt;
 sed -i &#039;s/\t/    /g&#039; *.py&lt;br /&gt;
&lt;br /&gt;
Remove trailing whitespace:&lt;br /&gt;
 sed -i &#039;s/\s*$//&#039; *.py&lt;br /&gt;
 sed --in-place &#039;s/[[:space:]]\+$//&#039; fileName&lt;br /&gt;
&lt;br /&gt;
Clean project:&lt;br /&gt;
 # find . -name &amp;quot;*py&amp;quot; -exec dos2unix {} \;&lt;br /&gt;
 # find . -name &amp;quot;*py&amp;quot; -exec sed -i &#039;s/\t/    /g&#039; {} \;&lt;br /&gt;
 # find . -name &amp;quot;*py&amp;quot; -exec sed -i &#039;s/\s*$//&#039; {} \;&lt;br /&gt;
 find . -name &amp;quot;*py&amp;quot; -exec dos2unix {} \; -exec sed -i &#039;s/\t/    /g&#039; {} \; -exec sed -i &#039;s/\s*$//&#039; {} \;&lt;br /&gt;
&lt;br /&gt;
==== Trim Tailing White Space ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sed -e &#039;s/[[:space:]]*$//&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
find . -name &amp;quot;*.py&amp;quot; -exec sed -i -e &#039;s/[[:space:]]*$//&#039; {} \;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ref: [https://stackoverflow.com/questions/369758/how-to-trim-whitespace-from-a-bash-variable]&lt;br /&gt;
&lt;br /&gt;
=== Print ===&lt;br /&gt;
&lt;br /&gt;
print - http://docs.python.org/tutorial/inputoutput.html&lt;br /&gt;
&lt;br /&gt;
Print:  # include new line&lt;br /&gt;
 print(&amp;quot;Hello World&amp;quot;)&lt;br /&gt;
 print &amp;quot;Hello World&amp;quot;   # python 2 only&lt;br /&gt;
&lt;br /&gt;
Suppress new line: [http://stackoverflow.com/questions/493386/how-to-print-in-python-without-newline-or-space]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
print(&#039;#&#039;, end=&#039;&#039;)    # python 3&lt;br /&gt;
print &amp;quot;Hello World&amp;quot;,  # python 2 only (does produce a single separating white space though)&lt;br /&gt;
&lt;br /&gt;
import sys&lt;br /&gt;
sys.stdout.write(&#039;.&#039;)  # no separating white space&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 # flush output&lt;br /&gt;
 # optional, if new line won&#039;t come for some time&lt;br /&gt;
 import sys&lt;br /&gt;
 sys.stdout.flush()&lt;br /&gt;
&lt;br /&gt;
Multiple with separator:&lt;br /&gt;
 print(&amp;quot;hello&amp;quot;, &amp;quot;world&amp;quot;)  # separated by spaces&lt;br /&gt;
 print(&amp;quot;hello&amp;quot;, &amp;quot;world&amp;quot;, sep = &#039;.&#039;)  # separated by period&lt;br /&gt;
&lt;br /&gt;
Formatting:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mystr = &amp;quot;abc&amp;quot;&lt;br /&gt;
myint = 5&lt;br /&gt;
myflt = 3.141592&lt;br /&gt;
print( &amp;quot;%s %d %.3f&amp;quot; % (mystr, myint, myflt) )&lt;br /&gt;
print( &amp;quot;{0} {1} {2}&amp;quot;.format(mystr, myint, myflt) )  # string&#039;s format function (python &amp;gt; 2.7)&lt;br /&gt;
print( &amp;quot;{a} {b} {c}&amp;quot;.format( b = myint, a = mystr, c = myflt) )  # by name&lt;br /&gt;
print( &amp;quot;={a:4s}={b:3d}={c:10.3f}=&amp;quot;.format( b = myint, a = mystr, c = myflt) )  # type and padding&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Padded floating point decimal number: (rounds)&lt;br /&gt;
 print &amp;quot;%06.2f&amp;quot; % 2.319         # &amp;quot;002.32&amp;quot;&lt;br /&gt;
 print &amp;quot;%6.2f&amp;quot; % 2.311          # &amp;quot;  2.31&amp;quot;&lt;br /&gt;
 print &amp;quot;{:06.2f}&amp;quot;.format(2.319) # &amp;quot;002.32&amp;quot;&lt;br /&gt;
 print &amp;quot;{:6.2f}&amp;quot;.format(2.319)  # &amp;quot;  2.32&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 # Python 3 version where var=2.321234&lt;br /&gt;
 print(f&amp;quot;{var:.2f}&amp;quot;)  # &amp;quot;2.32&amp;quot;&lt;br /&gt;
 print(f&amp;quot;{var:6.2f}&amp;quot;)  # &amp;quot;  2.32&amp;quot;&lt;br /&gt;
 print(f&amp;quot;{var:06.2f}&amp;quot;)  # &amp;quot;002.32&amp;quot;&lt;br /&gt;
 print(f&amp;quot;{var:08.2f}&amp;quot;)  # &amp;quot;00002.32&amp;quot;&lt;br /&gt;
 print(f&amp;quot;{var:08.4f}&amp;quot;)  # &amp;quot;002.3212&amp;quot;&lt;br /&gt;
 # Python 3 version where var=2.329 - rounding&lt;br /&gt;
 print(f&amp;quot;{var:06.2f}&amp;quot;)  # &amp;quot;002.33&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Comments ===&lt;br /&gt;
&lt;br /&gt;
 # this is a comment&lt;br /&gt;
 # this is a comment&lt;br /&gt;
 x = y  # this is a comment&lt;br /&gt;
&lt;br /&gt;
Using a non assigned string constant as a comment: (also used for doc strings, not generally recommended)&lt;br /&gt;
 &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
 multi line comment&lt;br /&gt;
 &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;&#039;&lt;br /&gt;
 multi line comment can comment out &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
 &#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This can be used like a C &amp;quot;#if 0&amp;quot; concept to comment out whole sections of code.&lt;br /&gt;
&lt;br /&gt;
Using false block to comment out a block code: (does not ignore bad syntax though)&lt;br /&gt;
 if False:&lt;br /&gt;
    # code in this block is ignored&lt;br /&gt;
&lt;br /&gt;
=== doc strings ===&lt;br /&gt;
&lt;br /&gt;
Using a non assigned string constant as a comment: (also used for doc strings, not generally recommended)&lt;br /&gt;
 &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
 multi line comment&lt;br /&gt;
 &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Variable Type ===&lt;br /&gt;
&lt;br /&gt;
 print( type(myvar).__name__ )&lt;br /&gt;
&lt;br /&gt;
Used to be able to just print the type(myvar), but this doesn&#039;t seem to work anymore :-(&lt;br /&gt;
&lt;br /&gt;
== Variable Directory ===&lt;br /&gt;
&lt;br /&gt;
All of the properties and functions of a variable or object&lt;br /&gt;
&lt;br /&gt;
 print( dir(myvar) )&lt;br /&gt;
&lt;br /&gt;
=== Help ===&lt;br /&gt;
&lt;br /&gt;
dir - list functions and properties of objects:&lt;br /&gt;
 import math&lt;br /&gt;
 dir(math)  # module&lt;br /&gt;
 dir(dir)   # function&lt;br /&gt;
 dir(&amp;quot;&amp;quot;)    # object  - &amp;quot;&amp;quot;, [], {}, etc...&lt;br /&gt;
 dir(__builtins__)  # built in functions&lt;br /&gt;
 dir()      # list imported objects, and dunder methods&lt;br /&gt;
&lt;br /&gt;
Note: dunder (double under) methods determine special functionality (eg. __add__ for +)&lt;br /&gt;
&lt;br /&gt;
help - manual printout: (class doc string, function doc string, data, etc)&lt;br /&gt;
 import math&lt;br /&gt;
 help(math)    # full module info&lt;br /&gt;
 help(len)     # full function info&lt;br /&gt;
 help([&amp;quot;foo&amp;quot;]) # full object info&lt;br /&gt;
&lt;br /&gt;
Pydoc: (command line, same as &#039;import math, help(math)&#039;&lt;br /&gt;
 $ pydoc math&lt;br /&gt;
&lt;br /&gt;
Documentation String: (aka docstring, doc string)&lt;br /&gt;
 print(math.pow.__doc__)  # module doc string&lt;br /&gt;
 print(len.__doc__)       # function doc string&lt;br /&gt;
&lt;br /&gt;
Object or function type:&lt;br /&gt;
 type(x)&lt;br /&gt;
&lt;br /&gt;
 mylist = []&lt;br /&gt;
 isinstance(mylist, list)  # True&lt;br /&gt;
 type(s) is list           # True&lt;br /&gt;
&lt;br /&gt;
Note: isinstance() and type() not equivalent when objects and subclass get involved&lt;br /&gt;
&lt;br /&gt;
IDLE interactive help:&lt;br /&gt;
 help()&lt;br /&gt;
&lt;br /&gt;
=== Variables ===&lt;br /&gt;
&lt;br /&gt;
Basic Data Types&lt;br /&gt;
 str = &amp;quot;string&amp;quot;  # string&lt;br /&gt;
 num = 5         # integer&lt;br /&gt;
 flt = 5.0       # float&lt;br /&gt;
 nothing = None  # None  (not the same as undefined)&lt;br /&gt;
&lt;br /&gt;
Undefined.  Variables start off in an &#039;undefined&#039; state.  It is always better to initially set the variable to None to avoid this state.  To check if undefined: [http://code.activestate.com/recipes/59892-testing-if-a-variable-is-defined/] [http://code.activestate.com/recipes/59892/]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 try:&lt;br /&gt;
   x&lt;br /&gt;
 except NameError:&lt;br /&gt;
   x = None&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Rules: [http://www.python.org/dev/peps/pep-0008/ PEP8 - Method Names and Instance Variables]&lt;br /&gt;
* any length&lt;br /&gt;
* letters, numbers, underscore&lt;br /&gt;
* first character can&#039;t be number&lt;br /&gt;
* case sensitive&lt;br /&gt;
* cannot use keywords&lt;br /&gt;
&lt;br /&gt;
Multiple assignment:&lt;br /&gt;
 x = y = z = 0              # Zero x, y and z&lt;br /&gt;
 x, y, z = 1, &amp;quot;two&amp;quot;, 3.0    # x = 1, y = &amp;quot;two&amp;quot;, z = 3.0&lt;br /&gt;
&lt;br /&gt;
Swap variables: (done in parallel)&lt;br /&gt;
 a, b = b, a&lt;br /&gt;
&lt;br /&gt;
Unpack variables: (requires equal items on each side)&lt;br /&gt;
 a, b, c = [1, 2, 3]&lt;br /&gt;
&lt;br /&gt;
Other Data Types:&lt;br /&gt;
* tuple&lt;br /&gt;
* list&lt;br /&gt;
* dictionary&lt;br /&gt;
* set&lt;br /&gt;
* objects&lt;br /&gt;
&lt;br /&gt;
Everything in Python is an object that has:&lt;br /&gt;
* identity:  id(obj)&lt;br /&gt;
* type:  type(obj)&lt;br /&gt;
* value:  obj&lt;br /&gt;
** mutable - id() stays the same on modification (dictionary, lists, objects)&lt;br /&gt;
** immutable - id() changes on modification as new object is created (string, integer, tuple)&lt;br /&gt;
&lt;br /&gt;
==== Check if Variable Exists ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
try:&lt;br /&gt;
    a # does a exist in the current namespace&lt;br /&gt;
except NameError:&lt;br /&gt;
    a = 10 # nope&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &#039;a&#039; in vars() or &#039;a&#039; in globals()&lt;br /&gt;
 &#039;a&#039; in vars(__builtins__)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if hasattr(a, &#039;property&#039;):&lt;br /&gt;
    doStuff(a.property)&lt;br /&gt;
else:&lt;br /&gt;
    otherStuff()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ref: [https://stackoverflow.com/questions/1592565/determine-if-variable-is-defined-in-python] [https://stackoverflow.com/questions/610883/how-to-know-if-an-object-has-an-attribute-in-python]&lt;br /&gt;
&lt;br /&gt;
=== Numbers ===&lt;br /&gt;
&lt;br /&gt;
 num = 5&lt;br /&gt;
 print &amp;quot;num: %d&amp;quot; % num&lt;br /&gt;
&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; print &amp;quot;Today&#039;s stock price: %f&amp;quot; % 50.4625   1&lt;br /&gt;
 50.462500&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; print &amp;quot;Today&#039;s stock price: %.2f&amp;quot; % 50.4625 2&lt;br /&gt;
 50.46&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; print &amp;quot;Change since yesterday: %+.2f&amp;quot; % 1.5 3&lt;br /&gt;
 +1.50&lt;br /&gt;
&lt;br /&gt;
Arithmetic:&lt;br /&gt;
 + - * /&lt;br /&gt;
 //  # integer division&lt;br /&gt;
 %   # modulus&lt;br /&gt;
 **  # exponent&lt;br /&gt;
&lt;br /&gt;
Compact Arithmetic:&lt;br /&gt;
 i+=1  # Increment - Note, there is no &#039;i++&#039;&lt;br /&gt;
 i*=2  # Multiply&lt;br /&gt;
 i%=2  # modulus&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
Math Functions:&lt;br /&gt;
 import math&lt;br /&gt;
 math.ceil(x)&lt;br /&gt;
 math.floor(x)&lt;br /&gt;
 math.trunc(x)&lt;br /&gt;
 math.pow(x,y)&lt;br /&gt;
&lt;br /&gt;
 abs(x)  # built in&lt;br /&gt;
&lt;br /&gt;
String interpolation:&lt;br /&gt;
 %% % character&lt;br /&gt;
 %d integer&lt;br /&gt;
 %x hex&lt;br /&gt;
 %X hex (upper)&lt;br /&gt;
 %f float&lt;br /&gt;
 %s string&lt;br /&gt;
&lt;br /&gt;
 x = 1/81&lt;br /&gt;
 print(&#039;value: %.2f&#039; % x)  # 0.01&lt;br /&gt;
 print(&#039;value: %.5f&#039; % x)  # 0.012345&lt;br /&gt;
 print(&#039;%d %d %d&#039; % (1, 2, 3))&lt;br /&gt;
&lt;br /&gt;
Type check:&lt;br /&gt;
 if not isinstance(myvar, (int, float)): ...&lt;br /&gt;
&lt;br /&gt;
=== Strings ===&lt;br /&gt;
&lt;br /&gt;
STRINGS ARE IMMUTABLE!  (to modify convert to a list)&lt;br /&gt;
&lt;br /&gt;
Strings: (String Constants)&lt;br /&gt;
 str = &amp;quot;Hello&amp;quot;&lt;br /&gt;
 str = &#039;Hello&#039;&lt;br /&gt;
 str = &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
   Hello&lt;br /&gt;
   World&lt;br /&gt;
 &amp;quot;&amp;quot;&amp;quot;      # can also use &#039;&#039;&#039;...&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
String literals can span multiple lines: (no wrapping when \ used)&lt;br /&gt;
 hello = &amp;quot;hello\&lt;br /&gt;
 world&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Length:&lt;br /&gt;
 len(&amp;quot;str&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Raw string: (back slashes are not escaped)&lt;br /&gt;
 myrawstr = r&amp;quot;hello\nworld\&lt;br /&gt;
 how are you&amp;quot;&lt;br /&gt;
 myrawstr = r&amp;quot;C:\&amp;quot;  # ERROR - limitation of what won&#039;t be escaped&lt;br /&gt;
&lt;br /&gt;
Concatenation:&lt;br /&gt;
 str = &#039;hot&#039; + &#039;dog&#039;&lt;br /&gt;
 print &amp;quot;Hello&amp;quot; &amp;quot;World&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Can&#039;t concat numbers&lt;br /&gt;
 str = 5 + &#039;test&#039;  # error&lt;br /&gt;
 num = 5&lt;br /&gt;
 str = num + &#039;test&#039;  # error&lt;br /&gt;
 str = str(5) + str(num) + &#039;test&#039;  # ok&lt;br /&gt;
&lt;br /&gt;
Repeated Concatenation:&lt;br /&gt;
 str = 10 * &#039;ha&#039;&lt;br /&gt;
 str = &#039;ha&#039; * 10  # same&lt;br /&gt;
 print &#039;-&#039;*60  # --------------------&lt;br /&gt;
&lt;br /&gt;
String Indexing:&lt;br /&gt;
 s = &#039;hello&#039;&lt;br /&gt;
 print( s[0] )    # is &#039;h&#039;&lt;br /&gt;
 print( s[-1] )   # is &#039;o&#039;&lt;br /&gt;
 print( s[len(s) - 1 ] )  # is also &#039;o&#039;&lt;br /&gt;
&lt;br /&gt;
Modify Strings: [http://stackoverflow.com/questions/1228299/change-one-character-in-a-string-in-python]&lt;br /&gt;
 s[1] = &#039;x&#039;  # ERROR!&lt;br /&gt;
 ERROR: can&#039;t modify string by index&lt;br /&gt;
 &lt;br /&gt;
 # solution:&lt;br /&gt;
 s = list(&amp;quot;Hello World&amp;quot;)&lt;br /&gt;
 s[0] = &#039;C&#039;&lt;br /&gt;
 print( &amp;quot;&amp;quot;.join(s) )&lt;br /&gt;
&lt;br /&gt;
String Slicing:&lt;br /&gt;
 s = &#039;hello&#039;&lt;br /&gt;
 print( s[0:3] )  # &#039;hel&#039;&lt;br /&gt;
 i = 1&lt;br /&gt;
 print( s[i:i+1] )  # &#039;e&#039;&lt;br /&gt;
 print( s[:3] )  # 0:3 &#039;hel&#039;&lt;br /&gt;
 print( s[4:] )  # 4:end &#039;o&#039;&lt;br /&gt;
 print( s[:] )  # start:end &#039;hello&#039;&lt;br /&gt;
 print( s[-2:] )  # -2:end &#039;lo&#039;&lt;br /&gt;
&lt;br /&gt;
For loop:&lt;br /&gt;
 s = &#039;hello&#039;&lt;br /&gt;
 for c in s:&lt;br /&gt;
   print c  # c = &#039;h&#039; first time&lt;br /&gt;
&lt;br /&gt;
Escape characters:&lt;br /&gt;
 \\  \&#039;  \&amp;quot;  \n  \r  \t&lt;br /&gt;
&lt;br /&gt;
Alternate loop:&lt;br /&gt;
 s = &#039;hello&#039;&lt;br /&gt;
 for i in range( len(s) ):&lt;br /&gt;
   print s[i]&lt;br /&gt;
&lt;br /&gt;
Ord and Char (ASCII):&lt;br /&gt;
 ord(&#039;a&#039;)  # 97&lt;br /&gt;
 chr(97)   # &#039;a&#039;&lt;br /&gt;
&lt;br /&gt;
 0-9 : 48-57&lt;br /&gt;
 A-Z : 65-90&lt;br /&gt;
 a-z : 97-122&lt;br /&gt;
&lt;br /&gt;
List Functions:  (dir on any string)&lt;br /&gt;
 dir(&#039;&#039;)&lt;br /&gt;
 dir(str)&lt;br /&gt;
&lt;br /&gt;
Help:&lt;br /&gt;
 help(&#039;&#039;)&lt;br /&gt;
 help(str)&lt;br /&gt;
&lt;br /&gt;
Padding:&lt;br /&gt;
 &amp;quot;a&amp;quot;.rjust(2, &#039;0&#039;)  # &#039;0a&#039;&lt;br /&gt;
 &amp;quot;1&amp;quot;.ljust(4, &#039;0&#039;)  # &#039;1000&#039;&lt;br /&gt;
&lt;br /&gt;
String Test Functions:&lt;br /&gt;
 &amp;quot;HELLO&amp;quot;.isupper()   # True&lt;br /&gt;
 &amp;quot;hello&amp;quot;.islower()   # True&lt;br /&gt;
 &amp;quot;hello&amp;quot;.isalpha()   # True&lt;br /&gt;
 &amp;quot;12.22&amp;quot;.isdigit()   # False (because of &#039;.&#039;)&lt;br /&gt;
 &amp;quot;12.22&amp;quot;.isnumeric() # False (because of &#039;.&#039;)&lt;br /&gt;
 &amp;quot;hel2&amp;quot;.isalnum()    # True&lt;br /&gt;
 &amp;quot;e&amp;quot; in &amp;quot;hello&amp;quot;      # True&lt;br /&gt;
 &amp;quot;hello&amp;quot;.startswith(&#039;he&#039;)  # True&lt;br /&gt;
 &amp;quot;hello&amp;quot;.endswith(&#039;lo&#039;)    # True&lt;br /&gt;
&lt;br /&gt;
Note: To check for floats: [http://stackoverflow.com/questions/354038/how-do-i-check-if-a-string-is-a-number-in-python]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def is_number(s):&lt;br /&gt;
    try:&lt;br /&gt;
        float(s)&lt;br /&gt;
        return True&lt;br /&gt;
    except ValueError:&lt;br /&gt;
        return False&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
String Modify Functions: (sort of... Strings are immutable)&lt;br /&gt;
 &amp;quot;HELLO&amp;quot;.lower()           # &#039;hello&#039;&lt;br /&gt;
 &amp;quot;hello&amp;quot;.upper()           # &#039;HELLO&#039;&lt;br /&gt;
 &amp;quot; hello &amp;quot;.strip()         # &#039;hello&#039; remove leading/tailing whitespace&lt;br /&gt;
 &amp;quot; hello &amp;quot;.lstrip()        # &#039;hello &#039; remove left whitespace&lt;br /&gt;
 &amp;quot; hello &amp;quot;.rstrip()        # &#039; hello&#039; remove right whitespace&lt;br /&gt;
 &amp;quot;www.com&amp;quot;.split(&#039;.&#039;)      # [&#039;www&#039;, &#039;com&#039;]   &amp;lt;- list&lt;br /&gt;
 &amp;quot;www.com&amp;quot;.partition(&#039;.&#039;)  # (&#039;www&#039;, &#039;.&#039;, &#039;com&#039;)  &amp;lt;- tuple&lt;br /&gt;
 &amp;quot;&amp;quot;.join( (&#039;a&#039;,&#039;b&#039;,&#039;c&#039;) )  # &amp;quot;abc&amp;quot;  join strings, list or tuple&lt;br /&gt;
 &amp;quot;-&amp;quot;.join( (&#039;a&#039;,&#039;b&#039;,&#039;c&#039;) ) # &amp;quot;a-b-c&amp;quot;  join with separator&lt;br /&gt;
 &amp;quot;23&amp;quot;.zfill(4)             # &amp;quot;0023&amp;quot;&lt;br /&gt;
&lt;br /&gt;
String Search Functions:&lt;br /&gt;
 &amp;quot;hello&amp;quot;.find(&#039;lo&#039;)   # 3  (-1 on fail)&lt;br /&gt;
 &amp;quot;hello&amp;quot;.index(&#039;lo&#039;)  # 3 (exception on fail)&lt;br /&gt;
 &amp;quot;hello&amp;quot;.rfind(&#039;lo&#039;)  # 3 right to left (-1 on fail)&lt;br /&gt;
 &amp;quot;hello&amp;quot;.rindex(&#039;lo&#039;) # 3 right to left (exception on fail)&lt;br /&gt;
&lt;br /&gt;
Formatting: (form of concatenation)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mystr = &amp;quot;abc&amp;quot;&lt;br /&gt;
myint = 5&lt;br /&gt;
myflt = 3.141592&lt;br /&gt;
print( &amp;quot;%s %d %.3f&amp;quot; % (mystr, myint, myflt) )&lt;br /&gt;
print( &amp;quot;{0} {1} {2}&amp;quot;.format(mystr, myint, myflt) )  # pep 3101 style - string&#039;s format function (python &amp;gt; 2.7)&lt;br /&gt;
print( &amp;quot;{a} {b} {c}&amp;quot;.format( b = myint, a = mystr, c = myflt) )  # by name&lt;br /&gt;
print( &amp;quot;={a:4s}={b:3d}={c:10.3f}=&amp;quot;.format( b = myint, a = mystr, c = myflt) )  # type and padding&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Split multi line string:&lt;br /&gt;
 for line in str.split(&#039;\n&#039;):  print(line)&lt;br /&gt;
 lines = str.splitlines()      # returns list&lt;br /&gt;
 lines = str.splitlines(True)  # returns list (each includes new line characters)&lt;br /&gt;
&lt;br /&gt;
Input a string:&lt;br /&gt;
 name = input(&#039;What is your name: &#039;).strip()  # python 3&lt;br /&gt;
 name = raw_input(&#039;What is your name: &#039;).strip()  # python 2&lt;br /&gt;
&lt;br /&gt;
Leet Speak:&lt;br /&gt;
 leet_table = &#039;&#039;.maketrans(&#039;EIOBT&#039;, &#039;31087&#039;)&lt;br /&gt;
 &#039;BE COOL. SPEAK LEET!&#039;.translate(leet_table)&lt;br /&gt;
&lt;br /&gt;
String Functions:&lt;br /&gt;
 newstr = mystr.strip()             # remove white space on both sides&lt;br /&gt;
 newstr = mystr.rstrip()            # remove white space on right side&lt;br /&gt;
 newstr = mystr.lstrip()            # remove white space on left side&lt;br /&gt;
 newstr = mystr.replace(&#039;\n&#039;, &#039; &#039;)  # replace string with another&lt;br /&gt;
 newstr = mystr.replace(&#039;jello&#039;, &#039;hello&#039;)  # replace string with another&lt;br /&gt;
&lt;br /&gt;
==== String Formatting ====&lt;br /&gt;
&lt;br /&gt;
PyFormat: Using % and .format() for great good! - https://pyformat.info/&lt;br /&gt;
&lt;br /&gt;
===== Zero Padding =====&lt;br /&gt;
&lt;br /&gt;
3 zero padding:&lt;br /&gt;
 &amp;quot;{:03}&amp;quot;.format(1)  # 003&lt;br /&gt;
&lt;br /&gt;
3 zero padding, specify position:&lt;br /&gt;
 &amp;quot;{1:03}&amp;quot;.format(1, 2)  # 002&lt;br /&gt;
&lt;br /&gt;
Old method:&lt;br /&gt;
 &amp;quot;%03d&amp;quot; % 2  # 002&lt;br /&gt;
&lt;br /&gt;
=== chr and ord ===&lt;br /&gt;
&lt;br /&gt;
Ord and Char (ASCII):&lt;br /&gt;
 ord(&#039;a&#039;)  # 97&lt;br /&gt;
 chr(97)   # &#039;a&#039;&lt;br /&gt;
&lt;br /&gt;
=== Range ===&lt;br /&gt;
&lt;br /&gt;
Creates a list of numbers.  Remember: range always ends one less than you want!&lt;br /&gt;
&lt;br /&gt;
Count:&lt;br /&gt;
 ten = 10&lt;br /&gt;
 one = 1&lt;br /&gt;
 range(ten)               # [0,1,...,9]   starts with zero by default&lt;br /&gt;
 range(one, ten + 1)      # [1,...,10]    actually get 1 to 10&lt;br /&gt;
 range(ten, one - 1, -1)  # [10,9,...,1]  count down&lt;br /&gt;
 range(2, 10 + 1, 2)      # [2,4,...,10]  even numbers&lt;br /&gt;
&lt;br /&gt;
=== drange ===&lt;br /&gt;
&lt;br /&gt;
Solution for decimal range() step value:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def drange(start, stop, step):&lt;br /&gt;
    r = start&lt;br /&gt;
    while r &amp;lt; stop:&lt;br /&gt;
        yield r&lt;br /&gt;
    r += step&lt;br /&gt;
&lt;br /&gt;
sub_ten = drange(0.0, 1.0, 0.1)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* floating point - Python decimal range() step value - Stack Overflow - http://stackoverflow.com/questions/477486/python-decimal-range-step-value&lt;br /&gt;
&lt;br /&gt;
=== Casting ===&lt;br /&gt;
&lt;br /&gt;
Convert:&lt;br /&gt;
 float(3)&lt;br /&gt;
 str(85)&lt;br /&gt;
 int(8.6)&lt;br /&gt;
 round(5.5)&lt;br /&gt;
&lt;br /&gt;
Check Type:&lt;br /&gt;
 type(5)     # &amp;lt;class &#039;int&#039;&amp;gt;&lt;br /&gt;
 type(5.0)   # &amp;lt;class &#039;float&#039;&amp;gt;&lt;br /&gt;
 type(&#039;5&#039;)   # &amp;lt;class &#039;str&#039;&amp;gt;&lt;br /&gt;
 type(None)  # &amp;lt;class &#039;NoneType&#039;&amp;gt;&lt;br /&gt;
 type(print) # &amp;lt;class &#039;builtin_function_or_method&#039;&amp;gt;&lt;br /&gt;
 type(())    # &amp;lt;class &#039;tuple&#039;&amp;gt;&lt;br /&gt;
 type([])    # &amp;lt;class &#039;list&#039;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 mytype = int&lt;br /&gt;
 if type(1) is mytype: ...&lt;br /&gt;
&lt;br /&gt;
=== Boolean Logic ===&lt;br /&gt;
&lt;br /&gt;
True and False:&lt;br /&gt;
 bol = True&lt;br /&gt;
 bol = False&lt;br /&gt;
&lt;br /&gt;
Boolean Operators: (in order precedence)&lt;br /&gt;
 a == b&lt;br /&gt;
 a != b&lt;br /&gt;
 not a&lt;br /&gt;
 a and b&lt;br /&gt;
 a or b&lt;br /&gt;
&lt;br /&gt;
Note: Short-circuit evaluated - &#039;and&#039; and &#039;or&#039;&lt;br /&gt;
&lt;br /&gt;
Return Boolean:&lt;br /&gt;
 return myint &amp;gt;= 16&lt;br /&gt;
&lt;br /&gt;
Get Boolean from string: [http://stackoverflow.com/questions/715417/converting-from-a-string-to-boolean-in-python]&lt;br /&gt;
 # Note: no built in way to do this&lt;br /&gt;
&lt;br /&gt;
 myString = &amp;quot;false&amp;quot;&lt;br /&gt;
 val = (myString == &amp;quot;true&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
 True if myString==&amp;quot;True&amp;quot; else False&lt;br /&gt;
&lt;br /&gt;
 s in [&#039;true&#039;, &#039;1&#039;, &#039;t&#039;, &#039;y&#039;, &#039;yes&#039;, &#039;yeah&#039;, &#039;yup&#039;, &#039;certainly&#039;, &#039;uh-huh&#039;]&lt;br /&gt;
&lt;br /&gt;
 def str2bool(v):&lt;br /&gt;
   return v.lower() in (&amp;quot;yes&amp;quot;, &amp;quot;true&amp;quot;, &amp;quot;t&amp;quot;, &amp;quot;1&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
=== None ===&lt;br /&gt;
&lt;br /&gt;
None is Python&#039;s version of NULL or NIL.&lt;br /&gt;
&lt;br /&gt;
None is a singleton (Python only has one copy of None in the interpreter).&lt;br /&gt;
&lt;br /&gt;
 if myvar is None:&lt;br /&gt;
     ...&lt;br /&gt;
&lt;br /&gt;
=== If Conditionals ===&lt;br /&gt;
&lt;br /&gt;
Operators:&lt;br /&gt;
 ==, !=, not, and, or, &amp;lt;, &amp;gt;, &amp;lt;&amp;gt;, &amp;lt;=, &amp;gt;=, in, not in, is, is not&lt;br /&gt;
&lt;br /&gt;
If statement:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if a == b:&lt;br /&gt;
  ...&lt;br /&gt;
elif c &amp;lt; age &amp;lt; d:&lt;br /&gt;
  ...&lt;br /&gt;
else:&lt;br /&gt;
  ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Shorthand conditional: (ternary operator)&lt;br /&gt;
 val = True if a == b else False&lt;br /&gt;
&lt;br /&gt;
is - checks for identical objects - same id()&lt;br /&gt;
 # None is a singleton, so this works great for None&lt;br /&gt;
 if myvar is None:&lt;br /&gt;
     ...&lt;br /&gt;
&lt;br /&gt;
Other shorthand:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def mycmp(x, y):&lt;br /&gt;
  if x &amp;gt; y: return True&lt;br /&gt;
  else: return False&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Switch/Case statement:&lt;br /&gt;
* there is no built in switch/case statement, use &amp;quot;if ... elif ... elif ...&amp;quot; sequence instead&lt;br /&gt;
&lt;br /&gt;
=== For Loop ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;for&#039;&#039; is used for iterating over an iterable sequence (eg. lists, dictionaries, tuples). (for each)&lt;br /&gt;
&lt;br /&gt;
# range(start, end + 1, skip)&lt;br /&gt;
&lt;br /&gt;
 for i in range(10):&lt;br /&gt;
   print(i)  # 0 .. 9&lt;br /&gt;
&lt;br /&gt;
 for i in range(5, 10):&lt;br /&gt;
   print(i)  # 5 .. 9&lt;br /&gt;
&lt;br /&gt;
 for i in range(10, 0, -1):&lt;br /&gt;
   print(i)  # 10 .. 1&lt;br /&gt;
&lt;br /&gt;
 for i in [1, 2, 3]:  # iterate over list&lt;br /&gt;
   print(i)  # 1 2 3&lt;br /&gt;
&lt;br /&gt;
Discard variable: [http://bytes.com/topic/python/answers/757444-loop-without-variable]&lt;br /&gt;
 for _ in range(10):  # repeat and discard variable (good for pep8 check)&lt;br /&gt;
   print &amp;quot;hello world&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 for key in my_dict.keys(): ...&lt;br /&gt;
 for value in my_dict.values(): ...&lt;br /&gt;
 for key, value in my_dict.items(): ...&lt;br /&gt;
&lt;br /&gt;
Compact version:&lt;br /&gt;
 for i in range(10): print(i)    # 0 .. 9&lt;br /&gt;
&lt;br /&gt;
Access index: [http://stackoverflow.com/questions/522563/accessing-the-index-in-python-for-loops]&lt;br /&gt;
 # using enumeration&lt;br /&gt;
 for idx, val in enumerate(mylist):&lt;br /&gt;
   print idx, val&lt;br /&gt;
&lt;br /&gt;
 # using range&lt;br /&gt;
 for ix in range(len(mylist)):&lt;br /&gt;
   print mylist[ix]&lt;br /&gt;
&lt;br /&gt;
 # list comprehension&lt;br /&gt;
 [ (ix, mylist[ix]) for ix in range(len(mylist))]&lt;br /&gt;
&lt;br /&gt;
=== While Loop ===&lt;br /&gt;
&lt;br /&gt;
 i = 0&lt;br /&gt;
 while i &amp;lt; 10:&lt;br /&gt;
   i = i + 1&lt;br /&gt;
&lt;br /&gt;
 while True:&lt;br /&gt;
   ...  # infinite loop&lt;br /&gt;
&lt;br /&gt;
=== Breaking Loops ===&lt;br /&gt;
&lt;br /&gt;
break statement:&lt;br /&gt;
 while True:&lt;br /&gt;
   if s == &#039;done&#039;:&lt;br /&gt;
     break  # jump out of the loop&lt;br /&gt;
   ...&lt;br /&gt;
&lt;br /&gt;
continue statement: (works with while too)&lt;br /&gt;
  for i in range(10):&lt;br /&gt;
    if i == 2:&lt;br /&gt;
      continue  # skip 2&lt;br /&gt;
    ...&lt;br /&gt;
&lt;br /&gt;
=== Functions ===&lt;br /&gt;
&lt;br /&gt;
No return value:  (None)&lt;br /&gt;
 x = print(&#039;&#039;)&lt;br /&gt;
 # x is &#039;None&#039;&lt;br /&gt;
&lt;br /&gt;
Note: specifying no return value is the same as this:&lt;br /&gt;
 return None&lt;br /&gt;
&lt;br /&gt;
No Operation - &#039;pass&#039;:&lt;br /&gt;
 def noop():&lt;br /&gt;
   pass&lt;br /&gt;
&lt;br /&gt;
Function:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def area(radius):&lt;br /&gt;
  &amp;quot;&amp;quot;&amp;quot; This is a doc string &amp;quot;&amp;quot;&amp;quot;   # can be &amp;quot; ... &amp;quot; also...&lt;br /&gt;
  import math&lt;br /&gt;
  return math.pi * radius ** 2&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Function Doc string:&lt;br /&gt;
 print(area.__doc__)&lt;br /&gt;
 foo.func_doc&lt;br /&gt;
&lt;br /&gt;
Function name:&lt;br /&gt;
  foo.func_name&lt;br /&gt;
&lt;br /&gt;
Local variable:&lt;br /&gt;
 name = &amp;quot;old&amp;quot;&lt;br /&gt;
 def cname():&lt;br /&gt;
   name = &amp;quot;new&amp;quot;&lt;br /&gt;
 print(name)  # is still &#039;old&#039;&lt;br /&gt;
&lt;br /&gt;
Global variable:&lt;br /&gt;
 name = &amp;quot;old&amp;quot;&lt;br /&gt;
 def cname():&lt;br /&gt;
   global name&lt;br /&gt;
   name = &amp;quot;new&amp;quot;&lt;br /&gt;
 cname()&lt;br /&gt;
 print(name)  # is now &#039;new&#039;&lt;br /&gt;
&lt;br /&gt;
By convention starting point is: (not required)&lt;br /&gt;
 def main():&lt;br /&gt;
&lt;br /&gt;
Parameters: (with default)&lt;br /&gt;
 def foo(x, y, z = &amp;quot;default&amp;quot;):&lt;br /&gt;
&lt;br /&gt;
Note: don&#039;t use mutable for defaults, as the object is remembered across runs! (unless that is what you want)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# each call to t() will increase list&lt;br /&gt;
def t(foo=[]):&lt;br /&gt;
   foo.append(&#039;1&#039;)&lt;br /&gt;
   print(foo)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# fix mutable issue&lt;br /&gt;
def named_param(a, foo=None):&lt;br /&gt;
  foo = foo or []&lt;br /&gt;
  if not foo:&lt;br /&gt;
    foo.append(a)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Parameters by keyword:&lt;br /&gt;
 def foo(x = &#039;1&#039;, y = &#039;2&#039;, z = &#039;3&#039;):&lt;br /&gt;
   ...&lt;br /&gt;
 foo(y = &#039;a&#039;, x = &#039;b&#039;)   # order is not important with keywords&lt;br /&gt;
&lt;br /&gt;
Trick for optional parameter:&lt;br /&gt;
 def do(x = None):&lt;br /&gt;
   if x == None:&lt;br /&gt;
&lt;br /&gt;
Function tests - functions are callable&lt;br /&gt;
 callable(myfunc)&lt;br /&gt;
&lt;br /&gt;
=== Type Hints ===&lt;br /&gt;
&lt;br /&gt;
: &amp;quot;Note The Python runtime does not enforce function and variable type annotations. They can be used by third party tools such as type checkers, IDEs, linters, etc.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 def surface_area_of_cube(edge_length: float) -&amp;gt; str:&lt;br /&gt;
     return f&amp;quot;The surface area of the cube is {6 * edge_length ** 2}.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Without the hints:&lt;br /&gt;
 def surface_area_of_cube(edge_length):&lt;br /&gt;
     ...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ref: https://docs.python.org/3/library/typing.html&lt;br /&gt;
&lt;br /&gt;
=== Pass ===&lt;br /&gt;
&lt;br /&gt;
Pass is a null operation (noop):&lt;br /&gt;
&lt;br /&gt;
Do nothing, noop, take no action:&lt;br /&gt;
 pass&lt;br /&gt;
&lt;br /&gt;
Great for creating minimal classes:&lt;br /&gt;
 class MyEmptyClass:&lt;br /&gt;
   pass&lt;br /&gt;
&lt;br /&gt;
Greate for making stub functions/methods:&lt;br /&gt;
 def initlog(*args):&lt;br /&gt;
   pass  # remember to implement this!&lt;br /&gt;
&lt;br /&gt;
=== Slice ===&lt;br /&gt;
&lt;br /&gt;
Take take a slice of strings, lists, tuples, etc...&lt;br /&gt;
 a = [0,1,2,3,4,5]&lt;br /&gt;
 a[0]    # 0 - not a slice&lt;br /&gt;
 a[-1]   # 5 - not a slice&lt;br /&gt;
 a[0:1]  # [0]&lt;br /&gt;
 a[1:3]  # [1, 2]&lt;br /&gt;
 a[:2]   # [0, 1]&lt;br /&gt;
 a[:-1]  # [0, 1, 2, 3, 4] - all but last&lt;br /&gt;
 a[2:]   # [2, 3, 4, 5]&lt;br /&gt;
 a[::2]  # [0, 2, 4] - stride&lt;br /&gt;
 a[::-1] # [5, 4, 3, 2, 1, 0] - reverse&lt;br /&gt;
 range(0,10)[::2]  # [0, 2, 4, 6, 8] - stride&lt;br /&gt;
&lt;br /&gt;
 a = &#039;012345&#039;&lt;br /&gt;
 a[1:3]  # &#039;12&#039;&lt;br /&gt;
 a[::2]  # &#039;024&#039;&lt;br /&gt;
&lt;br /&gt;
=== [http://docs.python.org/reference/compound_stmts.html Compound Statements] ===&lt;br /&gt;
&lt;br /&gt;
Compound statements: (generally discouraged)&lt;br /&gt;
 fun1(); fun2(); fun3()&lt;br /&gt;
&lt;br /&gt;
Compound with statements: [http://docs.python.org/reference/compound_stmts.html#the-with-statement]&lt;br /&gt;
 with A() as a, B() as b: ...&lt;br /&gt;
&lt;br /&gt;
 #is equivalent to&lt;br /&gt;
 with A() as a:&lt;br /&gt;
     with B() as b:&lt;br /&gt;
         ...&lt;br /&gt;
&lt;br /&gt;
[http://www.python.org/dev/peps/pep-0343 PEP 0343] - The “with” statement&lt;br /&gt;
&lt;br /&gt;
 f = open(&#039;file&#039;)&lt;br /&gt;
 with f: ...&lt;br /&gt;
&lt;br /&gt;
Try: (quick ignore all exceptions, very dangerous)&lt;br /&gt;
 try: my_broken_function()&lt;br /&gt;
 except: pass&lt;br /&gt;
&lt;br /&gt;
=== Passing Command Line Arguments ===&lt;br /&gt;
&lt;br /&gt;
Parameters are stored in the &#039;sys.argv&#039; variable:&lt;br /&gt;
 import sys&lt;br /&gt;
 print( sys.argv[0] )  # name of script&lt;br /&gt;
 print( sys.argv[1] )  # first argument&lt;br /&gt;
 for arg in sys.argv: print( arg )  # list all arguments&lt;br /&gt;
&lt;br /&gt;
Print script name:&lt;br /&gt;
 os.path.basename(sys.argv[0])&lt;br /&gt;
&lt;br /&gt;
Print path to script:&lt;br /&gt;
 print sys.path[0]&lt;br /&gt;
&lt;br /&gt;
Paths: [http://code.activestate.com/recipes/474083-get-the-path-of-the-currently-executing-python-scr/]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import os,sys&lt;br /&gt;
print &amp;quot;CWD: &amp;quot;,os.getcwd()&lt;br /&gt;
print &amp;quot;Script: &amp;quot;,sys.argv[0]&lt;br /&gt;
print &amp;quot;.EXE: &amp;quot;,os.path.dirname(sys.executable)&lt;br /&gt;
print &amp;quot;Script dir: &amp;quot;, os.path.realpath(os.path.dirname(sys.argv[0]))&lt;br /&gt;
pathname, scriptname = os.path.split(sys.argv[0])&lt;br /&gt;
print &amp;quot;Relative script dir: &amp;quot;,pathname&lt;br /&gt;
print &amp;quot;Script dir: &amp;quot;, os.path.abspath(pathname)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 os.path.realpath(__file__)&lt;br /&gt;
&lt;br /&gt;
 print &#039;sys.argv[0] =&#039;, sys.argv[0]             &lt;br /&gt;
 pathname = os.path.dirname(sys.argv[0])        &lt;br /&gt;
 print &#039;path =&#039;, pathname&lt;br /&gt;
 print &#039;full path =&#039;, os.path.abspath(pathname)&lt;br /&gt;
&lt;br /&gt;
=== Environment Variables ===&lt;br /&gt;
&lt;br /&gt;
 import os&lt;br /&gt;
 a = os.environ.get(&#039;MYVAR&#039;)               # get environment var&lt;br /&gt;
 a = os.environ.get(&#039;MYVAR&#039;,&#039;default&#039;)     # get environment var&lt;br /&gt;
 a = os.environ[&#039;MYVAR&#039;]                   # get environment var&lt;br /&gt;
 os.environ[&#039;MYVAR&#039;] = &#039;something&#039;         # set environment var&lt;br /&gt;
 os.environ.update({&#039;MYVAR&#039;:&#039;something&#039;})  # set environment var&lt;br /&gt;
&lt;br /&gt;
 for env in os.environ:&lt;br /&gt;
   print &amp;quot;%s = %s&amp;quot; % (env, os.environ[env])&lt;br /&gt;
&lt;br /&gt;
 with open(&amp;quot;environment.txt&amp;quot;, &amp;quot;w&amp;quot;) as f:&lt;br /&gt;
   for env in os.environ:&lt;br /&gt;
      f.write(&amp;quot;%s = %s\n&amp;quot; % (env, os.environ[env]))&lt;br /&gt;
&lt;br /&gt;
=== PYTHONPATH ===&lt;br /&gt;
&lt;br /&gt;
Environment Search path:&lt;br /&gt;
 PYTHONPATH=...&lt;br /&gt;
&lt;br /&gt;
From Code:&lt;br /&gt;
 sys.path.append(&#039;...&#039;)&lt;br /&gt;
&lt;br /&gt;
Get site-package directory from shell: [http://stackoverflow.com/questions/122327/how-do-i-find-the-location-of-my-python-site-packages-directory]&lt;br /&gt;
 python -c &amp;quot;from distutils.sysconfig import get_python_lib; print(get_python_lib())&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Import and Modules ===&lt;br /&gt;
&lt;br /&gt;
Import and Modules - http://docs.python.org/tutorial/modules.html&lt;br /&gt;
&lt;br /&gt;
Import module:&lt;br /&gt;
 import package            # standard import&lt;br /&gt;
 import package.code       # nested name space&lt;br /&gt;
 from package import code  # import specifics from module&lt;br /&gt;
 import module             # standard import&lt;br /&gt;
 from math import sin      # import specifics from module&lt;br /&gt;
 from module import myfunc as fun1  # alias function/object&lt;br /&gt;
 import math as other_math # alias module&lt;br /&gt;
 import longname as ln     # alias module&lt;br /&gt;
 from module import *      # BAD BAD BAD!&lt;br /&gt;
&lt;br /&gt;
 import math&lt;br /&gt;
 math.pow(x,y)&lt;br /&gt;
&lt;br /&gt;
Group and organize by:&lt;br /&gt;
* stdlib libraries&lt;br /&gt;
* local libraries&lt;br /&gt;
* 3rd party libraries&lt;br /&gt;
&lt;br /&gt;
Remove import:&lt;br /&gt;
 del math&lt;br /&gt;
&lt;br /&gt;
 from math import *&lt;br /&gt;
 pow(x,y)&lt;br /&gt;
&lt;br /&gt;
 from math import pow&lt;br /&gt;
 pow(x,y)&lt;br /&gt;
&lt;br /&gt;
 import math as math_lib   # rename&lt;br /&gt;
 math_lib.pow(x,y)&lt;br /&gt;
&lt;br /&gt;
List functions in module:&lt;br /&gt;
 import math&lt;br /&gt;
 dir(math)&lt;br /&gt;
&lt;br /&gt;
List all built in functions:&lt;br /&gt;
 dir(__builtins__)&lt;br /&gt;
&lt;br /&gt;
Note: Modules have the extension .py&lt;br /&gt;
&lt;br /&gt;
Simply module Example:&lt;br /&gt;
&lt;br /&gt;
 # mymod.py:&lt;br /&gt;
 def hello():&lt;br /&gt;
   &amp;quot;&amp;quot;&amp;quot; this is a doc string &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
   print &amp;quot;Hello World&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 # Use the module:&lt;br /&gt;
 import mymod&lt;br /&gt;
 mymod.hello():&lt;br /&gt;
&lt;br /&gt;
 # Use everything in the the module, except for names beginning with &#039;_&#039;:  (bad practice!)&lt;br /&gt;
 from mymod import *&lt;br /&gt;
 hello()&lt;br /&gt;
&lt;br /&gt;
 # Use specific functions in the module:&lt;br /&gt;
 from mymod import hello, hi&lt;br /&gt;
 hello()&lt;br /&gt;
&lt;br /&gt;
 # Function assignment:&lt;br /&gt;
 h = mymod.hello&lt;br /&gt;
 h()&lt;br /&gt;
&lt;br /&gt;
 # module name&lt;br /&gt;
 mymod.__name__   # mymod&lt;br /&gt;
 __name__         # used inside of module will print current module or &amp;quot;__main__&amp;quot; if directly called&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Note: careful when building own modules, as the import literally imports and executes the code, so any code not in functions is executed!&lt;br /&gt;
&lt;br /&gt;
Check if being called directly or indirectly:&lt;br /&gt;
 if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
   # execute tests...&lt;br /&gt;
&lt;br /&gt;
Standard Script Setup:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def main(args):&lt;br /&gt;
  # do logic&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
  sys.exit(main(sys.argv))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Easter egg:&lt;br /&gt;
 # The Zen of Python&lt;br /&gt;
 import this&lt;br /&gt;
&lt;br /&gt;
Search path:&lt;br /&gt;
* environment variable &#039;PYTHONPATH&#039;   (on Unix, this is usually .:/usr/local/lib/python)&lt;br /&gt;
* sys.path  (list of paths, initialized to PYTHONPATH)&lt;br /&gt;
** sys.path.append(&#039;path&#039;)&lt;br /&gt;
&lt;br /&gt;
Module folder: [http://stackoverflow.com/questions/391879/organising-my-python-project] [http://stackoverflow.com/questions/279237/python-import-a-module-from-a-folder] [http://stackoverflow.com/questions/72852/how-to-do-relative-imports-in-python]&lt;br /&gt;
 /kenlib/kenmod.py&lt;br /&gt;
 # so you can do &amp;quot;import kenlib.kenmod&amp;quot;&lt;br /&gt;
 # create file &#039;__init__.py&#039; in kenlib/&lt;br /&gt;
&lt;br /&gt;
Check if package exists:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
try:&lt;br /&gt;
    import argparse&lt;br /&gt;
except ImportError:&lt;br /&gt;
    print &amp;gt;&amp;gt; sys.stderr, &amp;quot;Please install argparse from http://code.google.com/p/&lt;br /&gt;
argparse.&amp;quot;&lt;br /&gt;
    exit(1)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== ifmain ===&lt;br /&gt;
&lt;br /&gt;
 if __name__ == &#039;__main__&#039;:&lt;br /&gt;
     sys.exit(main(sys.argv))&lt;br /&gt;
&lt;br /&gt;
 if __name__ == &#039;__main__&#039;:&lt;br /&gt;
     sys.exit(main(sys.argv[1:]) or 0)&lt;br /&gt;
&lt;br /&gt;
=== Lists ===&lt;br /&gt;
&lt;br /&gt;
* Lists can be modified (mutable)&lt;br /&gt;
* Tuples are constant (immutable)&lt;br /&gt;
&lt;br /&gt;
List: (mutable or modifiable)&lt;br /&gt;
 x = []  # empty list&lt;br /&gt;
 x = [5] # singleton list&lt;br /&gt;
&lt;br /&gt;
 s = list(&amp;quot;Hello World&amp;quot;)&lt;br /&gt;
 print(s)  # s = [&#039;H&#039;, &#039;e&#039;, &#039;l&#039;, &#039;l&#039;, &#039;o&#039;, &#039; &#039;, &#039;W&#039;, &#039;o&#039;, &#039;r&#039;, &#039;l&#039;, &#039;d&#039;]&lt;br /&gt;
 s[0] = &#039;X&#039;&lt;br /&gt;
&lt;br /&gt;
 s.append(x)     # append x&lt;br /&gt;
 s.insert(i, x)  # insert x at i&lt;br /&gt;
 del(s[i])       # delete item at i&lt;br /&gt;
 s.sort()        # sort (modify in place!)&lt;br /&gt;
 s.reverse()     # reverse&lt;br /&gt;
 s.index(x)      # index of x in s&lt;br /&gt;
 new = old[:]    # create copy of list&lt;br /&gt;
 new = list(old) # create copy of list&lt;br /&gt;
&lt;br /&gt;
Check if item in list:&lt;br /&gt;
 if x in s: ...&lt;br /&gt;
&lt;br /&gt;
Filter list of strings based on contents: [https://stackoverflow.com/questions/2152898/filtering-a-list-of-strings-based-on-contents]&lt;br /&gt;
 res = [k for k in lst if &#039;ab&#039; in k]&lt;br /&gt;
&lt;br /&gt;
List comprehension&lt;br /&gt;
 [n * n for n in range(1, 11)]   # squares of numbers 1 to 10&lt;br /&gt;
 [c for c in &#039;pizza&#039;]            # list of string &#039;pizza&#039;&lt;br /&gt;
 [c.upper() for c in &#039;pizza&#039;]    # list of string &#039;pizza&#039; uppercase&lt;br /&gt;
 [n for n in nums if n &amp;gt; 0]      # filters out only positive numbers in nums list&lt;br /&gt;
 [fname for fname in os.listdir(path)  # on multiple lines&lt;br /&gt;
    if os.path.isfile(fname)&lt;br /&gt;
    if fname.endswith(&#039;.py&#039;)]&lt;br /&gt;
&lt;br /&gt;
Enumeration&lt;br /&gt;
 for index, value in enumerate(mylist):  print index, value&lt;br /&gt;
&lt;br /&gt;
Length:&lt;br /&gt;
 len(x)&lt;br /&gt;
&lt;br /&gt;
Concatenation:&lt;br /&gt;
 x + s&lt;br /&gt;
 x * 2&lt;br /&gt;
&lt;br /&gt;
Convert list to string:&lt;br /&gt;
 &amp;quot;&amp;quot;.join(mylist)  # no separator&lt;br /&gt;
 &amp;quot; &amp;quot;.join(mylist) # space separator&lt;br /&gt;
 &amp;quot;,&amp;quot;.join(mylist) # comma separator&lt;br /&gt;
&lt;br /&gt;
Test Membership&lt;br /&gt;
 x in s&lt;br /&gt;
&lt;br /&gt;
Multi dimensional list:&lt;br /&gt;
 mylist = [ [0,&amp;quot;hi&amp;quot;], [1,&amp;quot;bye&amp;quot;] ]&lt;br /&gt;
 print( mylist[0][1] )&lt;br /&gt;
&lt;br /&gt;
Sorting: (see lambda)&lt;br /&gt;
 data.sort()  # alpha numerica sort&lt;br /&gt;
 data.reverse()  # alpha numerica sort&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# custom sort&lt;br /&gt;
data = [1, 5, 3, 9]&lt;br /&gt;
def mylistcmp(x, y):&lt;br /&gt;
  if x == y: return 0&lt;br /&gt;
  if x &amp;lt; y:&lt;br /&gt;
    return -1&lt;br /&gt;
  else:  # swap 1 and -1 here to reverse&lt;br /&gt;
    return 1&lt;br /&gt;
&lt;br /&gt;
data.sort(cmp=mylistcmp)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Slices:&lt;br /&gt;
 lst = [&#039;1a&#039;, &#039;2b&#039;, &#039;3c&#039;, &#039;4d&#039;, &#039;5e&#039;, &#039;6f&#039;]&lt;br /&gt;
 lst[0]     # &#039;1a&#039;&lt;br /&gt;
 lst[-1]    # &#039;6f&#039; last item&lt;br /&gt;
 lst[0:2]   # [&#039;1a&#039;, &#039;2b&#039;]&lt;br /&gt;
 lst[0:2] = [&#039;11&#039;, &#039;22&#039;]   # lst = [&#039;11&#039;, &#039;22&#039;, &#039;3c&#039;, &#039;4d&#039;, &#039;5e&#039;, &#039;6f&#039;] - assignment to slice&lt;br /&gt;
 lst[0:2] = []   # remove items&lt;br /&gt;
 lst[0:0] = [&#039;1a&#039;, &#039;2b&#039;]   # insert items (at beginning)&lt;br /&gt;
 lst[-1:-1] = [&#039;7g&#039;, &#039;8h&#039;]   # insert items (at item BEFORE last), not really what you want, use append()&lt;br /&gt;
 lst[-1:] = [&#039;7g&#039;, &#039;8h&#039;]   # replace last item&lt;br /&gt;
 lst[:] = []   # clear entire list&lt;br /&gt;
 del(lst[0:2])  # delete slice items&lt;br /&gt;
&lt;br /&gt;
Note: it is not safe to modify a sequence while being iterated over.  Create a copy first:&lt;br /&gt;
 for x in mylst[:]:  # make a slice copy of the entire list&lt;br /&gt;
   if len(x) &amp;gt; 6: a.insert(0,x)&lt;br /&gt;
&lt;br /&gt;
Make list from tuple:&lt;br /&gt;
 list( range(10) )&lt;br /&gt;
&lt;br /&gt;
Merge multiple lists: [http://www.testingreflections.com/node/view/4930]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def merge(seq):&lt;br /&gt;
    merged = []&lt;br /&gt;
    for s in seq:&lt;br /&gt;
        for x in s:&lt;br /&gt;
            merged.append(x)&lt;br /&gt;
    return merged&lt;br /&gt;
&lt;br /&gt;
# sample usage:&lt;br /&gt;
foo = [[&#039;a&#039;, &#039;b&#039;],[&#039;c&#039;],[&#039;d&#039;, &#039;e&#039;, &#039;f&#039;]]&lt;br /&gt;
print merge(foo)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt;[&#039;a&#039;, &#039;b&#039;, &#039;c&#039;, &#039;d&#039;, &#039;e&#039;, &#039;f&#039;]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Tuple ===&lt;br /&gt;
&lt;br /&gt;
Tuple: (immutable or constant)&lt;br /&gt;
 x = ()    # empty tuple&lt;br /&gt;
 x = (5,)  # singleton tuple&lt;br /&gt;
 x = (5)   # NOTE: integer with parenthesis, not tuple&lt;br /&gt;
 &lt;br /&gt;
 s = tuple(&amp;quot;Hello World&amp;quot;)&lt;br /&gt;
 print(s)  # s = (&#039;H&#039;, &#039;e&#039;, &#039;l&#039;, &#039;l&#039;, &#039;o&#039;, &#039; &#039;, &#039;W&#039;, &#039;o&#039;, &#039;r&#039;, &#039;l&#039;, &#039;d&#039;)&lt;br /&gt;
 # ERROR: s[0] = &#039;X&#039;&lt;br /&gt;
&lt;br /&gt;
Make list from tuple:&lt;br /&gt;
 list( range(10) )&lt;br /&gt;
&lt;br /&gt;
Use in conditionals:&lt;br /&gt;
 if answer in (&#039;y&#039;, &#039;ye&#039;, &#039;yes&#039;): ...&lt;br /&gt;
&lt;br /&gt;
Convert tuple string to tuple: [http://stackoverflow.com/questions/3945856/converting-string-to-tuple-and-adding-to-tuple]&lt;br /&gt;
 x = &amp;quot;(1,2,3)&amp;quot;&lt;br /&gt;
 t = tuple(int(v) for v in re.findall(&amp;quot;[0-9]+&amp;quot;, x))&lt;br /&gt;
&lt;br /&gt;
Another Convert tuple string to tuple: [http://stackoverflow.com/questions/3945856/converting-string-to-tuple-and-adding-to-tuple]&lt;br /&gt;
 import ast&lt;br /&gt;
 ast.literal_eval(&amp;quot;(1,2,3,4)&amp;quot;) # (1,2,3,4)&lt;br /&gt;
&lt;br /&gt;
=== Named Tuple ===&lt;br /&gt;
&lt;br /&gt;
What are &amp;quot;named tuples&amp;quot; in Python? - Stack Overflow - http://stackoverflow.com/questions/2970608/what-are-named-tuples-in-python&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from collections import namedtuple&lt;br /&gt;
Point = namedtuple(&#039;Point&#039;, &#039;x y&#039;)&lt;br /&gt;
pt1 = Point(1.0, 5.0)&lt;br /&gt;
pt2 = Point(2.5, 1.5)&lt;br /&gt;
print p1     # point(x=1, y=5)&lt;br /&gt;
print p1.x   # 1.0&lt;br /&gt;
print p1[0]  # 1.0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Dictionary ===&lt;br /&gt;
&lt;br /&gt;
NOTE: Dictionaries are also known as associative arrays, maps or hash tables.&lt;br /&gt;
&lt;br /&gt;
Dictionary: (mutable or modifiable)&lt;br /&gt;
&lt;br /&gt;
 color = {}                      # empty dictionary&lt;br /&gt;
 color = {&#039;red&#039; : 1, &#039;blue&#039;, 2}&lt;br /&gt;
 print( color[&#039;red&#039;] )           # 1&lt;br /&gt;
 print( color.get(&#039;red&#039;) )       # 1&lt;br /&gt;
 print( color.get(&#039;red&#039;, &#039;default&#039;) )       # red if found, or return &#039;default&#039;&lt;br /&gt;
 color[&#039;green&#039;] = 3              # able to add new item on the fly!&lt;br /&gt;
 &#039;red&#039; in color                  # True - check if index exists&lt;br /&gt;
 del(color[&amp;quot;red&amp;quot;])               # delete item&lt;br /&gt;
 len(color)                      # 2 - count of items&lt;br /&gt;
&lt;br /&gt;
List in dictionary&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
d.setdefault(key,[]).append(member)  # tricky!&lt;br /&gt;
&lt;br /&gt;
# more tricky: set default type as list&lt;br /&gt;
from from collections import defaultdict&lt;br /&gt;
d = defaultdict(list)&lt;br /&gt;
d[key].append(member)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Enumeration:&lt;br /&gt;
 for index, key in enumerate(mylist):  print index, key&lt;br /&gt;
&lt;br /&gt;
functions:&lt;br /&gt;
 d.clear()&lt;br /&gt;
 d.copy()&lt;br /&gt;
 d.get(key)&lt;br /&gt;
 d.get(key, default_val)&lt;br /&gt;
 d.update(e)   # update with (key, value) pairs in e&lt;br /&gt;
 d.setdefault(key, value)  # only update if not exist, and return set value&lt;br /&gt;
&lt;br /&gt;
Views: (adjust on the fly as dictionary changes)&lt;br /&gt;
 d.items()  (key, values)&lt;br /&gt;
 for k, v in d.items(): print(k, v)&lt;br /&gt;
 &lt;br /&gt;
 d.keys()&lt;br /&gt;
 for k in d.keys(): print(k)&lt;br /&gt;
 &lt;br /&gt;
 d.values()&lt;br /&gt;
 for v in d.values(): print(v)&lt;br /&gt;
&lt;br /&gt;
Sorting: (see also lambda)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# custom sort of dictionaries in list&lt;br /&gt;
data = [dict(number=x) for x in &#039;036149&#039;]  # create list of dictionaries&lt;br /&gt;
def mydictcmp(x, y):&lt;br /&gt;
  if x[&#039;number&#039;] == y[&#039;number&#039;]: return 0&lt;br /&gt;
  if x[&#039;number&#039;] &amp;lt; y[&#039;number&#039;]:&lt;br /&gt;
    return -1&lt;br /&gt;
  else:  # swap 1 and -1 here to reverse&lt;br /&gt;
    return 1&lt;br /&gt;
&lt;br /&gt;
# data.sort(cmp=mydictcmp)  # modifies data&lt;br /&gt;
&lt;br /&gt;
new_data = sorted(data, cmp=mydictcmp)  # better solution&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sorting:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
my_dict = {&#039;a&#039;:1, &#039;b&#039;:4, &#039;c&#039;:3, &#039;d&#039;:9}&lt;br /&gt;
my_dict_keys = my_dict.keys()&lt;br /&gt;
&lt;br /&gt;
def my_dict_sort(x, y):&lt;br /&gt;
    if my_dict[x] == my_dict[y]: return 0&lt;br /&gt;
    if my_dict[x] &amp;lt; my_dict[y]: return -1&lt;br /&gt;
    if my_dict[x] &amp;gt; my_dict[y]: return 1&lt;br /&gt;
&lt;br /&gt;
#sorted_my_dict = sorted(my_dict_keys, cmp=my_dict_sort, reverse=True)&lt;br /&gt;
sorted_tuple = sorted(my_dict_keys, cmp=my_dict_sort)&lt;br /&gt;
print &amp;quot;Sorted Dictionary:&amp;quot;&lt;br /&gt;
for key in sorted_tuple:&lt;br /&gt;
    print &amp;quot;%s: %d&amp;quot; % (key, my_dict[key])&lt;br /&gt;
&lt;br /&gt;
# a: 1, c: 3, b: 4, d: 9,&lt;br /&gt;
# reverse: d: 9, b: 4, c: 3, a: 1,&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sort and keys:&lt;br /&gt;
 keys = sorted(mydict.keys())&lt;br /&gt;
&lt;br /&gt;
Sort by value: [http://stackoverflow.com/questions/613183/python-sort-a-dictionary-by-value]&lt;br /&gt;
 import operator&lt;br /&gt;
 x = {1: 2, 3: 4, 4:3, 2:1, 0:0}&lt;br /&gt;
 sorted_x = sorted(x.iteritems(), key=operator.itemgetter(1))&lt;br /&gt;
&lt;br /&gt;
Sort options:&lt;br /&gt;
 # LIST.sort(cmp=None, key=None, reverse=False) -- stable sort *IN PLACE*;&lt;br /&gt;
 # sorted(iterable, cmp=None, key=None, reverse=False)&lt;br /&gt;
&lt;br /&gt;
Another: (works well!)&lt;br /&gt;
 sorted(my_dict.items(), key=lambda x: x[1])&lt;br /&gt;
&lt;br /&gt;
See: http://wiki.python.org/moin/HowTo/Sorting/&lt;br /&gt;
&lt;br /&gt;
=== Sets ===&lt;br /&gt;
&lt;br /&gt;
Sets are special lists with unique values (good for removing duplicates)&lt;br /&gt;
 lst = [1, 1, 6, 8, 1, 5]&lt;br /&gt;
 s = set(lst)&lt;br /&gt;
 print(s)  # set([8, 1, 5, 6])&lt;br /&gt;
 s.add(item)&lt;br /&gt;
 item in s  # true&lt;br /&gt;
 s.remove(item)&lt;br /&gt;
&lt;br /&gt;
Union (return combination of all):&lt;br /&gt;
 s.union(t)&lt;br /&gt;
&lt;br /&gt;
Intersection (return matching):&lt;br /&gt;
 s.intersection(t)&lt;br /&gt;
&lt;br /&gt;
Symmetric Difference (return only items not matching either, inverse of intersection):&lt;br /&gt;
 s.symmetric_difference(t)&lt;br /&gt;
 list( set(mylist).symmetric_difference(set(mylist2)) )&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Operation		   Equivalent	Result&lt;br /&gt;
len(s) 	  				cardinality of set s&lt;br /&gt;
x in s 	  				test x for membership in s&lt;br /&gt;
x not in s 	  			test x for non-membership in s&lt;br /&gt;
s.issubset(t) 		   s &amp;lt;= t       test whether every element in s is in t&lt;br /&gt;
s.issuperset(t) 	   s &amp;gt;= t 	test whether every element in t is in s&lt;br /&gt;
s.union(t) 		   s | t 	new set with elements from both s and t&lt;br /&gt;
s.intersection(t)	   s &amp;amp; t 	new set with elements common to s and t&lt;br /&gt;
s.difference(t) 	   s - t	new set with elements in s but not in t&lt;br /&gt;
s.symmetric_difference(t)  s ^ t 	new set with elements in either s or t but not both&lt;br /&gt;
s.copy() 	  			new set with a shallow copy of s&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* sets — Unordered collections of unique elements - http://docs.python.org/library/sets.html&lt;br /&gt;
&lt;br /&gt;
=== Files ===&lt;br /&gt;
&lt;br /&gt;
Open file, get file descriptor:&lt;br /&gt;
 fd = open(&#039;/dev/null&#039;)&lt;br /&gt;
&lt;br /&gt;
File Modes:&lt;br /&gt;
 &#039;r&#039; read (default)&lt;br /&gt;
 &#039;w&#039; write (truncate and create if needed)&lt;br /&gt;
 &#039;a&#039; append (create if needed)&lt;br /&gt;
 &lt;br /&gt;
 &#039;b&#039; binary&lt;br /&gt;
 &#039;t&#039; text (default)&lt;br /&gt;
 &lt;br /&gt;
 &#039;+&#039; read and write&lt;br /&gt;
&lt;br /&gt;
Common Functions: (fd)&lt;br /&gt;
&lt;br /&gt;
 f.read()       # read whole file to string&lt;br /&gt;
 f.read(n)      # read n bytes from file to string&lt;br /&gt;
 f.readline()   # read single line as string (while loop)&lt;br /&gt;
 f.readlines()  # read all lines to list&lt;br /&gt;
&lt;br /&gt;
 f.write(str)   # write string to file (does not auto include new line)&lt;br /&gt;
 f.writelines(list)  # write list to file (does not auto include new lines)&lt;br /&gt;
&lt;br /&gt;
 f.seek(0)      # seek to start of file&lt;br /&gt;
 f.seek(pos)    # seek to position&lt;br /&gt;
 f.truncate()   # truncate file&lt;br /&gt;
&lt;br /&gt;
 f.close()      # close file (fd)&lt;br /&gt;
 f.closed       # True/False flag that reports if file is closed&lt;br /&gt;
&lt;br /&gt;
Help:&lt;br /&gt;
 help(open(&#039;/dev/null&#039;))&lt;br /&gt;
 pydoc file&lt;br /&gt;
&lt;br /&gt;
Read Text File Line by Line&lt;br /&gt;
 f = open(fname, &#039;r&#039;)  # (&#039;r&#039; optional)&lt;br /&gt;
 for line in f:  # or f.readlines()&lt;br /&gt;
   print(line)&lt;br /&gt;
 f.close()  # optional&lt;br /&gt;
&lt;br /&gt;
Write list to file (with new lines):&lt;br /&gt;
 f.writelines(&#039;\n&#039;.join(mylist))&lt;br /&gt;
&lt;br /&gt;
One liner read whole file:&lt;br /&gt;
 print( open( fname, &#039;r&#039; ).read() )&lt;br /&gt;
&lt;br /&gt;
Write text file:&lt;br /&gt;
 # f = open(fname, &#039;a&#039;)  # append text file&lt;br /&gt;
 f = open(fname, &#039;w&#039;)&lt;br /&gt;
 f.write(&amp;quot;Hello\n&amp;quot;)&lt;br /&gt;
 f.write( str(10) )  # convert numbers to strings first&lt;br /&gt;
 f.writelines([&amp;quot;line one\n&amp;quot;, &amp;quot;line two\n&amp;quot;])&lt;br /&gt;
 f.close&lt;br /&gt;
&lt;br /&gt;
Read binary file:&lt;br /&gt;
 def is_gif(fname):&lt;br /&gt;
   f = open(fname, &#039;br&#039;)  # not sure &#039;b&#039; is correct&lt;br /&gt;
   first4 = tuple(f.read(4))&lt;br /&gt;
   return first4 == (0x47, 0x49, 0x46, 0x38)&lt;br /&gt;
&lt;br /&gt;
Read all characters of file:&lt;br /&gt;
 c = f.read(1)&lt;br /&gt;
 while c:&lt;br /&gt;
   # if c == ... logic&lt;br /&gt;
   c = f.read(1)&lt;br /&gt;
&lt;br /&gt;
Reading file in while loop: [http://ubuntuforums.org/showthread.php?t=1092300]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
f=open(&amp;quot;file&amp;quot;)&lt;br /&gt;
while True:&lt;br /&gt;
  line=f.readline()&lt;br /&gt;
  if not line: break&lt;br /&gt;
  print line  &lt;br /&gt;
f.close()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
with - implicit close - [http://www.python.org/dev/peps/pep-0343/ PEP 343 -- The &amp;quot;with&amp;quot; Statement]: [http://docs.python.org/reference/compound_stmts.html#the-with-statement] (python &amp;gt;= 2.5)&lt;br /&gt;
 with open(&amp;quot;/etc/passwd&amp;quot;) as f:&lt;br /&gt;
   # ..., f.read(), etc&lt;br /&gt;
&lt;br /&gt;
With statement: (promptly close open handle at end of block)&lt;br /&gt;
 with open(fname, &#039;r&#039;) as f:&lt;br /&gt;
   for ...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# eqivalent to:&lt;br /&gt;
f = open(&amp;quot;/etc/passwd&amp;quot;)&lt;br /&gt;
f.__enter__()&lt;br /&gt;
try:&lt;br /&gt;
  ...&lt;br /&gt;
finally:&lt;br /&gt;
  f.__exit__()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
cat: (for grabbing a configuration line)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def cat(filename):&lt;br /&gt;
    with open(filename) as f:&lt;br /&gt;
        return f.readline().strip()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== With ===&lt;br /&gt;
&lt;br /&gt;
PEP 343 -- The &amp;quot;with&amp;quot; Statement - http://www.python.org/dev/peps/pep-0343/&lt;br /&gt;
&lt;br /&gt;
&#039;with&#039; structure:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
with EXPR as VAR:&lt;br /&gt;
  BLOCK&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
translates to:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
VAR = EXPR&lt;br /&gt;
VAR.__enter__()&lt;br /&gt;
try:&lt;br /&gt;
  BLOCK&lt;br /&gt;
finally:&lt;br /&gt;
  VAR.__exit__()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: The &amp;quot;as VAR&amp;quot; part is optional.  Good for locking:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
with locking(myLock):&lt;br /&gt;
  BLOCK&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
with - implicit close - [http://www.python.org/dev/peps/pep-0343/ PEP 343 -- The &amp;quot;with&amp;quot; Statement]: [http://docs.python.org/reference/compound_stmts.html#the-with-statement] (python &amp;gt;= 2.5)&lt;br /&gt;
 with open(&amp;quot;/etc/passwd&amp;quot;) as f:&lt;br /&gt;
   ...&lt;br /&gt;
&lt;br /&gt;
With statement: (promptly close open handle at end of block)&lt;br /&gt;
 with open(fname, &#039;r&#039;) as f:&lt;br /&gt;
   for ...&lt;br /&gt;
&lt;br /&gt;
See also [[#Files]]&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* PEP 343 -- The &amp;quot;with&amp;quot; Statement - http://www.python.org/dev/peps/pep-0343/&lt;br /&gt;
* PEP 340 -- Anonymous Block Statements - http://www.python.org/dev/peps/pep-0340/&lt;br /&gt;
&lt;br /&gt;
=== Try Exception Handling ===&lt;br /&gt;
&lt;br /&gt;
Exception Handling - http://docs.python.org/release/2.6.6/tutorial/errors.html&lt;br /&gt;
&lt;br /&gt;
throw execption:&lt;br /&gt;
 raise [EXCEPTION]&lt;br /&gt;
 raise IOError(&amp;quot;This is a test!&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Catch exceptions:&lt;br /&gt;
 try:&lt;br /&gt;
 except ( [EXCEPTION], [EXCEPTION] ):&lt;br /&gt;
 except [EXCEPTION]:&lt;br /&gt;
 except [EXCEPTION] as err:  # use &amp;quot;[EXCEPTION], err&amp;quot; in python &amp;lt; 2.6&lt;br /&gt;
   print(&amp;quot;Error: {}&amp;quot;.format(err))&lt;br /&gt;
 except:&lt;br /&gt;
   raise   # reraise caught error that is not handled&lt;br /&gt;
 else:     # if no exception caught&lt;br /&gt;
 finally:  # always executed&lt;br /&gt;
&lt;br /&gt;
Note: Usually a good idea to re-raise exception if you don&#039;t handle it (just &#039;raise&#039;)&lt;br /&gt;
&lt;br /&gt;
General Exception: (all exceptions inherit from Exception)&lt;br /&gt;
 try:&lt;br /&gt;
   raise Exception(&#039;spam&#039;, &#039;eggs&#039;)&lt;br /&gt;
 except Exception as e:&lt;br /&gt;
   pass&lt;br /&gt;
&lt;br /&gt;
Custom Exception Class:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class MyError(Exception):&lt;br /&gt;
  &amp;quot;&amp;quot;&amp;quot;My Error Exception&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
class MyException(Exception):&lt;br /&gt;
    pass&lt;br /&gt;
&lt;br /&gt;
rasie MyError(&amp;quot;My Error&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class ValidationError(Exception):&lt;br /&gt;
    def __init__(self, message, Errors):&lt;br /&gt;
&lt;br /&gt;
        # Call the base class constructor with the parameters it needs&lt;br /&gt;
        Exception.__init__(self, message)&lt;br /&gt;
&lt;br /&gt;
        # Now for your custom code...&lt;br /&gt;
        self.Errors = Errors&lt;br /&gt;
    def __str__(self):&lt;br /&gt;
        return &amp;quot;MyErrors - %s&amp;quot; % self.Errors&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Rename standard exception:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Failure(StandardError):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;Exception for unexpected failures.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: a good place to hide the exception classes in the __init__.py file.&lt;br /&gt;
&lt;br /&gt;
==== exception line number ====&lt;br /&gt;
&lt;br /&gt;
Python When I catch an exception, how do I get the type, file, and line number? - Stack Overflow [http://stackoverflow.com/questions/1278705/python-when-i-catch-an-exception-how-do-i-get-the-type-file-and-line-number]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import sys, os&lt;br /&gt;
&lt;br /&gt;
try:&lt;br /&gt;
    raise NotImplementedError(&amp;quot;No error&amp;quot;)&lt;br /&gt;
except Exception as e:&lt;br /&gt;
    exc_type, exc_obj, exc_tb = sys.exc_info()&lt;br /&gt;
    fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]&lt;br /&gt;
    print(exc_type, fname, exc_tb.tb_lineno)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== traceback ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import traceback&lt;br /&gt;
    try:&lt;br /&gt;
    ...&lt;br /&gt;
    except Exception as E:&lt;br /&gt;
        ...&lt;br /&gt;
        print &#039;Traceback: %s&#039;, traceback.format_exc()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Catching multiple exceptions and getting properties from the exception:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import traceback&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
class MyError(Exception):&lt;br /&gt;
  &amp;quot;&amp;quot;&amp;quot;My Error Exception&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
try:&lt;br /&gt;
  #raise ValueError(&amp;quot;a value error&amp;quot;)  # &amp;lt;type &#039;exceptions.ValueError&#039;&amp;gt;&lt;br /&gt;
  raise MyError(&amp;quot;a my error&amp;quot;)         # &amp;lt;class &#039;__main__.MyError&#039;&amp;gt;&lt;br /&gt;
  raise Exception(&amp;quot;won&#039;t be caught&amp;quot;)  # &amp;lt;type &#039;exceptions.Exception&#039;&amp;gt;&lt;br /&gt;
except (ValueError, MyError) as e:&lt;br /&gt;
  print type(e)       # &amp;lt;class &#039;__main__.MyError&#039;&amp;gt;&lt;br /&gt;
  print e             # __str__() = a my error&lt;br /&gt;
  msg = str(e)        # msg = &#039;a my error&#039;&lt;br /&gt;
  print e.__doc__     # My Error Exception&lt;br /&gt;
  print e.__str__()   # a my error&lt;br /&gt;
  print e.__repr__()  # MyError(&#039;a my error&#039;,)&lt;br /&gt;
  print e.args        # (&#039;a my error&#039;,)&lt;br /&gt;
  x = e               # __getitem__() allows args to be unpacked directly&lt;br /&gt;
  # x, y = e          # if two args were passed, use len(e.args) to see count&lt;br /&gt;
&lt;br /&gt;
  # manually print stack trace (import traceback, sys)&lt;br /&gt;
  print &amp;quot;Exception in user code:&amp;quot;&lt;br /&gt;
  print &#039;-&#039;*60&lt;br /&gt;
  traceback.print_exc(file=sys.stdout)&lt;br /&gt;
  # stack_trace = traceback.format_exc()&lt;br /&gt;
  print &#039;-&#039;*60&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Object Oriented Programming ===&lt;br /&gt;
&lt;br /&gt;
Terms:&lt;br /&gt;
* encapsulates&lt;br /&gt;
* inheritance&lt;br /&gt;
* polymorphism&lt;br /&gt;
* method overriding&lt;br /&gt;
&lt;br /&gt;
==== class ====&lt;br /&gt;
&lt;br /&gt;
class animal.py:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Animal(object):  # default &amp;quot;(object)&amp;quot; not required&lt;br /&gt;
  &amp;quot; Animal class &amp;quot;&lt;br /&gt;
  def __init__(self, name):&lt;br /&gt;
    self.name = name       # name is private variable&lt;br /&gt;
    self.__iam = &amp;quot;animal&amp;quot;  # __iam is private variable&lt;br /&gt;
  def __str__(self):       # string representation&lt;br /&gt;
    return &amp;quot;name = &#039;%s&#039;&amp;quot; % (self.name)&lt;br /&gt;
  def __repr__(self):      # object representation (just typing instance in IDLE, or repr())&lt;br /&gt;
    return &#039;Animal(%s)&#039; % str(self)  # returns __str__&lt;br /&gt;
  def speak(self, msg=&#039;Nothing to say&#039;):&lt;br /&gt;
    print(msg)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: if no __str__ defined, but __repr__ is, then:  __str__ = __repr__&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from animal import Animal&lt;br /&gt;
a = Animal(&#039;good&#039;)&lt;br /&gt;
print(a.__doc__)  # Animal class&lt;br /&gt;
print(a)          # name = &#039;good&#039;&lt;br /&gt;
a                 # Animal(name = &#039;good&#039;)&lt;br /&gt;
print(a.name)     # good&lt;br /&gt;
a.speak(&#039;hi&#039;)     # hi&lt;br /&gt;
print(a._Animal__iam)  # animal - access to private variable (shouldn&#039;t do)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
subclass dog.py:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from animal import Animal&lt;br /&gt;
class Dog(Animal):&lt;br /&gt;
  &amp;quot; Dog class &amp;quot;&lt;br /&gt;
  def __init__(self, name):&lt;br /&gt;
    self.name = name      # name is private variable&lt;br /&gt;
    self.__iam = &amp;quot;dog&amp;quot;    # __iam is private variable&lt;br /&gt;
  # NOTICE: no __str__, inherited from super class&lt;br /&gt;
  def __repr__(self):     # override to reflect &amp;quot;dog&amp;quot;&lt;br /&gt;
    return &#039;Dog(%s)&#039; % str(self)  # returns __str__&lt;br /&gt;
  def speak(self, msg=&#039;Nothing to say&#039;):   # override method&lt;br /&gt;
    super(Dog, self).speak(&#039;Dog says: &#039; + msg)     # call super class method&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Subclass usage:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from dog import Dog&lt;br /&gt;
d = Dog(&#039;bad&#039;)&lt;br /&gt;
print(d.__doc__)    # Dog class&lt;br /&gt;
print(d)            # name = &#039;bad&#039;&lt;br /&gt;
d                   # Dog(name = &#039;bad&#039;)&lt;br /&gt;
print(d.name)       # bad&lt;br /&gt;
d.speak(&#039;hi&#039;)       # Dog says: hi&lt;br /&gt;
print(d._Dog__iam)  # dog - access to private variable (shouldn&#039;t do)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Super: [http://stackoverflow.com/questions/576169/understanding-python-super-with-init-methods]&lt;br /&gt;
 # python 3.0&lt;br /&gt;
 super().__init__()&lt;br /&gt;
&lt;br /&gt;
 # python 2.7&lt;br /&gt;
 super(self.__class__, self).__init__()&lt;br /&gt;
 super([CLASSNAME], self).__init__()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Rectangle(Polygon):&lt;br /&gt;
    def __init__(self, id, width, height):&lt;br /&gt;
        #  super(Rectangle, self).__init__(id)&lt;br /&gt;
        super(self.__class__, self).__init__(id)&lt;br /&gt;
        self.shape = (width, height)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Get class name:&lt;br /&gt;
 self.__class__.__name__&lt;br /&gt;
 obj.__class__.__name__&lt;br /&gt;
&lt;br /&gt;
Full name:&lt;br /&gt;
 obj.__module__ + &amp;quot;.&amp;quot; + obj.__class__.__name__&lt;br /&gt;
&lt;br /&gt;
Private variables: (uses name mangling)&lt;br /&gt;
  self.__age&lt;br /&gt;
  # direct access:  _classname__varname  (eg. p._Person__age = 44)&lt;br /&gt;
&lt;br /&gt;
Tests:&lt;br /&gt;
 isinstance(myobj, myclass)  # check if myobj is a class or subclass of myclass &lt;br /&gt;
 issubclass(A, B)  # check if A is subclass of B&lt;br /&gt;
 issubclass(Exception, BaseException)  # True&lt;br /&gt;
&lt;br /&gt;
Multiple Inheritance:  (methods searched in order)&lt;br /&gt;
 class DerviedClass(Base1, Base2, Base3):&lt;br /&gt;
   pass&lt;br /&gt;
&lt;br /&gt;
Standard startup script:&lt;br /&gt;
 class MyClass():&lt;br /&gt;
     ...&lt;br /&gt;
     @classmethod&lt;br /&gt;
     def main(cls, argv=None):&lt;br /&gt;
         ...&lt;br /&gt;
         # return cls() # creator&lt;br /&gt;
 if __name__ == &amp;quot;__main__&amp;quot;;&lt;br /&gt;
     sys.exit(MyClass.main(sys.argv))&lt;br /&gt;
&lt;br /&gt;
Raise an error if a method is not overridden (not implemented)&lt;br /&gt;
    def _get_dist(self):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Find linux disto. Implemented in subclasses.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        raise NotImplementedError&lt;br /&gt;
&lt;br /&gt;
==== Multiple Constructors ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Animal(object):&lt;br /&gt;
&lt;br /&gt;
  def __init__(self, name):&lt;br /&gt;
    self.name = name&lt;br /&gt;
&lt;br /&gt;
  @classmethod&lt;br /&gt;
  def create_fido(cls):&lt;br /&gt;
    return cls(&amp;quot;fido&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Descriptor Classes ====&lt;br /&gt;
&lt;br /&gt;
&amp;quot;In general, a descriptor is an object attribute with “binding behavior”, one whose attribute access has been overridden by methods in the descriptor protocol: __get__(), __set__(), and __delete__(). If any of those methods are defined for an object, it is said to be a descriptor.&amp;quot; [http://docs.python.org/2/reference/datamodel.html#implementing-descriptors]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
object.__get__(self, instance, owner)&lt;br /&gt;
&lt;br /&gt;
    Called to get the attribute of the owner class (class attribute access) or of an instance of that&lt;br /&gt;
    class (instance attribute access). owner is always the owner class, while instance is the instance&lt;br /&gt;
    that the attribute was accessed through, or None when the attribute is accessed through the owner.&lt;br /&gt;
    This method should return the (computed) attribute value or raise an AttributeError exception.&lt;br /&gt;
&lt;br /&gt;
object.__set__(self, instance, value)&lt;br /&gt;
&lt;br /&gt;
    Called to set the attribute on an instance instance of the owner class to a new value, value.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example: [http://stackoverflow.com/questions/3798835/understanding-get-and-set-and-python-descriptors]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Celsius(object):&lt;br /&gt;
    def __init__(self, value=0.0):&lt;br /&gt;
        self.value = float(value)&lt;br /&gt;
    def __get__(self, instance, owner):&lt;br /&gt;
        return self.value&lt;br /&gt;
    def __set__(self, instance, value):&lt;br /&gt;
        self.value = float(value)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
class Temperature(object):&lt;br /&gt;
    celsius = Celsius()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
t = Temperature()&lt;br /&gt;
t.celsius = 5    # calls Celsius.__set__&lt;br /&gt;
print t.celsius  # calls Celsius.__get__&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: Also appears in &#039;pydoc&#039; under &amp;quot;Data descriptors defined here&amp;quot; with object&#039;s docstring.  Trick: the __doc__ can be overridden in the __init__ method, which makes for dynamic docstrings!&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* Descriptor HowTo Guide — Python v2.7.5 documentation - http://docs.python.org/2/howto/descriptor.html&lt;br /&gt;
* 3.4.2.2. Implementing Descriptors¶ - 3. Data model — Python v2.7.5 documentation - http://docs.python.org/2/reference/datamodel.html#implementing-descriptors&lt;br /&gt;
&lt;br /&gt;
=== [http://docs.python.org/reference/simple_stmts.html#the-exec-statement exec code] ===&lt;br /&gt;
&lt;br /&gt;
DANGEROUS!&lt;br /&gt;
&lt;br /&gt;
Execute code in string:&lt;br /&gt;
 exec( &#039;print(&amp;quot;hi&amp;quot;)&#039; )&lt;br /&gt;
&lt;br /&gt;
Example of executing a startup script for IDLE:&lt;br /&gt;
 if os.path.isfile(&#039;.pythonrc.py&#039;): exec(open(&#039;.pythonrc.py&#039;).read())&lt;br /&gt;
&lt;br /&gt;
 import os&lt;br /&gt;
 filename = os.environ.get(&#039;PYTHONSTARTUP&#039;)&lt;br /&gt;
 if filename and os.path.isfile(filename):&lt;br /&gt;
   exec(open(filename).read())&lt;br /&gt;
&lt;br /&gt;
=== eval ===&lt;br /&gt;
&lt;br /&gt;
VERY DANGEROUS&lt;br /&gt;
&lt;br /&gt;
Will execute a string as though it were pure python code!&lt;br /&gt;
&lt;br /&gt;
 eval(&amp;quot;print &#039;hello&#039;&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
=== Common Header Format ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
__author__ = &amp;quot;software team&amp;quot;&lt;br /&gt;
__date__ =&amp;quot;$Feb 15, 2011 1:42:17 PM$&amp;quot;&lt;br /&gt;
__version__ = &amp;quot;1.1.0.441 bandelier@66d9fe1edf3e&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Next should be authorship information. This information should follow this format:&lt;br /&gt;
&lt;br /&gt;
__author__ = &amp;quot;Rob Knight, Gavin Huttley, and Peter Maxwell&amp;quot;&lt;br /&gt;
__copyright__ = &amp;quot;Copyright 2007, The Cogent Project&amp;quot;&lt;br /&gt;
__credits__ = [&amp;quot;Rob Knight&amp;quot;, &amp;quot;Peter Maxwell&amp;quot;, &amp;quot;Gavin Huttley&amp;quot;,&lt;br /&gt;
                    &amp;quot;Matthew Wakefield&amp;quot;]&lt;br /&gt;
__license__ = &amp;quot;GPL&amp;quot;&lt;br /&gt;
__version__ = &amp;quot;1.0.1&amp;quot;&lt;br /&gt;
__maintainer__ = &amp;quot;Rob Knight&amp;quot;&lt;br /&gt;
__email__ = &amp;quot;rob@spot.colorado.edu&amp;quot;&lt;br /&gt;
__status__ = &amp;quot;Production&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Source: Python Coding Guidelines - http://bayes.colorado.edu/PythonGuidelines.html&lt;br /&gt;
&lt;br /&gt;
These will show up in the help() like such:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Help on module test:&lt;br /&gt;
&lt;br /&gt;
NAME&lt;br /&gt;
    test&lt;br /&gt;
&lt;br /&gt;
FILE&lt;br /&gt;
    /home/kenneth/test.py&lt;br /&gt;
&lt;br /&gt;
FUNCTIONS&lt;br /&gt;
    test()&lt;br /&gt;
&lt;br /&gt;
DATA&lt;br /&gt;
    __author__ = &#039;test author&#039;&lt;br /&gt;
    __version__ = &#039;1.0&#039;&lt;br /&gt;
&lt;br /&gt;
VERSION&lt;br /&gt;
    1.0&lt;br /&gt;
&lt;br /&gt;
AUTHOR&lt;br /&gt;
    test author&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* Python: What is the common header format? - Stack Overflow - http://stackoverflow.com/questions/1523427/python-what-is-the-common-header-format&lt;br /&gt;
&lt;br /&gt;
=== Common Environment Variables ===&lt;br /&gt;
&lt;br /&gt;
 Command line and environment — Python v2.7.2 documentation - http://docs.python.org/using/cmdline.htm&lt;br /&gt;
&lt;br /&gt;
PYTHONUNBUFFERED&lt;br /&gt;
: If this is set to a non-empty string it is equivalent to specifying the -u option. [http://docs.python.org/using/cmdline.html#envvar-PYTHONUNBUFFERED]&lt;br /&gt;
: -u - Force stdin, stdout and stderr to be totally unbuffered. On systems where it matters, also put stdin, stdout and stderr in binary mode.&lt;br /&gt;
* See also stdout - Python output buffering - Stack Overflow - http://stackoverflow.com/questions/107705/python-output-buffering&lt;br /&gt;
 export PYTHONUNBUFFERED=1&lt;br /&gt;
 set PYTHONUNBUFFERED=1&lt;br /&gt;
&lt;br /&gt;
PYTHONVERBOSE&lt;br /&gt;
:If this is set to a non-empty string it is equivalent to specifying the -v option. If set to an integer, it is equivalent to specifying -v multiple times.&lt;br /&gt;
: -v - Print a message each time a module is initialized, showing the place (filename or built-in module) from which it is loaded.&lt;br /&gt;
 export PYTHONVERBOSE=1&lt;br /&gt;
 set PYTHONVERBOSE=1&lt;br /&gt;
&lt;br /&gt;
PYTHONPATH&lt;br /&gt;
: Augment the default search path for module files. The format is the same as the shell’s PATH: one or more directory pathnames separated by os.pathsep (e.g. colons on Unix or semicolons on Windows). Non-existent directories are silently ignored. [http://docs.python.org/using/cmdline.html#envvar-PYTHONPATH]&lt;br /&gt;
 export PYTHONPATH=/path1/:path2/&lt;br /&gt;
 set PYTHONPATH=C:\path1\;C:\path2\&lt;br /&gt;
&lt;br /&gt;
=== Queue ===&lt;br /&gt;
&lt;br /&gt;
Good for threading.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;The Queue module implements multi-producer, multi-consumer queues. It is especially useful in threaded programming when information must be exchanged safely between multiple threads. The Queue class in this module implements all the required locking semantics.&amp;quot; [http://docs.python.org/2/library/queue.html]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import Queue&lt;br /&gt;
&lt;br /&gt;
bucket = Queue.Queue()&lt;br /&gt;
bucket.put(&amp;quot;something&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
while True:&lt;br /&gt;
    try:&lt;br /&gt;
        item = bucket.get(block=False)&lt;br /&gt;
    except Queue.Empty:&lt;br /&gt;
        pass&lt;br /&gt;
    else:&lt;br /&gt;
        # do stuff with queue&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Important methods:&lt;br /&gt;
  Queue.qsize()&lt;br /&gt;
  Queue.empty()&lt;br /&gt;
  Queue.put(item[, block[, timeout]])&lt;br /&gt;
  Queue.get([block[, timeout]])&lt;br /&gt;
&lt;br /&gt;
-&lt;br /&gt;
&lt;br /&gt;
Example: http://docs.python.org/2/library/queue.html&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def worker():&lt;br /&gt;
    while True:&lt;br /&gt;
        item = q.get()&lt;br /&gt;
        do_work(item)&lt;br /&gt;
        q.task_done()&lt;br /&gt;
&lt;br /&gt;
q = Queue()&lt;br /&gt;
for i in range(num_worker_threads):&lt;br /&gt;
     t = Thread(target=worker)&lt;br /&gt;
     t.daemon = True&lt;br /&gt;
     t.start()&lt;br /&gt;
&lt;br /&gt;
for item in source():&lt;br /&gt;
    q.put(item)&lt;br /&gt;
&lt;br /&gt;
q.join()       # block until all tasks are done&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
-&lt;br /&gt;
&lt;br /&gt;
&amp;quot;The module implements three types of queue, which differ only in the order in which the entries are retrieved. In a FIFO queue, the first tasks added are the first retrieved. In a LIFO queue, the most recently added entry is the first retrieved (operating like a stack). With a priority queue, the entries are kept sorted (using the heapq module) and the lowest valued entry is retrieved first.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Queue Types:&lt;br /&gt;
  class Queue.Queue(maxsize=0)          # FIFO Queue&lt;br /&gt;
  class Queue.LifoQueue(maxsize=0)      # LIFO Queue&lt;br /&gt;
  class Queue.PriorityQueue(maxsize=0)  # Priority Queue&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* 8.10. Queue — A synchronized queue class — Python v2.7.5 documentation - http://docs.python.org/2/library/queue.html&lt;br /&gt;
&lt;br /&gt;
== Recipes ==&lt;br /&gt;
&lt;br /&gt;
=== Remove Numbers from String ===&lt;br /&gt;
&lt;br /&gt;
Using list comprehension: [http://stackoverflow.com/questions/12851791/removing-numbers-from-string]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
result = &#039;&#039;.join([i for i in s if not i.isdigit()])&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Using pattern matching:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; re.compile(r&#039;\D+&#039;).findall(&amp;quot;test 1234 test 1234&amp;quot;)&lt;br /&gt;
[&#039;test &#039;, &#039; test &#039;]&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; re.compile(r&amp;quot;\d&amp;quot;).sub(&amp;quot;&amp;quot;, &amp;quot;test 1234 test 1234&amp;quot;)&lt;br /&gt;
&#039;test  test &#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Retry Wrapper ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import functool&lt;br /&gt;
class SomethingRetry:&lt;br /&gt;
&lt;br /&gt;
    def retry_with_backoff(retries: int, base_delay: float, exceptions: tuple[type[Exception], ...] = (Exception,)) -&amp;gt; callable:&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Retries a function with exponential backoff, doubling on each attempt.&lt;br /&gt;
        Arguments:&lt;br /&gt;
            retries: Number of retry attempts.&lt;br /&gt;
            base_delay: Initial delay between retries in seconds.&lt;br /&gt;
            exceptions: Tuple of exceptions to catch and retry.&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
        def decorator(func):&lt;br /&gt;
            @functools.wraps(func)&lt;br /&gt;
            def wrapper(*args, **kwargs):&lt;br /&gt;
                for attempt in range(1, retries + 1):&lt;br /&gt;
                    try:&lt;br /&gt;
                        return func(*args, **kwargs)&lt;br /&gt;
                    except exceptions as e:&lt;br /&gt;
                        print(f&amp;quot;Warning: Attempt {attempt} failed with error: {e}&amp;quot;)&lt;br /&gt;
                        if attempt == retries:&lt;br /&gt;
                            print(&amp;quot;Error: All retry attempts failed.&amp;quot;)&lt;br /&gt;
                            raise&lt;br /&gt;
                        sleep_time = base_delay * (2 ** (attempt - 1))&lt;br /&gt;
                        print(f&amp;quot;Notice: Retrying in {sleep_time} seconds...&amp;quot;)&lt;br /&gt;
                        time.sleep(sleep_time)&lt;br /&gt;
            return wrapper&lt;br /&gt;
        return decorator&lt;br /&gt;
&lt;br /&gt;
    @retry_with_backoff(retries=6, base_delay=10, exceptions=(Exception,))&lt;br /&gt;
    def do_something(self, sample_param: str):&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Standard Libraries ==&lt;br /&gt;
&lt;br /&gt;
=== user input ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
line = raw_input()  # Python 2&lt;br /&gt;
# line = input()    # Python 2&lt;br /&gt;
line = input(&#039;What is your name: &#039;)&lt;br /&gt;
print(&amp;quot;: &amp;quot; + line.strip() + &amp;quot; :&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== sys - stdout stderr stdin ===&lt;br /&gt;
&lt;br /&gt;
STDOUT:&lt;br /&gt;
 import sys&lt;br /&gt;
 sys.stdout.write(&amp;quot;Hello &amp;quot;)  # does not write new line&lt;br /&gt;
 sys.stdout.write(&amp;quot;World\n&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
STDERR:&lt;br /&gt;
 import sys&lt;br /&gt;
 sys.stderr.write(&amp;quot;ERROR!\n&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
STDIN:&lt;br /&gt;
 import sys&lt;br /&gt;
 line = sys.stdin.readline()&lt;br /&gt;
&lt;br /&gt;
 line = input()   # use raw_input() in Python 2&lt;br /&gt;
 line = input(&#039;What is your name: &#039;)&lt;br /&gt;
 print(&amp;quot;: &amp;quot; + line.strip() + &amp;quot; :&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Read piped stdin line by line: [http://stackoverflow.com/questions/1450393/how-do-you-read-from-stdin-in-python]&lt;br /&gt;
 # cat /etc/passwd | ./readlines.py     # linux&lt;br /&gt;
 # type file.txt | python readlines.py  # windows&lt;br /&gt;
&lt;br /&gt;
 # fileinput.input() - returns fileinput object which is iterative&lt;br /&gt;
 import fileinput&lt;br /&gt;
 for line in fileinput.input():&lt;br /&gt;
     print(&amp;quot;: &amp;quot; + line + &amp;quot; :&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
 # sys.stdin.readlines() - returns list of strings&lt;br /&gt;
 import sys&lt;br /&gt;
 for line in sys.stdin.readlines():&lt;br /&gt;
     print(&amp;quot;: &amp;quot; + line + &amp;quot; :&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
 # sys.stdin - returns object which is iterative&lt;br /&gt;
 import sys&lt;br /&gt;
 for line in sys.stdin:&lt;br /&gt;
     print(&amp;quot;: &amp;quot; + line + &amp;quot; :&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
 # ugly while loop: [http://ubuntuforums.org/showthread.php?t=1092300]&lt;br /&gt;
 while True:&lt;br /&gt;
     try:&lt;br /&gt;
         s = raw_input(&amp;quot;Say something &amp;quot;)&lt;br /&gt;
     except EOFError:&lt;br /&gt;
         break&lt;br /&gt;
     print &amp;quot;: %s&amp;quot; % s&lt;br /&gt;
&lt;br /&gt;
Check if stdin has any waiting data: [http://stackoverflow.com/questions/3762881/how-do-i-check-if-stdin-has-some-data]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import sys&lt;br /&gt;
import select&lt;br /&gt;
&lt;br /&gt;
# if select.select([sys.stdin,],[],[],0.0)[0]:  # alternative old method&lt;br /&gt;
&lt;br /&gt;
if not sys.stdin.isatty():&lt;br /&gt;
    print &amp;quot;Have data!&amp;quot;&lt;br /&gt;
    print sys.stdin.readlines()&lt;br /&gt;
else:&lt;br /&gt;
    print &amp;quot;No data&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if len(sys.argv) &amp;gt; 1:&lt;br /&gt;
    message = &#039; &#039;.join(sys.argv[1:])&lt;br /&gt;
elif not sys.stdin.isatty():&lt;br /&gt;
    # read from pipe in&lt;br /&gt;
    message = sys.stdin.readline()&lt;br /&gt;
else:&lt;br /&gt;
    # read from user&lt;br /&gt;
    sys.stdout.write(&amp;quot;Message: &amp;quot;)&lt;br /&gt;
    message = raw_input().strip()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [http://docs.python.org/library/re.html Regular Expressions] ===&lt;br /&gt;
&lt;br /&gt;
Import:&lt;br /&gt;
 import re  # user regular expressions&lt;br /&gt;
&lt;br /&gt;
Match vs Search:&lt;br /&gt;
 re.match(&amp;quot;cde&amp;quot;, &amp;quot;abcdef&amp;quot;)  # no match (match searches beginning of string, first match)&lt;br /&gt;
 re.match(&amp;quot;abc&amp;quot;, &amp;quot;abcdef&amp;quot;)  # match (match searches beginning of string, first match)&lt;br /&gt;
 re.search(&amp;quot;cd&amp;quot;, &amp;quot;abcdef&amp;quot;)  # match (matches any location, first match)&lt;br /&gt;
&lt;br /&gt;
Both re.match() and re.search() return objects that are not intuitive to use.  You can check the object&#039;s group() method for what matched, but I prefer re.findall().&lt;br /&gt;
&lt;br /&gt;
Match:&lt;br /&gt;
 s = &#039;done&#039;&lt;br /&gt;
 if re.match(&#039;done|quit&#039;, s) != None  # True&lt;br /&gt;
&lt;br /&gt;
Search:&lt;br /&gt;
 s = &#039;done&#039;&lt;br /&gt;
 if re.search(&#039;do&#039;, s) != None  # True&lt;br /&gt;
&lt;br /&gt;
Replace:&lt;br /&gt;
 msg = &#039;jello world&#039;&lt;br /&gt;
 msg = re.sub(&#039;jello&#039;, &#039;hello&#039;, msg)&lt;br /&gt;
&lt;br /&gt;
For case intensive searches append 3rd parameter &amp;quot;re.I&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Find all:&lt;br /&gt;
 re.findall(&amp;quot;[a-z]+&amp;quot;, &amp;quot;aaa111bbb222&amp;quot;)       # [&#039;aaa&#039;, &#039;bbb&#039;]&lt;br /&gt;
 re.findall(&amp;quot;111([a-z]+)&amp;quot;, &amp;quot;aaa111bbb222&amp;quot;)  # [&#039;bbb&#039;]&lt;br /&gt;
 re.findall(&amp;quot;hello&amp;quot;, &amp;quot;HELLO&amp;quot;, re.I)         # [&#039;HELLO&#039;] - Case Insensitive&lt;br /&gt;
&lt;br /&gt;
Split:&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; re.split(&#039;[a-z]+&#039;,&#039;111aaa222bbb&#039;)&lt;br /&gt;
 [&#039;111&#039;, &#039;222&#039;, &#039;&#039;]&lt;br /&gt;
&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; re.split(&#039;([a-z]+)&#039;,&#039;111aaa222bbb&#039;)  # parenthesis cause return of all&lt;br /&gt;
 [&#039;111&#039;, &#039;aaa&#039;, &#039;222&#039;, &#039;bbb&#039;, &#039;&#039;]&lt;br /&gt;
&lt;br /&gt;
Replacement Substitution:&lt;br /&gt;
 # re.sub(pattern, repl, string[, count, flags])&lt;br /&gt;
 re.sub(r&#039;\\&#039;, r&#039;/&#039;, r&#039;\\data\files&#039;)&lt;br /&gt;
&lt;br /&gt;
Compiled regular express for repeated use: (performance)&lt;br /&gt;
 valid = re.compile(r&amp;quot;[0-9]+&amp;quot;)&lt;br /&gt;
 valid.match(&amp;quot;aaa111bbb&amp;quot;)               # not valid&lt;br /&gt;
 match = valid.search(&amp;quot;aaa111bbb222&amp;quot;)   # valid&lt;br /&gt;
 print(match.group())                   # what matched: &#039;111&#039;&lt;br /&gt;
&lt;br /&gt;
=== Date and Time ===&lt;br /&gt;
&lt;br /&gt;
Sleep in seconds:&lt;br /&gt;
 import time&lt;br /&gt;
 time.sleep(seconds)&lt;br /&gt;
&lt;br /&gt;
Use the following functions to convert between time representations:&lt;br /&gt;
&amp;lt;table border=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;From&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;To&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Use&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;seconds since the epoch&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;struct_time in UTC&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;gmtime()&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;seconds since the epoch&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;struct_time in local time&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;localtime()&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;struct_time in UTC&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;seconds since the epoch&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;calendar.timegm()&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;struct_time in local time&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;seconds since the epoch&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;mktime()&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Date formats:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; time.strftime(&amp;quot;%Y-%m-%d %H:%M:%S&amp;quot;, time.localtime())&lt;br /&gt;
&#039;2014-04-04 12:22:43&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; time.time()&lt;br /&gt;
1396635763.0581281&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; datetime.datetime.now()&lt;br /&gt;
datetime.datetime(2014, 4, 4, 12, 22, 43, 58456)&lt;br /&gt;
# datetime(year, month, day, hour, minute, second, microsecond)&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; time.localtime()&lt;br /&gt;
time.struct_time(tm_year=2014, tm_mon=4, tm_mday=4, tm_hour=12, tm_min=22, tm_sec=43, tm_wday=4, tm_yday=94, tm_isdst=1)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Current epoch time:&lt;br /&gt;
 int(time.time())&lt;br /&gt;
&lt;br /&gt;
Time zone offset:&lt;br /&gt;
 standard_tz_offset = - time.timezone / 3600  # 7&lt;br /&gt;
 daylight_tz_offset = - time.altzone / 3600  # 6&lt;br /&gt;
&lt;br /&gt;
Is daylight saving time: [http://stackoverflow.com/questions/2881025/python-daylight-savings-time]&lt;br /&gt;
 import time&lt;br /&gt;
 time.localtime()&lt;br /&gt;
 _.tm_isdst  # 0 or 1&lt;br /&gt;
&lt;br /&gt;
 mst_epoch_time = time.time()  # server in MST/MDT&lt;br /&gt;
 if time.localtime().tm_isdst:  # are we in daylight saving time?&lt;br /&gt;
   utc_epoch_time = mst_epoch_time + time.altzone&lt;br /&gt;
 else:&lt;br /&gt;
   utc_epoch_time = mst_epoch_time + time.timezone&lt;br /&gt;
&lt;br /&gt;
Format current time: [http://docs.python.org/2/library/time.html#time.strftime]&lt;br /&gt;
 time.strftime(&#039;%d%b%y&#039;)  # &#039;12May11&#039;&lt;br /&gt;
 time.strftime(&#039;%Y.%m.%d %H:%M:%S&#039;)  # &#039;2013.08.09 14:01:28&#039;&lt;br /&gt;
&lt;br /&gt;
Time conversions:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# epoch to str&lt;br /&gt;
epoch_time = time.time()    # 1375992088.7867229&lt;br /&gt;
dt = datetime.datetime.fromtimestamp( epoch_time )    # datetime.datetime(2013, 8, 8, 14, 1, 28, 786723)&lt;br /&gt;
date_str = dt.strftime(&amp;quot;%Y-%m-%d %H:%M:%S&amp;quot;)    # &#039;2013-08-08 14:01:28&#039;&lt;br /&gt;
tz_offset = - time.altzone / 3600&lt;br /&gt;
if tz_offset &amp;lt; 0:&lt;br /&gt;
  tz_offset_str = &amp;quot;-%02d00&amp;quot; % abs(tz_offset)&lt;br /&gt;
else:&lt;br /&gt;
  tz_offset_str = &amp;quot;+%02d00&amp;quot; % abs(tz_offset)&lt;br /&gt;
print date_str + &amp;quot; &amp;quot; + tz_offset_str  # &#039;2013-08-08 14:01:28 -0600&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# UTC epoch to str&lt;br /&gt;
gm_epoch_time = calendar.timegm(time.gmtime())    # 1375992114&lt;br /&gt;
dt = datetime.utcfromtimestamp( gm_epoch_time )    # datetime.datetime(2013, 8, 8, 20, 1, 54)&lt;br /&gt;
dt.strftime(&amp;quot;%Y-%m-%d %H:%M:%S +0000&amp;quot;)    # &#039;2013-08-08 20:01:54 +0000&#039;&lt;br /&gt;
dt.strftime(&amp;quot;%Y-%m-%dT%H:%M:%SZ&amp;quot;)    # &#039;2013-08-08 20:01:54 +0000&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Local time str to epoch&lt;br /&gt;
iso_string=&#039;2013-08-08T14:01:28&#039;&lt;br /&gt;
epoch_time = time.mktime( time.strptime( iso_string, &#039;%Y-%m-%dT%H:%M:%S&#039; ) )    # 1375992088.0&lt;br /&gt;
&lt;br /&gt;
iso_string=&#039;2013-08-08T14:01:28 MDT&#039;&lt;br /&gt;
epoch_time = time.mktime( time.strptime( iso_string, &#039;%Y-%m-%dT%H:%M:%S %Z&#039; ) )    # 1375992088.0&lt;br /&gt;
&lt;br /&gt;
# not sure how to specify numerical time zone and pull it in!&lt;br /&gt;
&lt;br /&gt;
# UTC (Zulu) str to epoch, and back again&lt;br /&gt;
iso_string = &#039;2013-08-08T20:01:54Z&#039;&lt;br /&gt;
epoch_time = calendar.timegm( time.strptime( iso_string.replace(&#039;Z&#039;, &#039;GMT&#039;), &#039;%Y-%m-%dT%H:%M:%S%Z&#039; ) )&lt;br /&gt;
print epoch_time    # 1375992114&lt;br /&gt;
print &amp;quot;%sZ&amp;quot; % datetime.utcfromtimestamp(timestamp).isoformat()  # 2013-08-08T20:01:54Z&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Convert epoch from Local to UTC&lt;br /&gt;
epoch_time = 1375992114&lt;br /&gt;
tz_offset = - time.altzone / 3600&lt;br /&gt;
gm_epoch_time = epoch_time - tz_offset * 3600    # 1376013714&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Convert epoch from UTC to Local&lt;br /&gt;
gm_epoch_time = 1376013714&lt;br /&gt;
tz_offset = - time.altzone / 3600&lt;br /&gt;
epoch_time = gm_epoch_time + tz_offset * 3600    # 1375992114&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
struct_time:&lt;br /&gt;
 time.localtime()  # local zime zone&lt;br /&gt;
 time.gmtime()     # UTC time&lt;br /&gt;
&lt;br /&gt;
 today = time.localtime()&lt;br /&gt;
 today_year = today.tm_year&lt;br /&gt;
 today_month = today.tm_mon&lt;br /&gt;
 today_day = today.tm_mday&lt;br /&gt;
&lt;br /&gt;
 time.strftime(&amp;quot;%a, %d %b %Y %H:%M:%S +0000&amp;quot;, time.gmtime())&lt;br /&gt;
&lt;br /&gt;
Zulu time to epoch time: [http://stackoverflow.com/questions/127803/how-to-parse-iso-formatted-date-in-python]&lt;br /&gt;
 s = &#039;2008-09-03T20:56:35.450686Z&#039;&lt;br /&gt;
 event_time_struct = time.strptime(s.split(&#039;.&#039;)[0]+ &amp;quot;UTC&amp;quot;, &amp;quot;%Y-%m-%dT%H:%M:%S%Z&amp;quot;)&lt;br /&gt;
 epoch_time = calendar.timegm(event_time_struct)&lt;br /&gt;
&lt;br /&gt;
Parse string to time.struct_time (like gmtime()): [http://docs.python.org/2/library/time.html#time.strptime]&lt;br /&gt;
 time.strptime(time.ctime())  # current time - default format is ctime format: &amp;quot;%a %b %d %H:%M:%S %Y&amp;quot;&lt;br /&gt;
 time.strptime(time.ctime(time.time()))  # default format is ctime format: &amp;quot;%a %b %d %H:%M:%S %Y&amp;quot;&lt;br /&gt;
 time.strptime(&amp;quot;30 Nov 00&amp;quot;, &amp;quot;%d %b %y&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Build from ticks: [http://www.tutorialspoint.com/python/python_date_time.htm]&lt;br /&gt;
 localtime = time.localtime( time.time() )  # build time.struct_time from ticks&lt;br /&gt;
 print time.asctime( localtime )  # Tue Jan 13 10:17:09 2009&lt;br /&gt;
&lt;br /&gt;
 dt = datetime.datetime.fromtimestamp( time.time() )  # build datetime.datetime struct from ticks&lt;br /&gt;
 dt.strftime(&amp;quot;%Y-%m-%d  %H:%M:%S&amp;quot;)  # &#039;2013-07-31  23:07:48&#039;&lt;br /&gt;
 time.strptime( time.time(), &amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from datetime import date&lt;br /&gt;
now = date.today()    # now = datetime.date(2003, 12,2)&lt;br /&gt;
now.strftime(&amp;quot;%m-%d-%y&amp;quot;)   # &#039;12-02-03&#039;&lt;br /&gt;
# dates support calendar arthimetic&lt;br /&gt;
birthday = date(1964, 7, 31)&lt;br /&gt;
age = now - birthday&lt;br /&gt;
age.days  # 14368&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 ts = (datetime.datetime.now().strftime(&amp;quot;%Y%m%d%H%M&amp;quot;))         # 201105191118&lt;br /&gt;
 tstxt = (datetime.datetime.now().strftime(&amp;quot;%m-%d-%Y %H:%M&amp;quot;))  # 05-19-2011 11:18&lt;br /&gt;
&lt;br /&gt;
Seconds since epoch:&lt;br /&gt;
 int(time.time())    # 1305842304&lt;br /&gt;
&lt;br /&gt;
Zulu and back again: ([http://aboutsimon.com/2013/06/05/datetime-hell-time-zone-aware-to-unix-timestamp/ Datetime hell])&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import time&lt;br /&gt;
from calendar import timegm&lt;br /&gt;
from datetime import datetime&lt;br /&gt;
 &lt;br /&gt;
if __name__ == &#039;__main__&#039;:&lt;br /&gt;
    iso_string = &#039;2013-06-05T15:19:10Z&#039;&lt;br /&gt;
 &lt;br /&gt;
    timestamp = timegm(&lt;br /&gt;
        time.strptime(&lt;br /&gt;
            iso_string.replace(&#039;Z&#039;, &#039;GMT&#039;),&lt;br /&gt;
            &#039;%Y-%m-%dT%H:%M:%S%Z&#039;&lt;br /&gt;
        )&lt;br /&gt;
    )&lt;br /&gt;
 &lt;br /&gt;
    print iso_string&lt;br /&gt;
    print timestamp&lt;br /&gt;
    print &#039;-&amp;gt; %sZ&#039; % datetime.utcfromtimestamp(timestamp).isoformat()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
http://wiki.python.org/moin/TimeTransitionsImage?action=AttachFile&amp;amp;do=get&amp;amp;target=v1.png  [http://wiki.python.org/moin/WorkingWithTime]&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* WorkingWithTime - PythonInfo Wiki - http://wiki.python.org/moin/WorkingWithTime&lt;br /&gt;
* Datetime hell. Time zone aware to UNIX timestamp. | About me and the things I do - http://aboutsimon.com/2013/06/05/datetime-hell-time-zone-aware-to-unix-timestamp/&lt;br /&gt;
* WorkingWithTime - Python Wiki - http://wiki.python.org/moin/WorkingWithTime&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
Something I cooked up...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def utc_time(self, years_offset=60):&lt;br /&gt;
        mst_epoch_time = time.time()  # server is in MST&lt;br /&gt;
        if time.localtime().tm_isdst: # are we daylight saving time?&lt;br /&gt;
            utc_epoch_time = mst_epoch_time + time.altzone&lt;br /&gt;
        else:&lt;br /&gt;
            utc_epoch_time = mst_epoch_time + time.timezone&lt;br /&gt;
        return utc_epoch_time&lt;br /&gt;
&lt;br /&gt;
    def tz_time(self, tz_offset, daylight_adjust=True):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot; return the future time based on timezone offset&lt;br /&gt;
            @tz_offset is timezone offset, eg -7 for MST&lt;br /&gt;
            @daylight_adjust is flag to auto adjust for daylight time&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        if daylight_adjust:&lt;br /&gt;
            if time.localtime().tm_isdst: # are we daylight saving time?&lt;br /&gt;
                _tz_offset = tz_offset - 1&lt;br /&gt;
            else:&lt;br /&gt;
                _tz_offset = tz_offset&lt;br /&gt;
            _utc_epoch_time = self.utc_time()&lt;br /&gt;
            _adj_time = _utc_epoch_time + _tz_offset * 60 * 60&lt;br /&gt;
            return _adj_time&lt;br /&gt;
&lt;br /&gt;
    def future_time(self, tz_offset=-7, daylight_adjust=True, years_offset=60):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot; Calculate some future year &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        _tz_time = self.tz_time(tz_offset)&lt;br /&gt;
        future_utc_epoch_time = _tz_time + years_offset * 365 * 24 * 60 * 60&lt;br /&gt;
        # account for leap years&lt;br /&gt;
        cur_year = datetime.datetime.now().year&lt;br /&gt;
        cur_year_leap = cur_year / 4&lt;br /&gt;
        future_year = cur_year + years_offset&lt;br /&gt;
        future_year_leap = future_year / 4&lt;br /&gt;
        leap_days = future_year_leap - cur_year_leap&lt;br /&gt;
        future_utc_epoch_time += leap_days * 24 * 60 * 60&lt;br /&gt;
        return future_utc_epoch_time&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Math ===&lt;br /&gt;
&lt;br /&gt;
Math Functions:&lt;br /&gt;
 import math&lt;br /&gt;
 math.ceil(x)&lt;br /&gt;
 math.floor(x)&lt;br /&gt;
 math.trunc(x)&lt;br /&gt;
 math.pow(x,y)&lt;br /&gt;
&lt;br /&gt;
 abs(x)  # built in&lt;br /&gt;
&lt;br /&gt;
=== Random ===&lt;br /&gt;
&lt;br /&gt;
 import random&lt;br /&gt;
 random.choice([&#039;a&#039;, &#039;b&#039;, &#039;c&#039;])&lt;br /&gt;
 random.sample(range(100), 10)&lt;br /&gt;
 random.random()  # random float 0 &amp;lt; x &amp;lt; 1&lt;br /&gt;
 random.randrange(3)     # integer in [0, 1, 2]&lt;br /&gt;
 random.randrange(1, 3)  # integer in [1, 2]&lt;br /&gt;
 random.randint(1, 3)    # integer in [1, 2, 3]&lt;br /&gt;
&lt;br /&gt;
=== Operating System Operations ===&lt;br /&gt;
&lt;br /&gt;
Import OS Library:&lt;br /&gt;
 import os&lt;br /&gt;
&lt;br /&gt;
Common Functions:&lt;br /&gt;
 # directory functions&lt;br /&gt;
 os.getcwd()       # get current directory&lt;br /&gt;
 os.listdir(p)     # get list of directory contents&lt;br /&gt;
 os.chdir(p)       # change directory&lt;br /&gt;
 os.mkdir(p)       # make directory&lt;br /&gt;
 os.makedirs(p)    # make directory and all intermediate&lt;br /&gt;
 os.rmdir(p)       # remove empty directory, see shutil.rmtree()&lt;br /&gt;
 os.removedirs(p)  # remove empty directories, see shutil.rmtree()&lt;br /&gt;
 os.path.exists(p) # does file/directory exist?&lt;br /&gt;
 os.path.isdir(p)  # does directory exist&lt;br /&gt;
 os.path.join(folder1, folder2, file, etc)  # portable path join&lt;br /&gt;
&lt;br /&gt;
 # file functions&lt;br /&gt;
 os.remove(p)      # remove file&lt;br /&gt;
 os.unlink(p)      # same as os.remove()&lt;br /&gt;
 os.path.exists(p) # does file/directory exist?&lt;br /&gt;
 os.path.isfile(p) # does file exist&lt;br /&gt;
 os.stat(fname)    # get file stats&lt;br /&gt;
 os.stat(fname).st_size  # file size&lt;br /&gt;
 os.link(src, dst) # create hard link&lt;br /&gt;
 os.readlink(p)    # read symbolic link&lt;br /&gt;
 os.rename(old, new) # rename/move file or directory&lt;br /&gt;
 os.tempnam(p)     # temporary unique name for target path&lt;br /&gt;
 os.tmpfile()      # create temporary file&lt;br /&gt;
 os.tmpnam()       # temporary file name&lt;br /&gt;
 os.path.getsize(filename)  # get file size&lt;br /&gt;
&lt;br /&gt;
 # system functions&lt;br /&gt;
 os.fork()         # fork process&lt;br /&gt;
 os.getpid()       # get process id&lt;br /&gt;
 os.getppid()      # get parent&#039;s process id&lt;br /&gt;
 os.kill(pid, sig) # kill a process&lt;br /&gt;
 os.getlogin()     # get user&#039;s login name&lt;br /&gt;
&lt;br /&gt;
 # execution&lt;br /&gt;
 os.system(cmd)    # output to stdout, return exit_status&lt;br /&gt;
 os.popen(cmd)     # returns a pipe to command&lt;br /&gt;
&lt;br /&gt;
Note: to get path to script:&lt;br /&gt;
 sys.path[0]&lt;br /&gt;
&lt;br /&gt;
Get directory and file names:&lt;br /&gt;
 os.path.dirname(path)  # &#039;/root/test.txt&#039; -&amp;gt; &#039;/root&#039;&lt;br /&gt;
 os.path.basename(path) # &#039;/root/test.txt&#039; -&amp;gt; &#039;test.txt&#039;&lt;br /&gt;
 os.path.splitext(path) # &#039;/root/test.test.txt&#039; -&amp;gt; (&#039;/root/test.test&#039;, &#039;.txt&#039;) - extract extention&lt;br /&gt;
 filename.split(&amp;quot;.&amp;quot;)[-1] # &#039;/root/test.test.txt&#039; -&amp;gt; &#039;txt&#039; - extract extention&lt;br /&gt;
&lt;br /&gt;
Normalize path, eliminating double slashes, etc.&lt;br /&gt;
 os.path.normpath(path)  # &#039;/root/..&#039; -&amp;gt; &#039;/&#039; or &#039;test/..&#039; -&amp;gt; &#039;.&#039;&lt;br /&gt;
 os.path.abspath(path)   # &#039;/root/..&#039; -&amp;gt; &#039;/&#039; or &#039;test/..&#039; -&amp;gt; &#039;/root/test&#039;&lt;br /&gt;
&lt;br /&gt;
List dir: (returns list)&lt;br /&gt;
 os.listdir( os.getcwd() )&lt;br /&gt;
&lt;br /&gt;
List of files:&lt;br /&gt;
 [p for p in os.listdir(os.getcwd())&lt;br /&gt;
    if os.path.isfile(p)]&lt;br /&gt;
&lt;br /&gt;
List of folders:&lt;br /&gt;
 [p for p in os.listdir(os.getcwd())&lt;br /&gt;
    if os.path.isdir(p)]&lt;br /&gt;
&lt;br /&gt;
Build path for local OS: (using appropriate slash)&lt;br /&gt;
 pathstr = os.path.join(&amp;quot;folder&amp;quot;, &amp;quot;folder&amp;quot;, &amp;quot;file_or_folder&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
File and directory management with shutil&lt;br /&gt;
 import shutil&lt;br /&gt;
 shutil.copyfile(&#039;file1&#039;, &#039;file2&#039;)&lt;br /&gt;
 shutil.move(&#039;file1&#039;, &#039;folder2/file1&#039;)&lt;br /&gt;
&lt;br /&gt;
File Wildcards:&lt;br /&gt;
 import glob&lt;br /&gt;
 glob.glob(&#039;*.py&#039;)  # return list of files&lt;br /&gt;
&lt;br /&gt;
Walk directory tree: [http://stackoverflow.com/questions/120656/directory-listing-in-python]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import os&lt;br /&gt;
for dirname, dirnames, filenames in os.walk(&#039;.&#039;):&lt;br /&gt;
    for subdirname in dirnames:&lt;br /&gt;
        print os.path.join(dirname, subdirname)&lt;br /&gt;
    for filename in filenames:&lt;br /&gt;
        print os.path.join(dirname, filename)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ugly &#039;deltree&#039; (by kenneth)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import os&lt;br /&gt;
def deltree(path):&lt;br /&gt;
    files = os.listdir(path)&lt;br /&gt;
    for file in files:&lt;br /&gt;
        file_path = os.path.join(path, file)&lt;br /&gt;
        if os.path.isdir(file_path):&lt;br /&gt;
            deltree(file_path)&lt;br /&gt;
            os.rmdir(file_path)&lt;br /&gt;
        else:&lt;br /&gt;
            os.remove(file_path)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cleaner &#039;deltree&#039; (by Kep)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import shutil&lt;br /&gt;
# Blow away (if needed), and reclone to proper version&lt;br /&gt;
if os.path.isdir(&amp;quot;xxx&amp;quot;):&lt;br /&gt;
    shutil.rmtree(&amp;quot;xxx&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== System Platform ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import platform&lt;br /&gt;
&lt;br /&gt;
if platform.system() == &amp;quot;Linux&amp;quot;:&lt;br /&gt;
 # ...&lt;br /&gt;
if platform.system() == &amp;quot;Windows&amp;quot;:&lt;br /&gt;
 # ...&lt;br /&gt;
else:&lt;br /&gt;
 # ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Temp Files ===&lt;br /&gt;
&lt;br /&gt;
 import tempfile&lt;br /&gt;
 filename = tempfile.mktemp()&lt;br /&gt;
 f = open(filename, &#039;w&#039;)&lt;br /&gt;
 ...&lt;br /&gt;
 f.close()&lt;br /&gt;
 &lt;br /&gt;
 import os&lt;br /&gt;
 os.remove(filename)  # delete temp file&lt;br /&gt;
&lt;br /&gt;
=== Pickling ===&lt;br /&gt;
&lt;br /&gt;
Pickling (serializing, making objects persistent):&lt;br /&gt;
 import pickle&lt;br /&gt;
 grades = {&#039;bob&#039; : [4, 5, 6],&lt;br /&gt;
           &#039;sue&#039; : [3, None, 7, 7]}&lt;br /&gt;
 outfile = open(fname, &#039;wb&#039;)&lt;br /&gt;
 pickle.dump(grades, outfile)&lt;br /&gt;
&lt;br /&gt;
 infile = open(fname, &#039;rb&#039;)&lt;br /&gt;
 grades = pickle.load(infile)&lt;br /&gt;
&lt;br /&gt;
=== [http://docs.python.org/library/logging.html Logging] ===&lt;br /&gt;
&lt;br /&gt;
* logging — Logging facility for Python — Python 3 documentation - https://docs.python.org/3/library/logging.html&lt;br /&gt;
* Logging HOWTO — Python Dev Version documentation - http://docs.python.org/dev/howto/logging.html&lt;br /&gt;
* Logging Cookbook — Python Dev Version documentation - http://docs.python.org/dev/howto/logging-cookbook.html&lt;br /&gt;
&lt;br /&gt;
Setup logger:&lt;br /&gt;
 import logging&lt;br /&gt;
 logging.basicConfig(level=logging.DEBUG,format=&#039;[%(asctime)s.%(msecs)03d] %(levelname)s %(filename)s(line:%(lineno)d): %(message)s&#039;)&lt;br /&gt;
&lt;br /&gt;
Log Levels:&lt;br /&gt;
 import logging&lt;br /&gt;
 msg = &amp;quot;i broke&amp;quot;&lt;br /&gt;
 logging.debug(msg)&lt;br /&gt;
 logging.info(msg)&lt;br /&gt;
 logging.warning(msg)   # WARNING:root:i broke&lt;br /&gt;
 logging.error(msg)     # ERROR:root:i broke&lt;br /&gt;
 logging.critical(msg)  # CRITICAL:root:i broke&lt;br /&gt;
&lt;br /&gt;
 log.setLevel(level)  # debug, info, warn/warning, error, critical&lt;br /&gt;
 log.setLevel(logging.DEBUG)&lt;br /&gt;
&lt;br /&gt;
A good convention to use when naming loggers is to use a module-level logger, in each module which uses logging, named as follows: [http://docs.python.org/dev/howto/logging.html]&lt;br /&gt;
 logger = logging.getLogger(__name__)&lt;br /&gt;
&lt;br /&gt;
Simple example: [http://stackoverflow.com/questions/345991/python-no-handlers-could-be-found-for-logger-opengl-error]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
log_format=&#039;%(asctime)s | %(levelname)s | %(message)s&#039;&lt;br /&gt;
log_date_format=&#039;%Y-%m-%d %H:%M:%S&#039;&lt;br /&gt;
logging.basicConfig(format=log_format, datefmt=log_date_format)&lt;br /&gt;
log = logging.getLogger(__name__)&lt;br /&gt;
log.setLevel(logging.INFO)&lt;br /&gt;
&lt;br /&gt;
log.info(&#039;hi&#039;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Formatter function:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def makeFormatter(format_str=&amp;quot;&amp;quot;, date_format=&amp;quot;%Y-%m-%d %H:%M:%S&amp;quot;):&lt;br /&gt;
    if not format_str:&lt;br /&gt;
        format_str = &amp;quot;%(asctime)s | %(levelname)s | %(filename)s:%(lineno)d:%(funcName)s | %(message)s&amp;quot;&lt;br /&gt;
    return logging.Formatter(fmt=format_str, datefmt=date_format)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Medium example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Create logger&lt;br /&gt;
log_format=&#039;%(asctime)s | %(levelname)s | %(message)s&#039;&lt;br /&gt;
log_date_format=&#039;%Y-%m-%d %H:%M:%S&#039;&lt;br /&gt;
log_formatter = logging.Formatter(fmt=log_format, datefmt=log_date_format)&lt;br /&gt;
log = logging.getLogger(__name__)&lt;br /&gt;
log.setLevel(logging.DEBUG)&lt;br /&gt;
&lt;br /&gt;
# Log to console&lt;br /&gt;
ch = logging.StreamHandler()&lt;br /&gt;
ch.setLevel(logging.INFO)&lt;br /&gt;
ch.setFormatter(log_formatter)&lt;br /&gt;
log.addHandler(ch)&lt;br /&gt;
&lt;br /&gt;
# Log to file&lt;br /&gt;
fh = logging.FileHandler(&#039;my_logger.log&#039;)&lt;br /&gt;
fh.setLevel(logging.DEBUG)&lt;br /&gt;
fh.setFormatter(log_formatter)&lt;br /&gt;
log.addHandler(fh)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Log all loggers to file - attach to root logger&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import logging&lt;br /&gt;
&lt;br /&gt;
logger = logging.getLogger(__name__)&lt;br /&gt;
&lt;br /&gt;
# Configure Logger&lt;br /&gt;
log_format=&#039;%(asctime)s | %(name)s | %(levelname)s | %(message)s&#039;&lt;br /&gt;
log_date_format=&#039;%Y-%m-%d %H:%M:%S&#039;&lt;br /&gt;
log_formatter = logging.Formatter(fmt=log_format, datefmt=log_date_format)&lt;br /&gt;
logging.basicConfig(level=logging.DEBUG, format=log_format, datefmt=log_date_format)&lt;br /&gt;
&lt;br /&gt;
# Setup Log to File handler, and attach to root logger&lt;br /&gt;
root_logger = logging.getLogger()  # Calling getLogger() without a name returns the root logger&lt;br /&gt;
fh = logging.FileHandler(&#039;logger.txt&#039;)&lt;br /&gt;
fh.setLevel(logging.DEBUG)&lt;br /&gt;
fh.setFormatter(log_formatter)&lt;br /&gt;
root_logger.addHandler(fh)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Application Setup (not basic log configuration carries across imported modules):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import logging&lt;br /&gt;
def main():&lt;br /&gt;
    logging.basicConfig(filename=&#039;myapp.log&#039;, level=logging.INFO)&lt;br /&gt;
    logging.info(&#039;Started&#039;)&lt;br /&gt;
    ...&lt;br /&gt;
    logging.info(&#039;Finished&#039;)&lt;br /&gt;
&lt;br /&gt;
if __name__ == &#039;__main__&#039;:&lt;br /&gt;
    main()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Log multiple lines:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
for line in output.splitlines():&lt;br /&gt;
    log.debug(line)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Set log level:  (warning is default)&lt;br /&gt;
 logging.basicConfig(level=logging.DEBUG)&lt;br /&gt;
&lt;br /&gt;
Set log level from string value: [http://docs.python.org/dev/howto/logging.html]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# assuming loglevel is bound to the string value obtained from the&lt;br /&gt;
# command line argument. Convert to upper case to allow the user to&lt;br /&gt;
# specify --log=DEBUG or --log=debug&lt;br /&gt;
numeric_level = getattr(logging, loglevel.upper(), None)&lt;br /&gt;
if not isinstance(numeric_level, int):&lt;br /&gt;
    raise ValueError(&#039;Invalid log level: %s&#039; % loglevel)&lt;br /&gt;
logging.basicConfig(level=numeric_level, ...)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Log to file:&lt;br /&gt;
 logging.basicConfig(filename=&#039;example.log&#039;,level=logging.DEBUG)&lt;br /&gt;
 logging.basicConfig(filename=&#039;example.log&#039;, filemode=&#039;w&#039;, level=logging.DEBUG)  # do not append&lt;br /&gt;
&lt;br /&gt;
Format output: (once set, can&#039;t be changed?)&lt;br /&gt;
 # WARNING:MESSAGE&lt;br /&gt;
 logging.basicConfig(format=&#039;%(levelname)s:%(message)s&#039;, level=logging.DEBUG)&lt;br /&gt;
&lt;br /&gt;
 # 05/23/2011 12:50:02 PM MESSAGE&lt;br /&gt;
 logging.basicConfig(format=&#039;%(asctime)s %(message)s&#039;, datefmt=&#039;%m/%d/%Y %I:%M:%S %p&#039;)&lt;br /&gt;
&lt;br /&gt;
 # 05/23/2011 12:55:28 PM : WARNING : MESSAGE&lt;br /&gt;
 logging.basicConfig(format=&#039;%(asctime)s : %(levelname)s : %(message)s&#039;, datefmt=&#039;%m/%d/%Y %I:%M:%S %p&#039;)&lt;br /&gt;
&lt;br /&gt;
 # 2011-05-23 13:05:30 : WARNING : MESSAGE&lt;br /&gt;
 logging.basicConfig(format=&#039;%(asctime)s : %(levelname)s : %(message)s&#039;, datefmt=&#039;%Y-%m-%d %H:%M:%S&#039;)&lt;br /&gt;
&lt;br /&gt;
 # 2011-05-23 13:05:30 | WARNING | FILE:FUNC | MESSAGE&lt;br /&gt;
 logging.basicConfig(format=&#039;%(asctime)s | %(levelname)s | %(filename)s:%(funcName)s | %(message)s&#039;, datefmt=&#039;%Y-%m-%d %H:%M:%S&#039;)&lt;br /&gt;
&lt;br /&gt;
Log record attributes - http://docs.python.org/library/logging.html#logrecord-attributes&lt;br /&gt;
&lt;br /&gt;
Format Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FORMAT = &#039;%(asctime)-15s %(clientip)s %(user)-8s %(message)s&#039;  # doesn&#039;t work!&lt;br /&gt;
logging.basicConfig(format=FORMAT)&lt;br /&gt;
d = { &#039;clientip&#039; : &#039;192.168.0.1&#039;, &#039;user&#039; : &#039;fbloggs&#039; }&lt;br /&gt;
logger = logging.getLogger(&#039;tcpserver&#039;)&lt;br /&gt;
logger.warning(&#039;Protocol problem: %s&#039;, &#039;connection reset&#039;, extra=d)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import logging&lt;br /&gt;
&lt;br /&gt;
# create logger with &#039;spam_application&#039;&lt;br /&gt;
logger = logging.getLogger(&#039;spam_application&#039;)&lt;br /&gt;
logger.setLevel(logging.DEBUG)&lt;br /&gt;
&lt;br /&gt;
# create file handler which logs even debug messages&lt;br /&gt;
fh = logging.FileHandler(&#039;spam.log&#039;)&lt;br /&gt;
fh.setLevel(logging.DEBUG)&lt;br /&gt;
&lt;br /&gt;
# create console handler with a higher log level&lt;br /&gt;
ch = logging.StreamHandler()&lt;br /&gt;
ch.setLevel(logging.ERROR)&lt;br /&gt;
&lt;br /&gt;
# create formatter and add it to the handlers&lt;br /&gt;
formatter = logging.Formatter(&#039;%(asctime)s - %(name)s - %(levelname)s - %(message)s&#039;)&lt;br /&gt;
fh.setFormatter(formatter)&lt;br /&gt;
ch.setFormatter(formatter)&lt;br /&gt;
&lt;br /&gt;
# add the handlers to the logger&lt;br /&gt;
logger.addHandler(fh)&lt;br /&gt;
logger.addHandler(ch)&lt;br /&gt;
&lt;br /&gt;
logger.info(&#039;Message to loggers and handlers&#039;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Templating ===&lt;br /&gt;
&lt;br /&gt;
 from string import Template&lt;br /&gt;
 t = Template(&#039;${name}&#039;s fav dish is $food&#039;)&lt;br /&gt;
 t.substitute(name = &#039;ken&#039;, food = &#039;beans&#039;) # throws exception if missing one, but can have more&lt;br /&gt;
 t.safe_substitute(name = &#039;ken&#039;)  # will fill in what it can&lt;br /&gt;
&lt;br /&gt;
Change delimiter:&lt;br /&gt;
 class MYT(Template):&lt;br /&gt;
   delimiter = &#039;%&#039;&lt;br /&gt;
 minput = input(&amp;quot;File name format (%d - date, %s - size): &amp;quot;)&lt;br /&gt;
 myt = MYT(minput)&lt;br /&gt;
 myt.substitute(%d=date, %s=size)&lt;br /&gt;
&lt;br /&gt;
=== [http://docs.python.org/library/threading.html Threading] ===&lt;br /&gt;
&lt;br /&gt;
Basic thread: [http://softwareramblings.com/2008/06/running-functions-as-threads-in-python.html]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import thread&lt;br /&gt;
 &lt;br /&gt;
def someFunc():&lt;br /&gt;
    print &amp;quot;someFunc was called&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
thread.start_new_thread(someFunc, ())&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
More complete basic thread:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import thread&lt;br /&gt;
import threading&lt;br /&gt;
import time&lt;br /&gt;
&lt;br /&gt;
def run_thread (threadname, sleeptime):&lt;br /&gt;
 print &amp;quot;Thread start: &amp;quot; + threadname&lt;br /&gt;
 time.sleep(sleeptime)&lt;br /&gt;
 print &amp;quot;Thread end: &amp;quot; + threadname&lt;br /&gt;
 thread.interrupt_main()   # throw keyboard interrupt to kill main program&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
 thread.start_new_thread(run_thread, (&amp;quot;Thread1&amp;quot;, 3))&lt;br /&gt;
 try:&lt;br /&gt;
     while 1:&lt;br /&gt;
         pass&lt;br /&gt;
 except:&lt;br /&gt;
     print &amp;quot;Thread1 exited....&amp;quot; &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Can use a global counter instead of exception to track number of threads:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import thread&lt;br /&gt;
import threading&lt;br /&gt;
import time&lt;br /&gt;
&lt;br /&gt;
threadcount = 3&lt;br /&gt;
&lt;br /&gt;
def run_thread (threadname, sleeptime):&lt;br /&gt;
  global threadcount&lt;br /&gt;
  print &amp;quot;Thread start: &amp;quot; + threadname&lt;br /&gt;
  time.sleep(sleeptime)&lt;br /&gt;
  print &amp;quot;Thread end: &amp;quot; + threadname&lt;br /&gt;
  threadcount -= 1&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
  thread.start_new_thread(run_thread, (&amp;quot;Thread1&amp;quot;, 3))&lt;br /&gt;
  thread.start_new_thread(run_thread, (&amp;quot;Thread2&amp;quot;, 4))&lt;br /&gt;
  thread.start_new_thread(run_thread, (&amp;quot;Thread3&amp;quot;, 2))&lt;br /&gt;
  while 1:&lt;br /&gt;
    if threadcount == 0:&lt;br /&gt;
      break&lt;br /&gt;
    else:&lt;br /&gt;
      pass&lt;br /&gt;
  print &amp;quot;completed&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
Thread object: [http://softwareramblings.com/2008/06/running-functions-as-threads-in-python.html]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import threading&lt;br /&gt;
 &lt;br /&gt;
t1 = threading.Thread(target=someFunc)&lt;br /&gt;
#  with parameters: Thread(target=myfunction, args=(&#039;MyStringHere&#039;,1)).start()&lt;br /&gt;
t1.start()&lt;br /&gt;
t1.join()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Basic threading with parameters:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import threading&lt;br /&gt;
t = threading.Thread(None, someFunc, None, (param1, param2))&lt;br /&gt;
t.start()&lt;br /&gt;
t.join()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
t = threading.Thread(target=client_recv, args=(s, name))&lt;br /&gt;
while True:&lt;br /&gt;
  t.join(timeout=2)&lt;br /&gt;
  if t.isAlive():&lt;br /&gt;
    print &amp;quot;Thread is dead...&amp;quot;&lt;br /&gt;
    break&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Threading as a class: [http://softwareramblings.com/2008/06/running-functions-as-threads-in-python.html]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import threading&lt;br /&gt;
 &lt;br /&gt;
class FuncThread(threading.Thread):&lt;br /&gt;
    def __init__(self, target, *args):&lt;br /&gt;
        self._target = target&lt;br /&gt;
        self._args = args&lt;br /&gt;
        threading.Thread.__init__(self)&lt;br /&gt;
 &lt;br /&gt;
    def run(self):&lt;br /&gt;
        self._target(*self._args)&lt;br /&gt;
 &lt;br /&gt;
# Example usage&lt;br /&gt;
def someOtherFunc(data, key):&lt;br /&gt;
    print &amp;quot;someOtherFunc was called : data=%s; key=%s&amp;quot; % (str(data), str(key))&lt;br /&gt;
 &lt;br /&gt;
t1 = FuncThread(someOtherFunc, [1,2], 6)&lt;br /&gt;
t1.start()&lt;br /&gt;
t1.join()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Threading as a class #2:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import threading&lt;br /&gt;
import time&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
class MyT(threading.Thread):&lt;br /&gt;
  def __init__(self, name, time):&lt;br /&gt;
    threading.Thread.__init__(self)&lt;br /&gt;
    self.name = name&lt;br /&gt;
    self.time = time&lt;br /&gt;
  def run(self):&lt;br /&gt;
    print(&amp;quot;Thread Start: &amp;quot; + self.name)&lt;br /&gt;
    for i in range(self.time):&lt;br /&gt;
      print(&amp;quot;[&amp;quot; + self.name + &amp;quot;]&amp;quot;, end=&#039;&#039;)&lt;br /&gt;
      sys.stdout.flush()&lt;br /&gt;
      time.sleep(1)&lt;br /&gt;
    print(&amp;quot;Thread Stop: &amp;quot; + self.name)&lt;br /&gt;
&lt;br /&gt;
myt1 = MyT(&#039;1&#039;, 10)&lt;br /&gt;
myt1.start()&lt;br /&gt;
&lt;br /&gt;
myt2 = MyT(&#039;2&#039;, 15)&lt;br /&gt;
myt2.start()&lt;br /&gt;
&lt;br /&gt;
myt3 = MyT(&#039;3&#039;, 5)&lt;br /&gt;
myt3.start()&lt;br /&gt;
&lt;br /&gt;
myt4 = MyT(&#039;4&#039;, 10)&lt;br /&gt;
myt4.start()&lt;br /&gt;
&lt;br /&gt;
myt1.join()&lt;br /&gt;
myt2.join()&lt;br /&gt;
myt3.join()&lt;br /&gt;
myt4.join()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Locking:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
lock=thread.allocate_lock()&lt;br /&gt;
&lt;br /&gt;
# pass lock to thread, and use in thread as such:&lt;br /&gt;
lock.acquire()&lt;br /&gt;
#some operation&lt;br /&gt;
lock.release()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Returning data from a thread (using a [http://docs.python.org/library/queue.html queue]): [http://stackoverflow.com/questions/1886090/return-value-from-thread] [http://stackoverflow.com/questions/2829329/catch-a-threads-exception-in-the-caller-thread-in-python]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Pass exception back to parent&lt;br /&gt;
import sys&lt;br /&gt;
import threading&lt;br /&gt;
import Queue&lt;br /&gt;
&lt;br /&gt;
class ExcThread(threading.Thread):&lt;br /&gt;
    def __init__(self, bucket):&lt;br /&gt;
        threading.Thread.__init__(self)&lt;br /&gt;
        self.bucket = bucket&lt;br /&gt;
    def run(self):&lt;br /&gt;
        try:&lt;br /&gt;
            raise Exception(&#039;An error occured here.&#039;)&lt;br /&gt;
        except Exception:&lt;br /&gt;
            self.bucket.put(sys.exc_info())&lt;br /&gt;
&lt;br /&gt;
def main():&lt;br /&gt;
    bucket = Queue.Queue()&lt;br /&gt;
    thread_obj = ExcThread(bucket)&lt;br /&gt;
    thread_obj.start()&lt;br /&gt;
    while True:&lt;br /&gt;
        try:&lt;br /&gt;
            exc = bucket.get(block=False)&lt;br /&gt;
        except Queue.Empty:&lt;br /&gt;
            pass&lt;br /&gt;
        else:&lt;br /&gt;
            exc_type, exc_obj, exc_trace = exc&lt;br /&gt;
            # deal with the exception&lt;br /&gt;
            print &amp;quot;Exception Caught:&amp;quot;, exc_type, exc_obj&lt;br /&gt;
            print &amp;quot;Exception Trace:&amp;quot;, exc_trace&lt;br /&gt;
        thread_obj.join(0.1)&lt;br /&gt;
        if thread_obj.isAlive():&lt;br /&gt;
            continue&lt;br /&gt;
        else:&lt;br /&gt;
            break&lt;br /&gt;
&lt;br /&gt;
if __name__ == &#039;__main__&#039;:&lt;br /&gt;
    main()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Exception Caught: &amp;lt;type &#039;exceptions.Exception&#039;&amp;gt; An error occured here.&lt;br /&gt;
Exception Trace: &amp;lt;traceback object at 0x2b2230a285f0&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Another Exception catching queue example: (kenneth&#039;s example)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# thread function&lt;br /&gt;
def run_thread(queue, item):&lt;br /&gt;
  ...&lt;br /&gt;
  queue.put( Exception(&amp;quot;Failure on item:&amp;quot; + item) )&lt;br /&gt;
&lt;br /&gt;
threads = []&lt;br /&gt;
queue = Queue.Queue()&lt;br /&gt;
&lt;br /&gt;
# start threads&lt;br /&gt;
for item in items:&lt;br /&gt;
  t = Thread(None, run_thread, None, (queue, item))&lt;br /&gt;
  t.start()&lt;br /&gt;
  threads.append(t)&lt;br /&gt;
&lt;br /&gt;
# wait for threads&lt;br /&gt;
for t in threads:&lt;br /&gt;
  t.join()&lt;br /&gt;
&lt;br /&gt;
# catch and reraise exceptions&lt;br /&gt;
while not queue.empty():&lt;br /&gt;
  raise(queue.get())&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Returning data from a thread (using a callback function): [http://stackoverflow.com/questions/1886090/return-value-from-thread]&lt;br /&gt;
:&amp;quot;Another approach is to pass a callback function to the thread. This gives a simple, safe and flexible way to return a value to the parent, anytime from the new thread.&amp;quot;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import threading&lt;br /&gt;
import time&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
class MyThread(threading.Thread):&lt;br /&gt;
    def __init__(self, cb):&lt;br /&gt;
        threading.Thread.__init__(self)&lt;br /&gt;
        self.callback = cb&lt;br /&gt;
    def run(self):&lt;br /&gt;
        for i in range(10):&lt;br /&gt;
            self.callback(i)&lt;br /&gt;
            time.sleep(1)&lt;br /&gt;
&lt;br /&gt;
def count(x):&lt;br /&gt;
    print x&lt;br /&gt;
    sys.stdout.flush()&lt;br /&gt;
&lt;br /&gt;
t = MyThread(count)&lt;br /&gt;
t.start()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* 16.2. threading — Higher-level threading interface — Python v2.7.1 documentation - http://docs.python.org/library/threading.html&lt;br /&gt;
* An Introduction to Thread Programming - http://www.prasannatech.net/2008/08/introduction-to-thread-programming.html&lt;br /&gt;
* Python - Multithreaded Programming - http://www.tutorialspoint.com/python/python_multithreading.htm&lt;br /&gt;
* Running Functions as Threads in Python « Software Ramblings - http://softwareramblings.com/2008/06/running-functions-as-threads-in-python.html&lt;br /&gt;
* Understanding Threading in Python LG #107 - http://linuxgazette.net/107/pai.html&lt;br /&gt;
* multithreading - Simple threading in Python 2.6 using thread.start_new_thread() - Stack Overflow - http://stackoverflow.com/questions/849674/simple-threading-in-python-2-6-using-thread-start-new-thread&lt;br /&gt;
* python - Return value from thread - Stack Overflow - http://stackoverflow.com/questions/1886090/return-value-from-thread&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
Interrupt main thread:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# source: http://stackoverflow.com/questions/4591917/python-how-to-quit-cli-when-stuck-in-blocking-raw-input&lt;br /&gt;
&lt;br /&gt;
import thread&lt;br /&gt;
import time&lt;br /&gt;
&lt;br /&gt;
def main():&lt;br /&gt;
    try:&lt;br /&gt;
        m = thread.start_new_thread(killable_input, tuple())&lt;br /&gt;
        while 1:&lt;br /&gt;
            time.sleep(0.1) &lt;br /&gt;
    except KeyboardInterrupt:&lt;br /&gt;
        print &amp;quot;exception&amp;quot; &lt;br /&gt;
&lt;br /&gt;
def killable_input():&lt;br /&gt;
    w = thread.start_new_thread(normal_input, tuple())&lt;br /&gt;
    i = thread.start_new_thread(wait_sometime, tuple())&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def normal_input():&lt;br /&gt;
    s = raw_input(&amp;quot;input:&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def wait_sometime():&lt;br /&gt;
    time.sleep(4) # or any other condition to kill the thread&lt;br /&gt;
    print &amp;quot;too slow, killing imput&amp;quot;&lt;br /&gt;
    thread.interrupt_main()&lt;br /&gt;
&lt;br /&gt;
if __name__ == &#039;__main__&#039;:&lt;br /&gt;
    main()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== urllib ===&lt;br /&gt;
&lt;br /&gt;
See [[Python/urllib]]&lt;br /&gt;
&lt;br /&gt;
=== Command line arguments ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import sys&lt;br /&gt;
for x in sys.argv:&lt;br /&gt;
    print x&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Execute other python script ===&lt;br /&gt;
&lt;br /&gt;
 import sys&lt;br /&gt;
 sys.argv = [&#039;&#039;, &#039;my&#039;, &#039;args&#039;, &#039;here&#039;]&lt;br /&gt;
 execfile(&#039;myscript.py&#039;)  # does not support arguments directly&lt;br /&gt;
&lt;br /&gt;
=== Exit Code ===&lt;br /&gt;
&lt;br /&gt;
sys.exit(n) http://docs.python.org/library/sys.html:&lt;br /&gt;
 import sys&lt;br /&gt;
 sys.exit(1)  # exit code of 1 (default is 0)&lt;br /&gt;
 sys.exit(&amp;quot;some error&amp;quot;)  # exit code of 1, and message displayed&lt;br /&gt;
&lt;br /&gt;
=== [http://docs.python.org/library/syslog.html syslog] ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import syslog&lt;br /&gt;
syslog.openlog(&#039;[WATER]&#039;)&lt;br /&gt;
syslog.syslog(&#039;Processing started&#039;)&lt;br /&gt;
if error:&lt;br /&gt;
    syslog.syslog(syslog.LOG_ERR, &#039;Processing started&#039;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import syslog&lt;br /&gt;
syslog.openlog(&#039;[WATER]&#039;)&lt;br /&gt;
def log(msg):&lt;br /&gt;
    syslog.syslog(str(msg))&lt;br /&gt;
log(&amp;quot;Starting...&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Subprocess ===&lt;br /&gt;
&lt;br /&gt;
Subprocess - http://docs.python.org/library/subprocess.html&lt;br /&gt;
&lt;br /&gt;
Methods of subprocess (or external command execution):&lt;br /&gt;
* subprocess (only method to rule/replace all others)&lt;br /&gt;
* os.system&lt;br /&gt;
* os.spawn*&lt;br /&gt;
* os.popen*&lt;br /&gt;
* popen2.*&lt;br /&gt;
* commands.*&lt;br /&gt;
&lt;br /&gt;
My New Favorite:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import subprocess&lt;br /&gt;
class Run(object):&lt;br /&gt;
    class RC(int):&lt;br /&gt;
        pass&lt;br /&gt;
    def __new__(cls, cmd, *args, **kwargs):&lt;br /&gt;
        p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)&lt;br /&gt;
        rc = cls.RC(p.wait())&lt;br /&gt;
        rc.output = &amp;quot;\n&amp;quot;.join(p.stdout.readlines())&lt;br /&gt;
        rc.error = &amp;quot;\n&amp;quot;.join(p.stderr.readlines())&lt;br /&gt;
        return rc&lt;br /&gt;
&lt;br /&gt;
if Run(&amp;quot;some command&amp;quot;): print &amp;quot;do something&amp;quot;  # on rc of not 0 (negative or positive)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
My Favorite:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def exe(cmd):&lt;br /&gt;
    p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)&lt;br /&gt;
    #output = &amp;quot; | &amp;quot;.join(p.stdout.readlines())&lt;br /&gt;
    output = &amp;quot;\n&amp;quot;.join(p.stdout.readlines())&lt;br /&gt;
    rc = p.wait()&lt;br /&gt;
    return (rc, output)&lt;br /&gt;
&lt;br /&gt;
def exe_checked(cmd, checked=True):&lt;br /&gt;
    p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)&lt;br /&gt;
    #output = &amp;quot; | &amp;quot;.join(p.stdout.readlines())&lt;br /&gt;
    output = &amp;quot;\n&amp;quot;.join(p.stdout.readlines())&lt;br /&gt;
    rc = p.wait()&lt;br /&gt;
    if rc and checked:&lt;br /&gt;
        raise Exception(&amp;quot;Command returned non zero [{0}]: {1}&amp;quot;.format(rc, cmd)&lt;br /&gt;
    return (rc, output)&lt;br /&gt;
&lt;br /&gt;
def exe_with_stderr(cmd):&lt;br /&gt;
    p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subproc&lt;br /&gt;
ess.PIPE)&lt;br /&gt;
    output = &amp;quot; | &amp;quot;.join(p.stdout.readlines())&lt;br /&gt;
    outputerr = &amp;quot; | &amp;quot;.join(p.stderr.readlines())&lt;br /&gt;
    rc = p.wait()&lt;br /&gt;
    return (rc, output, outputerr)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def exec_program(cmd):&lt;br /&gt;
    s = subprocess.Popen(cmd.split(), stdout=subprocess.PIPE, stderr=subprocess.PIPE)&lt;br /&gt;
    stdout, stderr = s.communicate()&lt;br /&gt;
    result = s.wait()&lt;br /&gt;
    return stdout, stderr, result&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pass along output and return true error code:&lt;br /&gt;
 import subprocess&lt;br /&gt;
 retcode = subprocess.call([&amp;quot;ls&amp;quot;, &amp;quot;-l&amp;quot;])  # true return code, output sent to STDOUT&lt;br /&gt;
&lt;br /&gt;
 retcode = subprocess.call([&amp;quot;foo.sh&amp;quot;,&amp;quot;args&amp;quot;],shell=True)  # Execute in shell, with shell processing&lt;br /&gt;
 retcode = subprocess.call([&#039;C:\\Temp\\a b c\\Notepad.exe&#039;])&lt;br /&gt;
 retcode = subprocess.call([&amp;quot;D:/Python24/Python.exe&amp;quot;, &amp;quot;Skripta.py&amp;quot;, &amp;quot;arg1&amp;quot;, &amp;quot;arg2&amp;quot;])&lt;br /&gt;
&lt;br /&gt;
Note: shell=True is equivalent to: subprocess.Popen([&#039;/bin/sh&#039;, &#039;-c&#039;, args[0], args[1], ...])&lt;br /&gt;
&lt;br /&gt;
Process STDOUT and STDERR and get return code:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
import subprocess&lt;br /&gt;
import string&lt;br /&gt;
&lt;br /&gt;
cmd = &amp;quot;cat /etc/passwd | grep ken&amp;quot;&lt;br /&gt;
p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) # stderr=subprocess.STDOUT to combine&lt;br /&gt;
&lt;br /&gt;
out = string.join(p.stdout.readlines())&lt;br /&gt;
outerr = string.join(p.stderr.readlines())&lt;br /&gt;
retcode = str(p.wait())&lt;br /&gt;
&lt;br /&gt;
print(&amp;quot;STDOUT: &amp;quot; + out)&lt;br /&gt;
print(&amp;quot;STDERR: &amp;quot; + outerr)&lt;br /&gt;
print(&amp;quot;RETCODE: &amp;quot; + retcode)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Above with stderr redirected to stdout (combined):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import subprocess&lt;br /&gt;
p = subprocess.Popen(&#039;ls&#039;, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)&lt;br /&gt;
for line in p.stdout.readlines():&lt;br /&gt;
    print line,&lt;br /&gt;
retval = p.wait()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Replacing shell backtick: [http://docs.python.org/library/subprocess.html]&lt;br /&gt;
 # shell code:&lt;br /&gt;
 # OUTPUT=`mycmd myarg`&lt;br /&gt;
 from subprocess import Popen&lt;br /&gt;
 output = Popen([&amp;quot;mycmd&amp;quot;, &amp;quot;myarg&amp;quot;], stdout=PIPE).communicate()[0]&lt;br /&gt;
&lt;br /&gt;
Replacing shell pipeline  [http://docs.python.org/library/subprocess.html]&lt;br /&gt;
 # shell code:&lt;br /&gt;
 # OUTPUT=`dmesg | grep hda`&lt;br /&gt;
 from subprocess import Popen&lt;br /&gt;
 p1 = Popen([&amp;quot;dmesg&amp;quot;], stdout=PIPE)&lt;br /&gt;
 p2 = Popen([&amp;quot;grep&amp;quot;, &amp;quot;hda&amp;quot;], stdin=p1.stdout, stdout=PIPE)&lt;br /&gt;
 p1.stdout.close()  # Allow p1 to receive a SIGPIPE if p2 exits.&lt;br /&gt;
 output = p2.communicate()[0]&lt;br /&gt;
&lt;br /&gt;
Replacing os.system(): [http://docs.python.org/library/subprocess.html]&lt;br /&gt;
 # old:&lt;br /&gt;
 sts = os.system(&amp;quot;mycmd&amp;quot; + &amp;quot; myarg&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
 # new:&lt;br /&gt;
 p = Popen(&amp;quot;mycmd&amp;quot; + &amp;quot; myarg&amp;quot;, shell=True)&lt;br /&gt;
 sts = os.waitpid(p.pid, 0)[1]&lt;br /&gt;
&lt;br /&gt;
Control an executed process:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cmd = &amp;quot;/usr/bin/java -Xms256M -Xmx1024M -jar minecraft_server.jar nogui&amp;quot;&lt;br /&gt;
&lt;br /&gt;
p = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE,&lt;br /&gt;
        stdout=subprocess.PIPE, stderr=subprocess.STDOUT)&lt;br /&gt;
&lt;br /&gt;
# cycle while process continues alive&lt;br /&gt;
while p.poll() == None:&lt;br /&gt;
&lt;br /&gt;
  # check if input&lt;br /&gt;
  if select.select([p.stdout.fileno()], [], [], 1)[0]:&lt;br /&gt;
    while select.select([p.stdout.fileno()], [], [], .1)[0]:&lt;br /&gt;
        line = p.stdout.readline()&lt;br /&gt;
        # ... process&lt;br /&gt;
&lt;br /&gt;
  # write something to process&lt;br /&gt;
  p.stdin.write(&amp;quot;tp %s %s\n&amp;quot; % (user1, user2))&lt;br /&gt;
&lt;br /&gt;
  ...&lt;br /&gt;
&lt;br /&gt;
  # time to force a quit: (choose which you need)&lt;br /&gt;
  p.kill()  # SIGKILL&lt;br /&gt;
  p.terminate()  # SIGTERM&lt;br /&gt;
  os.kill(p.pid, signal.SIGTERM)  # same as first, but not as clean&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Other Command Execution ====&lt;br /&gt;
&lt;br /&gt;
Old method with os.system(): [http://docs.python.org/library/os.html]&lt;br /&gt;
 import os&lt;br /&gt;
 encoded_wait_code = os.system(&amp;quot;some command&amp;quot;)  # output sent to STDOUT&lt;br /&gt;
 # Note: returns code of 0 if command returns 0, but wait() encoded value for all other values&lt;br /&gt;
&lt;br /&gt;
Quick and dirty old method (prints stderr, captures stdout)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import os&lt;br /&gt;
out = string.join( os.popen(cmd).readlines() )&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Quick and dirty old method (prints stderr, captures stdout, captures ugly wait() encoded return code)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import os&lt;br /&gt;
p = os.popen(cmd)&lt;br /&gt;
stdout = &amp;quot;&amp;quot;.join( p.readlines() )&lt;br /&gt;
encoded_wait_code = p.close()  # None if 0&lt;br /&gt;
rcode = os.WEXITSTATUS(ugly_rcode) # fix ugly wait() encoded rcode&lt;br /&gt;
print(stdout)&lt;br /&gt;
print(rcode)&lt;br /&gt;
&lt;br /&gt;
if os.popen(cmd).close():&lt;br /&gt;
  print &amp;quot;error with cmd: %s&amp;quot; % cmd&lt;br /&gt;
  sys.exit(1)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
???:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
os.spawnvp(os.P_WAIT,&amp;quot;/usr/bin/mplayer&amp;quot;,[&amp;quot;&amp;quot;,&amp;quot;-ao&amp;quot;,&amp;quot;pcm&amp;quot;,file])&lt;br /&gt;
# or &lt;br /&gt;
os.spawnvp(os.P_NOWAIT,&amp;quot;/usr/bin/mplayer&amp;quot;,[&amp;quot;&amp;quot;,&amp;quot;-ao&amp;quot;,&amp;quot;pcm&amp;quot;,file])&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Replacing os.system(): [http://docs.python.org/library/subprocess.html]&lt;br /&gt;
 # old:&lt;br /&gt;
 sts = os.system(&amp;quot;mycmd&amp;quot; + &amp;quot; myarg&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
 # new:&lt;br /&gt;
 p = Popen(&amp;quot;mycmd&amp;quot; + &amp;quot; myarg&amp;quot;, shell=True)&lt;br /&gt;
 sts = os.waitpid(p.pid, 0)[1]&lt;br /&gt;
&lt;br /&gt;
More realistic example replacing os.system(): [http://docs.python.org/library/subprocess.html]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
try:&lt;br /&gt;
    retcode = call(&amp;quot;mycmd&amp;quot; + &amp;quot; myarg&amp;quot;, shell=True)&lt;br /&gt;
    if retcode &amp;lt; 0:&lt;br /&gt;
        print &amp;gt;&amp;gt;sys.stderr, &amp;quot;Child was terminated by signal&amp;quot;, -retcode&lt;br /&gt;
    else:&lt;br /&gt;
        print &amp;gt;&amp;gt;sys.stderr, &amp;quot;Child returned&amp;quot;, retcode&lt;br /&gt;
except OSError, e:&lt;br /&gt;
    print &amp;gt;&amp;gt;sys.stderr, &amp;quot;Execution failed:&amp;quot;, e&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== select ====&lt;br /&gt;
&lt;br /&gt;
Select:&lt;br /&gt;
&lt;br /&gt;
select.select(rlist, wlist, xlist[, timeout])&lt;br /&gt;
: This is a straightforward interface to the Unix select() system call. The first three arguments are sequences of ‘waitable objects’: either integers representing file descriptors or objects with a parameterless method named fileno() returning such an integer&lt;br /&gt;
: The optional timeout argument specifies a time-out as a floating point number in seconds. When the timeout argument is omitted the function blocks until at least one file descriptor is ready. A time-out value of zero specifies a poll and never blocks.&lt;br /&gt;
&lt;br /&gt;
 if select.select([sys.stdin.fileno()], [], [], .1)[0]:&lt;br /&gt;
     line = p.stdout.readline()&lt;br /&gt;
&lt;br /&gt;
==== full wrapped execution ====&lt;br /&gt;
&lt;br /&gt;
Process timeout (by Kenneth):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import subprocess&lt;br /&gt;
import time&lt;br /&gt;
import os&lt;br /&gt;
import signal&lt;br /&gt;
&lt;br /&gt;
def cmd(cmd, timeout=300, retry=0):&lt;br /&gt;
    # Execute command, time progress, and kill on timeout&lt;br /&gt;
&lt;br /&gt;
    # (status, output) = commands.getstatusoutput(cmd)&lt;br /&gt;
    start_time = None&lt;br /&gt;
    status = None&lt;br /&gt;
    output = None&lt;br /&gt;
    for retry_count in range(retry+1):&lt;br /&gt;
        if retry_count &amp;gt; 0:&lt;br /&gt;
            print(&amp;quot;RETRY: &amp;quot; + str(retry_count) + &amp;quot; &amp;quot; + cmd)&lt;br /&gt;
        start_time = time.time()&lt;br /&gt;
        p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE,&lt;br /&gt;
                stderr=subprocess.STDOUT)&lt;br /&gt;
        timeout_fail = False&lt;br /&gt;
        while p.poll() == None:&lt;br /&gt;
            if time.time() - start_time &amp;gt; timeout:&lt;br /&gt;
                # kill process&lt;br /&gt;
                print(&amp;quot;TIMEOUT: &amp;quot; + str(timeout) + &amp;quot;sec - killing (&amp;quot; + str(p.pid) + &amp;quot;) - &amp;quot; + cmd)&lt;br /&gt;
                try:&lt;br /&gt;
                    os.kill(p.pid, signal.SIGTERM)&lt;br /&gt;
                except OSError as e:&lt;br /&gt;
                    print(&amp;quot;Kill exception: &amp;quot; + str(e))&lt;br /&gt;
                timeout_fail = True&lt;br /&gt;
                break&lt;br /&gt;
            #print(&amp;quot;.&amp;quot;)&lt;br /&gt;
            time.sleep(1)&lt;br /&gt;
        status = p.poll()&lt;br /&gt;
        output = p.stdout.read()&lt;br /&gt;
        if timeout_fail == False:&lt;br /&gt;
            break&lt;br /&gt;
    seconds = int(time.time() - start_time)&lt;br /&gt;
    return (status, output, seconds)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
Process input and output wrapper (from minecraft):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import subprocess&lt;br /&gt;
import select&lt;br /&gt;
import re&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
cmd = &amp;quot;/usr/bin/java -Xms256M -Xmx1024M -jar minecraft_server.jar nogui&amp;quot;&lt;br /&gt;
&lt;br /&gt;
p = subprocess.Popen(cmd, shell=True,&lt;br /&gt;
        stdin=subprocess.PIPE,&lt;br /&gt;
        stdout=subprocess.PIPE,&lt;br /&gt;
        stderr=subprocess.STDOUT)&lt;br /&gt;
&lt;br /&gt;
# cycle while process continues alive&lt;br /&gt;
while p.poll() == None:&lt;br /&gt;
&lt;br /&gt;
    if select.select([p.stdout.fileno()], [], [], 1)[0]:&lt;br /&gt;
        while select.select([p.stdout.fileno()], [], [], .1)[0]:&lt;br /&gt;
            line = p.stdout.readline()&lt;br /&gt;
            # &amp;lt;kiloforce&amp;gt; -tp joe&lt;br /&gt;
            match = re.findall(&amp;quot;&amp;lt;(.*)&amp;gt; -tp (.*)&amp;quot;, line)&lt;br /&gt;
            if match:&lt;br /&gt;
                user1 = match[0][0]&lt;br /&gt;
                user2 = match[0][1]&lt;br /&gt;
                print &amp;quot;&amp;gt;&amp;gt; ACTION: Teleporting %s to %s&amp;quot; % (user1, user2)&lt;br /&gt;
                p.stdin.write(&amp;quot;tp %s %s\n&amp;quot; % (user1, user2))&lt;br /&gt;
            if line:&lt;br /&gt;
                print &amp;quot;&amp;gt;&amp;gt; SERVER: %s&amp;quot; % line.strip()&lt;br /&gt;
            else:&lt;br /&gt;
                print &amp;quot;The server died!&amp;quot;&lt;br /&gt;
                sys.exit(1)&lt;br /&gt;
&lt;br /&gt;
    if select.select([sys.stdin.fileno()], [], [], .1)[0]:&lt;br /&gt;
        line = sys.stdin.readline()&lt;br /&gt;
        print &amp;quot;&amp;gt;&amp;gt; CONSOLE: %s&amp;quot; % line.strip()&lt;br /&gt;
        p.stdin.write(&amp;quot;%s&amp;quot; % line)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Command With Timeout ====&lt;br /&gt;
&lt;br /&gt;
python - Using module &#039;subprocess&#039; with timeout - Stack Overflow - http://stackoverflow.com/questions/1191374/using-module-subprocess-with-timeout&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import subprocess, threading&lt;br /&gt;
&lt;br /&gt;
class Command(object):&lt;br /&gt;
    def __init__(self, cmd):&lt;br /&gt;
        self.cmd = cmd&lt;br /&gt;
        self.process = None&lt;br /&gt;
&lt;br /&gt;
    def run(self, timeout):&lt;br /&gt;
        def target():&lt;br /&gt;
            print &#039;Thread started&#039;&lt;br /&gt;
            self.process = subprocess.Popen(self.cmd, shell=True)&lt;br /&gt;
            self.process.communicate()&lt;br /&gt;
            print &#039;Thread finished&#039;&lt;br /&gt;
&lt;br /&gt;
        thread = threading.Thread(target=target)&lt;br /&gt;
        thread.start()&lt;br /&gt;
&lt;br /&gt;
        thread.join(timeout)&lt;br /&gt;
        if thread.is_alive():&lt;br /&gt;
            print &#039;Terminating process&#039;&lt;br /&gt;
            self.process.terminate()&lt;br /&gt;
            thread.join()&lt;br /&gt;
        print self.process.returncode&lt;br /&gt;
&lt;br /&gt;
command = Command(&amp;quot;echo &#039;Process started&#039;; sleep 2; echo &#039;Process finished&#039;&amp;quot;)&lt;br /&gt;
command.run(timeout=3)&lt;br /&gt;
command.run(timeout=1)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
My version:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import subprocess&lt;br /&gt;
import threading&lt;br /&gt;
&lt;br /&gt;
class Command(object):&lt;br /&gt;
    def __init__(self, cmd, capture=False, shell=True):&lt;br /&gt;
        self.cmd = cmd&lt;br /&gt;
        self.process = None&lt;br /&gt;
        self.thread = None&lt;br /&gt;
        self.shell = shell&lt;br /&gt;
        if type(cmd) == list:&lt;br /&gt;
            self.shell = False&lt;br /&gt;
        self.rc = None&lt;br /&gt;
        self.pid = None&lt;br /&gt;
        self.stdout = None&lt;br /&gt;
        self.stderr = None&lt;br /&gt;
        self.capture = capture  # capture stdout?&lt;br /&gt;
&lt;br /&gt;
    def run(self, timeout=None, wait=True):&lt;br /&gt;
        def target():&lt;br /&gt;
            print &#039;&amp;gt;&amp;gt; Thread started (%s)&#039; % self.cmd&lt;br /&gt;
            if self.capture:&lt;br /&gt;
                self.process = subprocess.Popen(self.cmd, shell=self.shell, stdout=subprocess.PIPE, stderr=subprocess.PIPE)&lt;br /&gt;
            else:&lt;br /&gt;
                self.process = subprocess.Popen(self.cmd, shell=self.shell)&lt;br /&gt;
            print &#039;&amp;gt;&amp;gt; Thread PID: %d&#039; % self.process.pid&lt;br /&gt;
            self.pid = self.process.pid&lt;br /&gt;
            self.stdout, self.stderr = self.process.communicate()&lt;br /&gt;
            self.rc = self.process.returncode&lt;br /&gt;
            print &#039;&amp;gt;&amp;gt; Thread finished: %d&#039; % self.rc&lt;br /&gt;
&lt;br /&gt;
        self.thread = threading.Thread(target=target)&lt;br /&gt;
        self.thread.start()&lt;br /&gt;
&lt;br /&gt;
        if wait:&lt;br /&gt;
            self.wait(timeout)&lt;br /&gt;
        return self  # so you can do: c = Command().run()&lt;br /&gt;
&lt;br /&gt;
    def wait(self, timeout=None):&lt;br /&gt;
        print &#039;&amp;gt;&amp;gt; Waiting for thread...&#039;&lt;br /&gt;
        if timeout:&lt;br /&gt;
            self.thread.join(timeout)&lt;br /&gt;
        else:&lt;br /&gt;
            self.thread.join()&lt;br /&gt;
        if self.thread.is_alive():&lt;br /&gt;
            print &#039;&amp;gt;&amp;gt; Terminating process&#039;&lt;br /&gt;
            self.process.terminate()&lt;br /&gt;
            self.rc = self.process.returncode&lt;br /&gt;
            self.thread.join()&lt;br /&gt;
            if self.thread.is_alive():&lt;br /&gt;
                print &#039;&amp;gt;&amp;gt; Failed to terminate&#039;&lt;br /&gt;
        else:&lt;br /&gt;
            print &#039;&amp;gt;&amp;gt; Thread completed&#039;&lt;br /&gt;
        #print self.process.returncode&lt;br /&gt;
&lt;br /&gt;
    def is_alive(self ):&lt;br /&gt;
        return self.thread.is_alive()&lt;br /&gt;
&lt;br /&gt;
command = Command(&#039;do something&#039;).run()&lt;br /&gt;
&lt;br /&gt;
command2 = Command([&#039;do&#039;, &#039;something&#039;, &#039;long&#039;]).run(wait=False)&lt;br /&gt;
command2.wait(timeout=10)&lt;br /&gt;
&lt;br /&gt;
command3 = Command(&#039;want output&#039;, capture=True).run()&lt;br /&gt;
print command3.stdout&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== System call ===&lt;br /&gt;
&lt;br /&gt;
 os.system(&amp;quot;some_command with args&amp;quot;)&lt;br /&gt;
 os.system(&amp;quot;some_command &amp;lt; input_file | another_command &amp;gt; output_file&amp;quot;)&lt;br /&gt;
 stream = os.popen(&amp;quot;some_command with args&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Here&#039;s a summary of the ways to call external programs and the advantages and disadvantages of each:&lt;br /&gt;
&lt;br /&gt;
1.&lt;br /&gt;
: os.system(&amp;quot;some_command with args&amp;quot;) passes the command and arguments to your system&#039;s shell. This is nice because you can actually run multiple commands at once in this manner and set up pipes and input/output redirection. For example,&lt;br /&gt;
: os.system(&amp;quot;some_command &amp;lt; input_file | another_command &amp;gt; output_file&amp;quot;)&lt;br /&gt;
: However, while this is convenient, you have to manually handle the escaping of shell characters such as spaces, etc. On the other hand, this also lets you run commands which are simply shell commands and not actually external programs.&lt;br /&gt;
: http://docs.python.org/lib/os-process.html&lt;br /&gt;
&lt;br /&gt;
2.&lt;br /&gt;
: stream = os.popen(&amp;quot;some_command with args&amp;quot;) will do the same thing as os.system except that it gives you a file-like object that you can use to access standard input/output for that process. There are 3 other variants of popen that all handle the i/o slightly differently. If you pass everything as a string, then your command is passed to the shell; if you pass them as a list then you don&#039;t need to worry about escaping anything.&lt;br /&gt;
: http://docs.python.org/lib/os-newstreams.html&lt;br /&gt;
&lt;br /&gt;
3.&lt;br /&gt;
: The Popen class of the subprocess module. This is intended as a replacement for os.popen but has the downside of being slightly more complicated by virtue of being so comprehensive. For example, you&#039;d say&lt;br /&gt;
: print Popen(&amp;quot;echo Hello World&amp;quot;, stdout=PIPE, shell=True).stdout.read()&lt;br /&gt;
: instead of&lt;br /&gt;
: print os.popen(&amp;quot;echo Hello World&amp;quot;).read()&lt;br /&gt;
: but it is nice to have all of the options there in one unified class instead of 4 different popen functions.&lt;br /&gt;
: http://docs.python.org/lib/node528.html&lt;br /&gt;
&lt;br /&gt;
4.&lt;br /&gt;
: The call function from the subprocess module. This is basically just like the Popen class and takes all of the same arguments, but it simply wait until the command completes and gives you the return code. For example:&lt;br /&gt;
: return_code = call(&amp;quot;echo Hello World&amp;quot;, shell=True)&lt;br /&gt;
: http://docs.python.org/lib/node529.html&lt;br /&gt;
&lt;br /&gt;
5.&lt;br /&gt;
: The os module also has all of the fork/exec/spawn functions that you&#039;d have in a C program, but I don&#039;t recommend using them directly.&lt;br /&gt;
&lt;br /&gt;
: The subprocess module should probably be what you use.&lt;br /&gt;
&lt;br /&gt;
Source: [http://stackoverflow.com/questions/89228/how-to-call-external-command-in-python]&lt;br /&gt;
&lt;br /&gt;
== Advanced Code ==&lt;br /&gt;
&lt;br /&gt;
=== Executing Code from Command Line ===&lt;br /&gt;
&lt;br /&gt;
 python -c [cmd]&lt;br /&gt;
 # -c cmd : program passed in as string (terminates option list)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python -c &amp;quot;import sys;exec(sys.stdin.read())&amp;quot; &amp;lt;&amp;lt; &amp;quot;EOF&amp;quot;&lt;br /&gt;
def test1():&lt;br /&gt;
  print &amp;quot;test1&amp;quot;&lt;br /&gt;
test1()&lt;br /&gt;
print &amp;quot;test&amp;quot;&lt;br /&gt;
EOF&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Integer Return Code Class ===&lt;br /&gt;
&lt;br /&gt;
Python3 version:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class RC(int):&lt;br /&gt;
  def __new__(cls, rc, stdout=&#039;&#039;, stderr=&#039;&#039;):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;We can&#039;t use use __init__ because int is immutable.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    return super(RC, cls).__new__(cls, rc)&lt;br /&gt;
  def __init__(self, rc, stdout=&#039;&#039;, stderr=&#039;&#039;):&lt;br /&gt;
    super().__init__()&lt;br /&gt;
    self.rc = rc  # redundant&lt;br /&gt;
    self.stdout = stdout&lt;br /&gt;
    self.stderr = stderr&lt;br /&gt;
  def __repr__(self):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;Optional string output&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    return &amp;quot;(%s, &#039;%s&#039;, &#039;%s&#039;)&amp;quot; % (self.rc, self.stdout, self.stderr)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Python2 version:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class RC(int):&lt;br /&gt;
  def __new__(cls, rc, stdout=&#039;&#039;, stderr=&#039;&#039;):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;We can&#039;t use use __init__ because int is immutable.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    return super(RC, cls).__new__(cls, rc)&lt;br /&gt;
  def __init__(self, rc, stdout=&#039;&#039;, stderr=&#039;&#039;):&lt;br /&gt;
    super(self.__class__, self).__init__(rc)&lt;br /&gt;
    self.rc = rc  # redundant&lt;br /&gt;
    self.stdout = stdout&lt;br /&gt;
    self.stderr = stderr&lt;br /&gt;
  def __repr__(self):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;Optional string output&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    return &amp;quot;(%s, &#039;%s&#039;, &#039;%s&#039;)&amp;quot; % (self, self.stdout, self.stderr)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
sample:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; rc1 = RC(5)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; rc2 = RC(0, &#039;out&#039;, &#039;err&#039;)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; rc1&lt;br /&gt;
(5, &#039;&#039;, &#039;&#039;)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; rc2&lt;br /&gt;
(5, &#039;out&#039;, &#039;err&#039;)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; rc2.stdout&lt;br /&gt;
&#039;out&#039;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; int(rc1)&lt;br /&gt;
5&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; 0 + rc1&lt;br /&gt;
5&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; if rc1 &amp;lt;= 5:  print &amp;quot;yes&amp;quot;&lt;br /&gt;
...&lt;br /&gt;
yes&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; if rc2:  print &amp;quot;non-zero&amp;quot;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Smart Execute ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class RC(int):&lt;br /&gt;
    def __new__(cls, rc, output=&#039;&#039;):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;We can&#039;t use use __init__ because int is immutable.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        return super(RC, cls).__new__(cls, rc)&lt;br /&gt;
    def __init__(self, rc, output=&#039;&#039;):&lt;br /&gt;
        super().__init__()&lt;br /&gt;
        self.rc = rc  # redundant&lt;br /&gt;
        self.output = output&lt;br /&gt;
    def __repr__(self):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Optional string output&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        return &amp;quot;(%s, &#039;%s&#039;)&amp;quot; % (self.rc, self.output)&lt;br /&gt;
&lt;br /&gt;
def smart_execute(cmd, display=True, checked=False):&lt;br /&gt;
    output = &amp;quot;&amp;quot;&lt;br /&gt;
    process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, bufsize=1, shell=True, encoding=&#039;utf-8&#039;)&lt;br /&gt;
    for c in iter(lambda: process.stdout.read(1), &amp;quot;&amp;quot;):&lt;br /&gt;
        if display:&lt;br /&gt;
            sys.stdout.buffer.write(c.encode(&#039;utf-8&#039;))&lt;br /&gt;
        output += c&lt;br /&gt;
    process.stdout.close()&lt;br /&gt;
    rc = process.wait()&lt;br /&gt;
    if checked and rc:&lt;br /&gt;
        raise subprocess.CalledProcessError(ret, cmd)&lt;br /&gt;
    return RC(rc, output.strip())&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Not smart version:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def execute(cmd, return_output=False):&lt;br /&gt;
    out = &amp;quot;&amp;quot;&lt;br /&gt;
    process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, bufsize=1, shell=True, encoding=&#039;utf-8&#039;)&lt;br /&gt;
    for c in iter(lambda: process.stdout.read(1), &amp;quot;&amp;quot;):&lt;br /&gt;
        sys.stdout.buffer.write(c.encode(&#039;utf-8&#039;))&lt;br /&gt;
        if return_output:&lt;br /&gt;
            out += c&lt;br /&gt;
    process.stdout.close()&lt;br /&gt;
    ret = process.wait()&lt;br /&gt;
    if ret:&lt;br /&gt;
        raise subprocess.CalledProcessError(ret, cmd)&lt;br /&gt;
    if return_output:&lt;br /&gt;
        return out.strip()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== select ===&lt;br /&gt;
&lt;br /&gt;
usage: select.select(rlist, wlist, xlist[, timeout]) [http://docs.python.org/2/library/select.html]&lt;br /&gt;
* rlist: wait until ready for reading&lt;br /&gt;
* wlist: wait until ready for writing&lt;br /&gt;
* xlist: wait for an “exceptional condition” (see the manual page for what your system considers such a condition)&lt;br /&gt;
* The optional timeout argument specifies a time-out as a floating point number in seconds.&lt;br /&gt;
&lt;br /&gt;
 if select.select([p.stdout.fileno()], [], [], 1)[0]:&lt;br /&gt;
&lt;br /&gt;
=== ANSI Color ===&lt;br /&gt;
&lt;br /&gt;
* ANSI escape code - http://en.wikipedia.org/wiki/ANSI_escape_code&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
unicode - Print in terminal with colors using Python? - Stack Overflow - https://stackoverflow.com/questions/287871/print-in-terminal-with-colors-using-python&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class bcolors:&lt;br /&gt;
    HEADER = &#039;\033[95m&#039;&lt;br /&gt;
    OKBLUE = &#039;\033[94m&#039;&lt;br /&gt;
    OKGREEN = &#039;\033[92m&#039;&lt;br /&gt;
    WARNING = &#039;\033[93m&#039;&lt;br /&gt;
    FAIL = &#039;\033[91m&#039;&lt;br /&gt;
    ENDC = &#039;\033[0m&#039;&lt;br /&gt;
    BOLD = &#039;\033[1m&#039;&lt;br /&gt;
    UNDERLINE = &#039;\033[4m&#039;&lt;br /&gt;
&lt;br /&gt;
print bcolors.WARNING + &amp;quot;Warning: No active frommets remain. Continue?&amp;quot; + bcolors.ENDC&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class colors:&lt;br /&gt;
  black = 0&lt;br /&gt;
  red = 1&lt;br /&gt;
  green = 2&lt;br /&gt;
  yellow = 3&lt;br /&gt;
  blue = 4&lt;br /&gt;
  magenta = 5&lt;br /&gt;
  cyan = 6&lt;br /&gt;
  white = 7&lt;br /&gt;
  fg = 30  # foreground add&lt;br /&gt;
  bg = 40  # background add&lt;br /&gt;
  bfg = 90  # bold foreground add&lt;br /&gt;
  bbg = 100  # bold background add&lt;br /&gt;
&lt;br /&gt;
print &#039;\033[%dm red foreground \033[0m&#039; % (colors.red + colors.fg)&lt;br /&gt;
print &#039;\033[%dm bold red foreground \033[0m&#039; % (colors.red + colors.bfg)&lt;br /&gt;
print &#039;\033[%dm blue background \033[0m&#039; % (colors.blue + colors.bg)&lt;br /&gt;
print &#039;\033[%dm bold blue background \033[0m&#039; % (colors.blue + colors.bbg)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
Before you start spouting escape sequences, you should check that stdout is a tty. You can do this with sys.stdout.isatty()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sys.stdout.isatty()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def hilite(string, status, bold):&lt;br /&gt;
    attr = []&lt;br /&gt;
    if status:&lt;br /&gt;
        # green&lt;br /&gt;
        attr.append(&#039;32&#039;)&lt;br /&gt;
    else:&lt;br /&gt;
        # red&lt;br /&gt;
        attr.append(&#039;31&#039;)&lt;br /&gt;
    if bold:&lt;br /&gt;
        attr.append(&#039;1&#039;)&lt;br /&gt;
    return &#039;\x1b[%sm%s\x1b[0m&#039; % (&#039;;&#039;.join(attr), string)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Python | change text color in shell - Stack Overflow - https://stackoverflow.com/questions/2330245/python-change-text-color-in-shell&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
For reference, a small bash script which prints a table of escape sequences: colortable16.sh: ([http://www.frexx.de/xterm-256-notes/ The 256 color mode of xterm], [http://plug.org/pipermail/plug/2008-March/016821.html The 90s called; they want their 256 colors back])&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
&lt;br /&gt;
# prints a color table of 8bg * 8fg * 2 states (regular/bold)&lt;br /&gt;
echo&lt;br /&gt;
echo Table for 16-color terminal escape sequences.&lt;br /&gt;
echo Replace ESC with \\033 in bash.&lt;br /&gt;
echo&lt;br /&gt;
echo &amp;quot;Background | Foreground colors&amp;quot;&lt;br /&gt;
echo &amp;quot;---------------------------------------------------------------------&amp;quot;&lt;br /&gt;
for((bg=40;bg&amp;lt;=47;bg++)); do&lt;br /&gt;
	for((bold=0;bold&amp;lt;=1;bold++)) do&lt;br /&gt;
		echo -en &amp;quot;\033[0m&amp;quot;&amp;quot; ESC[${bg}m   | &amp;quot;&lt;br /&gt;
		for((fg=30;fg&amp;lt;=37;fg++)); do&lt;br /&gt;
			if [ $bold == &amp;quot;0&amp;quot; ]; then&lt;br /&gt;
				echo -en &amp;quot;\033[${bg}m\033[${fg}m [${fg}m  &amp;quot;&lt;br /&gt;
			else&lt;br /&gt;
				echo -en &amp;quot;\033[${bg}m\033[1;${fg}m [1;${fg}m&amp;quot;&lt;br /&gt;
			fi&lt;br /&gt;
		done&lt;br /&gt;
		echo -e &amp;quot;\033[0m&amp;quot;&lt;br /&gt;
	done&lt;br /&gt;
	echo &amp;quot;--------------------------------------------------------------------- &amp;quot;&lt;br /&gt;
done&lt;br /&gt;
&lt;br /&gt;
echo&lt;br /&gt;
echo&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Python version: (modified by me)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
# prints a color table of 8bg * 8fg * 2 states (regular/bold)&lt;br /&gt;
print&lt;br /&gt;
print &amp;quot;Table for 16-color terminal escape sequences.&amp;quot;&lt;br /&gt;
print &amp;quot;Replace ESC with \\033 in bash.&amp;quot;&lt;br /&gt;
print&lt;br /&gt;
print &amp;quot;Background | Foreground colors&amp;quot;&lt;br /&gt;
print &amp;quot;---------------------------------------------------------------------&amp;quot;&lt;br /&gt;
for bg in range(40, 47+1):&lt;br /&gt;
  for bold in range(0, 1+1):&lt;br /&gt;
                sys.stdout.write(&amp;quot;\033[0m&amp;quot;&amp;quot; ESC[{bg}m   | &amp;quot;.format(bg=bg))&lt;br /&gt;
                for fg in range(30, 37+1):&lt;br /&gt;
                        if bold == 0:&lt;br /&gt;
                                sys.stdout.write(&amp;quot;\033[{bg}m\033[{fg}m [{fg}m  &amp;quot;.format(bg=bg, fg=fg))&lt;br /&gt;
                        else:&lt;br /&gt;
                                sys.stdout.write(&amp;quot;\033[{bg}m\033[1;{fg}m [1;{fg}m&amp;quot;.format(bg=bg, fg=fg))&lt;br /&gt;
                sys.stdout.write(&amp;quot;\033[0m\n&amp;quot;)&lt;br /&gt;
  print &amp;quot;--------------------------------------------------------------------- &amp;quot;&lt;br /&gt;
&lt;br /&gt;
print&lt;br /&gt;
print&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Execute External Application ===&lt;br /&gt;
&lt;br /&gt;
Execute program: (and send output to STDOUT)&lt;br /&gt;
 encoded_wait_code = os.system(&#039;mkdir mydir&#039;)  # output sent to STDOUT&lt;br /&gt;
&lt;br /&gt;
Get output and ugly return code: (STDERR goes to STDOUT)&lt;br /&gt;
 p = os.popen(cmd)&lt;br /&gt;
 print p.readlines()&lt;br /&gt;
 encoded_wait_code = p.close()&lt;br /&gt;
&lt;br /&gt;
Execute other python script&lt;br /&gt;
 import sys&lt;br /&gt;
 sys.argv = [, &#039;my&#039;, &#039;args&#039;, &#039;here&#039;]&lt;br /&gt;
 execfile(&#039;myscript.py&#039;)  # does not support arguments directly&lt;br /&gt;
&lt;br /&gt;
Subprocess:&lt;br /&gt;
* See [[#Subprocess]]&lt;br /&gt;
&lt;br /&gt;
=== Program Layout ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
PackageName/&lt;br /&gt;
    README&lt;br /&gt;
    setup.py&lt;br /&gt;
    bin/&lt;br /&gt;
        script&lt;br /&gt;
    docs/&lt;br /&gt;
    test/  # some include in package_name&lt;br /&gt;
    pacakgename/&lt;br /&gt;
        __init__.py&lt;br /&gt;
        code1.py&lt;br /&gt;
        subpackage/&lt;br /&gt;
            __init__.py&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== __init__.py ===&lt;br /&gt;
&lt;br /&gt;
Purpose: Makes the folder into a package library&lt;br /&gt;
&lt;br /&gt;
NOTE: This file is most commonly blank&lt;br /&gt;
&lt;br /&gt;
Good place to put your package functions.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# ken/__init__.py&lt;br /&gt;
def load():&lt;br /&gt;
  ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import ken&lt;br /&gt;
ken.load()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Can import other modules to then use as package modules:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# ken/__init__.py&lt;br /&gt;
from ken.client import Server&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import ken&lt;br /&gt;
ken.Server()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Good place to put your Exceptions.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class MyException(Exception):&lt;br /&gt;
  &amp;quot;&amp;quot;&amp;quot; My Error Exception &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use the __all__ to specify what gets imported on &#039;from package import *&#039;&lt;br /&gt;
  __all__ = [&#039;func1&#039;, &#039;func2&#039;]&lt;br /&gt;
&lt;br /&gt;
=== Metadata ===&lt;br /&gt;
&lt;br /&gt;
 VERSION = (0, 2, 1)&lt;br /&gt;
or&lt;br /&gt;
 __version__ = &#039;0.2.1&#039;&lt;br /&gt;
&lt;br /&gt;
Also See [[#pydoc]]&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
 __version__ = &#039;1.10&#039;&lt;br /&gt;
 __author__ = &#039;Joshua Roesslein&#039;&lt;br /&gt;
 __license__ = &#039;MIT&#039;&lt;br /&gt;
&lt;br /&gt;
=== setup.py ===&lt;br /&gt;
&lt;br /&gt;
See [[#Distributing Python Modules with Distutils]]&lt;br /&gt;
&lt;br /&gt;
=== Distributing Python Modules with Distutils ===&lt;br /&gt;
&lt;br /&gt;
Distributing Python Modules — http://docs.python.org/distutils/index.html&lt;br /&gt;
&lt;br /&gt;
Uses setup.py for package installation.&lt;br /&gt;
 python setup.py install&lt;br /&gt;
&lt;br /&gt;
==== Simple example ====&lt;br /&gt;
&lt;br /&gt;
To install foo.py:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from distutils.core import setup&lt;br /&gt;
setup(name=&#039;foo&#039;,&lt;br /&gt;
      version=&#039;1.0&#039;,&lt;br /&gt;
      py_modules=[&#039;foo&#039;],&lt;br /&gt;
      )&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Source: http://docs.python.org/distutils/introduction.html&lt;br /&gt;
&lt;br /&gt;
==== klib example ====&lt;br /&gt;
&lt;br /&gt;
klib setup.py:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from distutils.core import setup&lt;br /&gt;
&lt;br /&gt;
setup(name = &amp;quot;klib&amp;quot;,&lt;br /&gt;
    version = &amp;quot;101&amp;quot;,&lt;br /&gt;
    description = &amp;quot;klib library&amp;quot;,&lt;br /&gt;
    url = &amp;quot;http://www.oeey.com/klib&amp;quot;,&lt;br /&gt;
    author = &amp;quot;Kenneth&amp;quot;,&lt;br /&gt;
    author_email = &amp;quot;kenneth@oeey.com&amp;quot;,&lt;br /&gt;
    license = &amp;quot;Kenneth License&amp;quot;,&lt;br /&gt;
    long_description = &amp;quot;&amp;quot;&amp;quot;Really long text here.&amp;quot;&amp;quot;&amp;quot;,&lt;br /&gt;
    platforms = &amp;quot;Any Platform&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
    packages = [&#039;klib&#039;,&#039;klib.messenger&#039;],&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Installed to:&lt;br /&gt;
 /opt/python26/lib/python2.6/site-packages/klib/&lt;br /&gt;
 /opt/python26/lib/python2.6/site-packages/klib-100-py2.6.egg-info&lt;br /&gt;
&lt;br /&gt;
Metadata: (/opt/python26/lib/python2.6/site-packages/klib-101-py2.6.egg-info)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Metadata-Version: 1.0&lt;br /&gt;
Name: klib&lt;br /&gt;
Version: 101&lt;br /&gt;
Summary: klib library&lt;br /&gt;
Home-page: http://www.oeey.com/klib&lt;br /&gt;
Author: Kenneth&lt;br /&gt;
Author-email: kenneth@oeey.com&lt;br /&gt;
License: Kenneth License&lt;br /&gt;
Description: Really long text here.&lt;br /&gt;
Platform: Any platform&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Any fields not included will be marked:&lt;br /&gt;
 Platform: UNKNOWN&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* 2. Writing the Setup Script — Python v2.7.2 documentation - http://docs.python.org/distutils/setupscript.html&lt;br /&gt;
* http://wiki.python.org/moin/Distutils/Tutorial&lt;br /&gt;
&lt;br /&gt;
==== Uninstall Package ====&lt;br /&gt;
&lt;br /&gt;
Collect files during install:&lt;br /&gt;
 python setup.py install --record install-record.txt&lt;br /&gt;
 sudo rm $(cat install-record.txt)&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* installation - python setup.py uninstall - Stack Overflow - http://stackoverflow.com/questions/1550226/python-setup-py-uninstall&lt;br /&gt;
&lt;br /&gt;
=== Distributing Python Modules with Setuptools ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
import setuptools&lt;br /&gt;
&lt;br /&gt;
setuptools.setup(name=&amp;quot;tweepy&amp;quot;,&lt;br /&gt;
      version=&amp;quot;1.10&amp;quot;,&lt;br /&gt;
      description=&amp;quot;Twitter library for python&amp;quot;,&lt;br /&gt;
      license=&amp;quot;MIT&amp;quot;,&lt;br /&gt;
      author=&amp;quot;Joshua Roesslein&amp;quot;,&lt;br /&gt;
      author_email=&amp;quot;tweepy@googlegroups.com&amp;quot;,&lt;br /&gt;
      url=&amp;quot;http://github.com/tweepy/tweepy&amp;quot;,&lt;br /&gt;
      packages = setuptools.find_packages(),&lt;br /&gt;
      keywords= &amp;quot;twitter library&amp;quot;,&lt;br /&gt;
      zip_safe = True)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Decorators ===&lt;br /&gt;
&lt;br /&gt;
Decorators wrap functions&lt;br /&gt;
&lt;br /&gt;
Function Counter: [http://stackoverflow.com/questions/739654/understanding-python-decorators]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def fcount(func):&lt;br /&gt;
    def wrapper(*args, **kw):&lt;br /&gt;
        wrapper.count = wrapper.count + 1&lt;br /&gt;
        return func(*args, **kw)&lt;br /&gt;
    wrapper.count = 0&lt;br /&gt;
    return wrapper&lt;br /&gt;
&lt;br /&gt;
@fcount&lt;br /&gt;
def f(n):&lt;br /&gt;
    return n*n&lt;br /&gt;
&lt;br /&gt;
print &amp;quot;f.count = &amp;quot;, f.count&lt;br /&gt;
print &amp;quot;f(10) = &amp;quot;, f(10)&lt;br /&gt;
print &amp;quot;f.count = &amp;quot;, f.count&lt;br /&gt;
print &amp;quot;f(3) = &amp;quot;, f(3)&lt;br /&gt;
print &amp;quot;f.count = &amp;quot;, f.count&lt;br /&gt;
print &amp;quot;f(12) = &amp;quot;, f(12)&lt;br /&gt;
print &amp;quot;f.count = &amp;quot;, f.count&lt;br /&gt;
print &amp;quot;f(15) = &amp;quot;, f(15)&lt;br /&gt;
print &amp;quot;f.count = &amp;quot;, f.count&lt;br /&gt;
&lt;br /&gt;
# Output:&lt;br /&gt;
# f.count =  0&lt;br /&gt;
# f(10) =  100&lt;br /&gt;
# f.count =  1&lt;br /&gt;
# f(3) =  9&lt;br /&gt;
# f.count =  2&lt;br /&gt;
# f(12) =  144&lt;br /&gt;
# f.count =  3&lt;br /&gt;
# f(15) =  225&lt;br /&gt;
# f.count =  4&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Great reference: Understanding Python decorators - Stack Overflow - http://stackoverflow.com/questions/739654/understanding-python-decorators&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Example 1:&lt;br /&gt;
 @dec1&lt;br /&gt;
 def func(arg1, arg2, ...): pass&lt;br /&gt;
&lt;br /&gt;
 # equivalent to:&lt;br /&gt;
 def func(arg1, arg2, ...): pass&lt;br /&gt;
 func = dec1(func)&lt;br /&gt;
&lt;br /&gt;
Example 2:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
@dec2&lt;br /&gt;
@dec1&lt;br /&gt;
def func(arg1, arg2, ...):&lt;br /&gt;
    pass&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# equivalent to:&lt;br /&gt;
def func(arg1, arg2, ...):&lt;br /&gt;
    pass&lt;br /&gt;
func = dec2(dec1(func))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example 3:&lt;br /&gt;
 @decomaker(argA, argB, ...)&lt;br /&gt;
 def func(arg1, arg2, ...):&lt;br /&gt;
     pass&lt;br /&gt;
&lt;br /&gt;
 # equivalent to:&lt;br /&gt;
 func = decomaker(argA, argB, ...)(func)&lt;br /&gt;
&lt;br /&gt;
 # example:&lt;br /&gt;
 @accepts(int,int)&lt;br /&gt;
 @returns(float)&lt;br /&gt;
 def bar(low,high):&lt;br /&gt;
     pass&lt;br /&gt;
&lt;br /&gt;
Example 4: (overrides and ignores passed in function - bad, unless desired)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def spamrun(fn):&lt;br /&gt;
    def sayspam(*args):&lt;br /&gt;
        print &amp;quot;spam, spam, spam&amp;quot;&lt;br /&gt;
    return sayspam&lt;br /&gt;
&lt;br /&gt;
@spamrun&lt;br /&gt;
def useful(a, b):&lt;br /&gt;
    print a**2 + b**2&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example 5: (Decorator that modifies behavior of undecorated func)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def addspam(fn):&lt;br /&gt;
    def new(*args):&lt;br /&gt;
        print &amp;quot;spam, spam, spam&amp;quot;&lt;br /&gt;
        return fn(*args)&lt;br /&gt;
    return new&lt;br /&gt;
&lt;br /&gt;
@addspam&lt;br /&gt;
def useful(a, b):&lt;br /&gt;
    print a**2 + b**2&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
My Example 1: (print args and continue to function)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def showargs(fn):&lt;br /&gt;
    def doshowargs(*args, **kw):&lt;br /&gt;
        print &amp;quot;Args for:&amp;quot;, fn.__name__, args, kw&lt;br /&gt;
        return fn(*args, **kw)&lt;br /&gt;
    return doshowargs&lt;br /&gt;
&lt;br /&gt;
@showargs&lt;br /&gt;
def useful(a, b):&lt;br /&gt;
    print a**2 + b**2&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Another Example: [http://stackoverflow.com/questions/739654/understanding-python-decorators]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def makebold(fn):&lt;br /&gt;
    def wrapped(*args, **kw):&lt;br /&gt;
        return &amp;quot;&amp;lt;b&amp;gt;&amp;quot; + fn(*args, **kw) + &amp;quot;&amp;lt;/b&amp;gt;&amp;quot;&lt;br /&gt;
    return wrapped&lt;br /&gt;
&lt;br /&gt;
def makeitalic(fn):&lt;br /&gt;
    def wrapped(*args, **kw):&lt;br /&gt;
        return &amp;quot;&amp;lt;i&amp;gt;&amp;quot; + fn(*args, **kw) + &amp;quot;&amp;lt;/i&amp;gt;&amp;quot;&lt;br /&gt;
    return wrapped&lt;br /&gt;
&lt;br /&gt;
@makebold&lt;br /&gt;
@makeitalic&lt;br /&gt;
def hello(msg):&lt;br /&gt;
    return msg&lt;br /&gt;
&lt;br /&gt;
print hello(&amp;quot;hello world&amp;quot;)&lt;br /&gt;
# output: &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;hello world&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* PEP 318 -- Decorators for Functions and Methods - http://www.python.org/dev/peps/pep-0318/&lt;br /&gt;
* Charming Python: Decorators make magic easy - http://www.ibm.com/developerworks/linux/library/l-cpdecor/index.html&lt;br /&gt;
* What are some common uses for Python decorators? - Stack Overflow - http://stackoverflow.com/questions/489720/what-are-some-common-uses-for-python-decorators&lt;br /&gt;
* Understanding Python decorators - Stack Overflow - http://stackoverflow.com/questions/739654/understanding-python-decorators&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
Utah Python July 2013 Meeting - Decorator Examples: [https://www.youtube.com/watch?v=uh9uhzitdvw]&lt;br /&gt;
&lt;br /&gt;
Example of uses:&lt;br /&gt;
* Count function calls&lt;br /&gt;
* Add additional output (debugging)&lt;br /&gt;
* Timing code&lt;br /&gt;
* Thread synchronization (locks)&lt;br /&gt;
* Type checking&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
## Simple wrapping call&lt;br /&gt;
def shout(f):&lt;br /&gt;
    def wrapper(*args):&lt;br /&gt;
        print(&#039;This is before {name}&#039;.format(name=f.__name__))&lt;br /&gt;
        ret = f(*args)&lt;br /&gt;
        print(&#039;This is after {name}&#039;.format(name=f.__name__))&lt;br /&gt;
        return ret&lt;br /&gt;
    wrapper.__name__ = f.__name__&lt;br /&gt;
    return wrapper&lt;br /&gt;
&lt;br /&gt;
@shout&lt;br /&gt;
def echo(text):&lt;br /&gt;
    print(text)&lt;br /&gt;
&lt;br /&gt;
echo(&#039;this is a test&#039;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
## Counting function calls&lt;br /&gt;
def count(f):&lt;br /&gt;
    def wrapper(*args):&lt;br /&gt;
        wrapper.counter += 1&lt;br /&gt;
        print(&amp;quot;Function called {count} times&amp;quot;.format(count=wrapper.counter))&lt;br /&gt;
        return f(*args)&lt;br /&gt;
    wrapper.counter = 0&lt;br /&gt;
    # change wrapper name, or it will just be &#039;wrapper&#039; (for inspection)&lt;br /&gt;
    wrapper.__name__ = f.__name__&lt;br /&gt;
    return wrapper&lt;br /&gt;
&lt;br /&gt;
@count&lt;br /&gt;
def donothing():&lt;br /&gt;
    pass&lt;br /&gt;
&lt;br /&gt;
donothing()&lt;br /&gt;
donothing()&lt;br /&gt;
print(&amp;quot;Function called a total of {count} times&amp;quot;.format(count=donothing.counter))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
## Timing your code&lt;br /&gt;
import time&lt;br /&gt;
&lt;br /&gt;
def timer(f):&lt;br /&gt;
    def wrapper(*arg):&lt;br /&gt;
        t = time.time()&lt;br /&gt;
        ret = f(*arg)&lt;br /&gt;
        print(&amp;quot;Took {elapsedtime} seconds&amp;quot;.format(elapsedtime=time.time()-t))&lt;br /&gt;
        return ret&lt;br /&gt;
    return wrapper&lt;br /&gt;
&lt;br /&gt;
@timer&lt;br /&gt;
def fact(n):&lt;br /&gt;
    prod = 1&lt;br /&gt;
    while n &amp;gt; 0:&lt;br /&gt;
        prod *= n&lt;br /&gt;
        n -= 1&lt;br /&gt;
    return prod&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
total = fact(10000)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
## Synchronization&lt;br /&gt;
import threading&lt;br /&gt;
&lt;br /&gt;
def synchronized(lock):&lt;br /&gt;
    def wrap(f):&lt;br /&gt;
        def wrapper(*args, **kwargs):&lt;br /&gt;
            lock.acquire()&lt;br /&gt;
            try:&lt;br /&gt;
                return f(*args, **kwargs)&lt;br /&gt;
            finally:&lt;br /&gt;
                lock.release()&lt;br /&gt;
        return wrapper&lt;br /&gt;
    return wrap&lt;br /&gt;
&lt;br /&gt;
mylock = threading.Lock()&lt;br /&gt;
&lt;br /&gt;
@synchronized(mylock)&lt;br /&gt;
def myfunc():&lt;br /&gt;
    pass&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
## Type checking&lt;br /&gt;
def myMethod(ID, name):&lt;br /&gt;
    &#039;&#039;&#039; Old way &#039;&#039;&#039;&lt;br /&gt;
    if not (isinstance(ID, &#039;uint&#039;) and isinstance(name, &#039;utf8string&#039;)):&lt;br /&gt;
        raise Exception()&lt;br /&gt;
&lt;br /&gt;
def accepts(*typeargs):&lt;br /&gt;
    &#039;&#039;&#039; Decorator way &#039;&#039;&#039;&lt;br /&gt;
    def wrap(f):&lt;br /&gt;
        def wrapper(*args):&lt;br /&gt;
            for a, t in zip(args, typeargs):&lt;br /&gt;
                if not isinstance(a, t):&lt;br /&gt;
                    raise Exception(&#039;{a} not of type {t}&#039;.format(a=a, t=t))&lt;br /&gt;
            return f(*args)&lt;br /&gt;
        return wrapper&lt;br /&gt;
    return wrap&lt;br /&gt;
&lt;br /&gt;
@accepts(int)&lt;br /&gt;
def add1(n):&lt;br /&gt;
    return n + 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
## Memoize&lt;br /&gt;
def memoize(f):&lt;br /&gt;
    def wrapper(*args):&lt;br /&gt;
        if not wrapper.ret:&lt;br /&gt;
            wrapper.ret = f(*args)&lt;br /&gt;
        return wrapper.ret&lt;br /&gt;
    wrapper.ret = False&lt;br /&gt;
    wrapper.__name__ = f.__name__&lt;br /&gt;
    return wrapper&lt;br /&gt;
&lt;br /&gt;
import time&lt;br /&gt;
&lt;br /&gt;
@memoize&lt;br /&gt;
def sumto10():&lt;br /&gt;
    count = 0&lt;br /&gt;
    sum = 0&lt;br /&gt;
    while count &amp;lt; 10:&lt;br /&gt;
        sum += count&lt;br /&gt;
        time.sleep(1)&lt;br /&gt;
        count += 1&lt;br /&gt;
    return sum&lt;br /&gt;
&lt;br /&gt;
# first time will count slow&lt;br /&gt;
print sumto10()&lt;br /&gt;
# second time will return cached value instantly&lt;br /&gt;
print sumto10()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Memoize: &amp;quot;Caches a function&#039;s return value each time it is called. If called later with the same arguments, the cached value is returned (not reevaluated)&amp;quot; [http://wiki.python.org/moin/PythonDecoratorLibrary#Memoize]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
## Nested decorators&lt;br /&gt;
import time&lt;br /&gt;
@shout&lt;br /&gt;
@memoize&lt;br /&gt;
def test1():&lt;br /&gt;
  print &amp;quot;calculating&amp;quot;&lt;br /&gt;
  time.sleep(3)&lt;br /&gt;
  return 100&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Order is important!  For tested decorators the execution order is from the top to the bottom.  If you reverse @shout and @memoize, the @shout will not run because of the way @memoize was written.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
## registry&lt;br /&gt;
registry = []&lt;br /&gt;
# can also decorate decorators:&lt;br /&gt;
@shout&lt;br /&gt;
def registry(f):&lt;br /&gt;
    registry.append(f)&lt;br /&gt;
    return f&lt;br /&gt;
&lt;br /&gt;
@register&lt;br /&gt;
def test2():&lt;br /&gt;
    pass&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Decorator is just a function that returns a function.&lt;br /&gt;
&lt;br /&gt;
Can use functools to automatically update decorator wrappers with __name__, etc [http://docs.python.org/2/library/functools.html]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
## Auto syntax sygar the wrapper for you&lt;br /&gt;
import functools&lt;br /&gt;
def my_decorator(f):&lt;br /&gt;
    @functools.wraps(f)&lt;br /&gt;
    def wrapper(*args, **kwds):&lt;br /&gt;
        print &#039;Calling decorated function&#039;&lt;br /&gt;
        return f(*args, **kwds)&lt;br /&gt;
    return wrapper&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Class Method Decorators ===&lt;br /&gt;
&lt;br /&gt;
Static methods: [http://docs.python.org/library/functions.html#staticmethod]&lt;br /&gt;
: Similar to C++ and Java static methods&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class C:&lt;br /&gt;
  @staticmethod&lt;br /&gt;
  def say(msg):&lt;br /&gt;
    print(msg)&lt;br /&gt;
&lt;br /&gt;
C.say(&#039;hi&#039;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Class method: [http://docs.python.org/library/functions.html#classmethod]&lt;br /&gt;
: A class method receives the class as implicit first argument, just like an instance method receives the instance.&lt;br /&gt;
: Class methods are different than C++ or Java static methods. If you want those, see staticmethod() in this section.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    @classmethod&lt;br /&gt;
    def setup_parser(cls, parser):&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See also [[#Class Properties]]&lt;br /&gt;
&lt;br /&gt;
=== Class Properties ===&lt;br /&gt;
&lt;br /&gt;
Properties: (not using decorators)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class C(object):&lt;br /&gt;
    def __init__(self):&lt;br /&gt;
        self._x = None&lt;br /&gt;
    def getx(self):&lt;br /&gt;
        print(&amp;quot;get x&amp;quot;)&lt;br /&gt;
        return self._x&lt;br /&gt;
    def setx(self, value):&lt;br /&gt;
        print(&amp;quot;set x&amp;quot;)&lt;br /&gt;
        self._x = value&lt;br /&gt;
    def delx(self):&lt;br /&gt;
        print(&amp;quot;del x&amp;quot;)&lt;br /&gt;
        del self._x&lt;br /&gt;
    x = property(getx, setx, delx, &amp;quot;I&#039;m the &#039;x&#039; property.&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#usage&lt;br /&gt;
c = C()&lt;br /&gt;
c.x = 5&lt;br /&gt;
print(c.x)&lt;br /&gt;
del(c.x)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Getter and Setter Property Decorators: [http://docs.python.org/library/functions.html#property]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class C(object):    # make sure to inherit from object for these properties to work!&lt;br /&gt;
    def __init__(self):&lt;br /&gt;
        self._x = None&lt;br /&gt;
    &lt;br /&gt;
    @property&lt;br /&gt;
    def x(self):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;I&#039;m the &#039;x&#039; property.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        print(&amp;quot;get x&amp;quot;)&lt;br /&gt;
        return self._x&lt;br /&gt;
    &lt;br /&gt;
    @x.setter   # python &amp;gt;= 2.6&lt;br /&gt;
    def x(self, value):&lt;br /&gt;
        print(&amp;quot;set x&amp;quot;)&lt;br /&gt;
        self._x = value&lt;br /&gt;
    &lt;br /&gt;
    @x.deleter  # python &amp;gt;= 2.6&lt;br /&gt;
    def x(self):&lt;br /&gt;
        print(&amp;quot;del x&amp;quot;)&lt;br /&gt;
        del self._x&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#usage&lt;br /&gt;
c = C()&lt;br /&gt;
c.x = 5&lt;br /&gt;
print(c.x)&lt;br /&gt;
del(c.x)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: If you don&#039;t add the @x.setter, the property will be read only, and will throw a &amp;quot;AttributeError: can&#039;t set attribute&amp;quot; if attempted to be set.&lt;br /&gt;
&lt;br /&gt;
Using x.getter example: [http://wiki.python.org/moin/AlternativeDescriptionOfProperty]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Cls(object):&lt;br /&gt;
    def __init__(self):&lt;br /&gt;
        self._x = 100&lt;br /&gt;
&lt;br /&gt;
    x = property()&lt;br /&gt;
&lt;br /&gt;
    @x.getter&lt;br /&gt;
    def x(self):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;I&#039;m the &#039;x&#039; property.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        return self._x&lt;br /&gt;
&lt;br /&gt;
    @x.setter&lt;br /&gt;
    def x(self, value):&lt;br /&gt;
        self._x = value&lt;br /&gt;
&lt;br /&gt;
    @x.deleter&lt;br /&gt;
    def x(self):&lt;br /&gt;
        del self._x&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Custom Decorators ===&lt;br /&gt;
&lt;br /&gt;
decorator&lt;br /&gt;
 @dec1&lt;br /&gt;
 def func(arg1, arg2, ...): pass&lt;br /&gt;
&lt;br /&gt;
equivalent to:&lt;br /&gt;
 def func(arg1, arg2, ...): pass&lt;br /&gt;
 func = dec1(func)&lt;br /&gt;
&lt;br /&gt;
Basic layout (names are arbitrary):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def my_decorator(function_name):&lt;br /&gt;
  # update wrapper.__doc__ and .func_name&lt;br /&gt;
  # or @functools.wraps(my_wrapper)&lt;br /&gt;
  def mywrapper(*args, **kw):&lt;br /&gt;
    # do something before&lt;br /&gt;
    result = function_name(*args, **kw)&lt;br /&gt;
    # do something after&lt;br /&gt;
    return result&lt;br /&gt;
  return my_wrapper&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def limit(length):&lt;br /&gt;
  def decorator(function):&lt;br /&gt;
    def wrapper(*args, **kw):&lt;br /&gt;
      result = function(*args, **kw)&lt;br /&gt;
      result = result[:length]&lt;br /&gt;
      return result&lt;br /&gt;
    return wrapper&lt;br /&gt;
  return decorator&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
@limit(3)&lt;br /&gt;
def echo(foo):  return foo&lt;br /&gt;
&lt;br /&gt;
echo(&#039;123456&#039;)  # &#039;123&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== assert ===&lt;br /&gt;
&lt;br /&gt;
 assert True&lt;br /&gt;
 assert False  # exception&lt;br /&gt;
 assert 1 == 1&lt;br /&gt;
 assert 1 == 2, &amp;quot;some message&amp;quot;  # AssertionError: some message&lt;br /&gt;
&lt;br /&gt;
=== Snake Case ===&lt;br /&gt;
&lt;br /&gt;
Convert Camel Case to Snake Case: [http://stackoverflow.com/questions/1175208/elegant-python-function-to-convert-camelcase-to-snake-case]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def snake_case(name):&lt;br /&gt;
    s1 = re.sub(&#039;(.)([A-Z][a-z]+)&#039;, r&#039;\1_\2&#039;, name)&lt;br /&gt;
    return re.sub(&#039;([a-z0-9])([A-Z])&#039;, r&#039;\1_\2&#039;, s1).lower()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; convert(&#039;CamelCase&#039;)&lt;br /&gt;
&#039;camel_case&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Camel Case ===&lt;br /&gt;
&lt;br /&gt;
Camel Case: [http://stackoverflow.com/questions/8347048/camelcase-every-string-any-standard-library]&lt;br /&gt;
&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; &#039;&#039;.join(x for x in &#039;make IT camel CaSe&#039;.title() if not x.isspace())&lt;br /&gt;
 &#039;MakeItCamelCase&#039;&lt;br /&gt;
&lt;br /&gt;
To titleize a sentence:&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; &amp;quot;this is a test&amp;quot;.title()&lt;br /&gt;
 &amp;quot;This Is A Test&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Lambda ===&lt;br /&gt;
&lt;br /&gt;
Simple functions&lt;br /&gt;
 mul = lambda a, b: a * b&lt;br /&gt;
&lt;br /&gt;
 # equivalent to:&lt;br /&gt;
 def mul(a, b):&lt;br /&gt;
   return a * b&lt;br /&gt;
&lt;br /&gt;
Sort usage:&lt;br /&gt;
 data = [dict(number=x) for x in &#039;036149&#039;]&lt;br /&gt;
 data.sort(key=lambda x: float(x[&#039;number&#039;]))&lt;br /&gt;
&lt;br /&gt;
Compare usage:&lt;br /&gt;
 data = [dict(number=x) for x in &#039;036149&#039;]&lt;br /&gt;
 data.sort(cmp=lambda x,y: cmp(x[&#039;number&#039;], y[&#039;number&#039;]))&lt;br /&gt;
&lt;br /&gt;
Boolean:&lt;br /&gt;
 lambda x: x % 3 == 0&lt;br /&gt;
&lt;br /&gt;
Multiple parameter:&lt;br /&gt;
 lambda x, y: x + y&lt;br /&gt;
&lt;br /&gt;
Call another function:&lt;br /&gt;
 lambda word: len(word)&lt;br /&gt;
&lt;br /&gt;
Strings:&lt;br /&gt;
 lambda line: line.split()[2]&lt;br /&gt;
&lt;br /&gt;
Embedded:&lt;br /&gt;
 def transform(n):&lt;br /&gt;
    return lambda x: x + n&lt;br /&gt;
&lt;br /&gt;
No parameters:&lt;br /&gt;
 lambda: 1&lt;br /&gt;
&lt;br /&gt;
Default parameters:&lt;br /&gt;
 lambda x=1: x+1&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* Python: Lambda Functions - http://www.secnetix.de/olli/Python/lambda_functions.hawk&lt;br /&gt;
&lt;br /&gt;
=== Map ===&lt;br /&gt;
&lt;br /&gt;
Apply a function to items of a sequence:&lt;br /&gt;
 map(str, range(3))   # [&#039;0&#039;, &#039;1&#039;, &#039;2&#039;]&lt;br /&gt;
&lt;br /&gt;
Note: list comprehensions can replace map and filter&lt;br /&gt;
&lt;br /&gt;
=== Reduce ===&lt;br /&gt;
&lt;br /&gt;
Apply a function to pairs of the sequence:&lt;br /&gt;
 import operator&lt;br /&gt;
 reduce(operator.mul, [1,2,3,4])   # 24   - ((1*2)*3)*4)&lt;br /&gt;
&lt;br /&gt;
Note: sum or for loop can replace reduce&lt;br /&gt;
&lt;br /&gt;
=== Filter ===&lt;br /&gt;
&lt;br /&gt;
Return a sequence of items for which function(item) is True&lt;br /&gt;
 filter(lambda x: x &amp;gt;= 0, [0, -1, 3])  # [0, 3]&lt;br /&gt;
&lt;br /&gt;
Note: list comprehensions can replace map and filter&lt;br /&gt;
&lt;br /&gt;
Find matching items in two lists:&lt;br /&gt;
 a = [&#039;a&#039;,&#039;b&#039;,&#039;c&#039;]&lt;br /&gt;
 b = [&#039;c&#039;,&#039;d&#039;]&lt;br /&gt;
 filter(lambda x: x in a, b)  # returns only &#039;c&#039; as it is in both lists&lt;br /&gt;
&lt;br /&gt;
=== List comprehension ===&lt;br /&gt;
&lt;br /&gt;
Nothing more than Syntactic Sugar&lt;br /&gt;
&lt;br /&gt;
5. Data Structures — Python v2.7.5 documentation - http://docs.python.org/2/tutorial/datastructures.html#list-comprehensions&lt;br /&gt;
: &amp;quot;List comprehensions provide a concise way to create lists.&amp;quot;&lt;br /&gt;
: &amp;quot;A list comprehension consists of &#039;&#039;&#039;brackets&#039;&#039;&#039; containing an &#039;&#039;&#039;expression&#039;&#039;&#039; followed by a &#039;&#039;&#039;for clause&#039;&#039;&#039;, then &#039;&#039;&#039;zero or more for or if clauses&#039;&#039;&#039;. &amp;quot;&lt;br /&gt;
&lt;br /&gt;
Remove newlines from each item in a list:&lt;br /&gt;
 mylist = [x.strip() for x in mylist]&lt;br /&gt;
&lt;br /&gt;
Simple:&lt;br /&gt;
 doubled = [x*2 for x in mylist]&lt;br /&gt;
 squares = [x**2 for x in range(10)]&lt;br /&gt;
&lt;br /&gt;
If:&lt;br /&gt;
 [ 2*x for x in range(1,10) if x &amp;gt;= 5 ]&lt;br /&gt;
&lt;br /&gt;
Complex:&lt;br /&gt;
 [(x, y) for x in [1,2,3] for y in [3,1,4] if x != y]&lt;br /&gt;
&lt;br /&gt;
Expanding PI:&lt;br /&gt;
 [str(round(pi, i)) for i in range(1, 6)]&lt;br /&gt;
&lt;br /&gt;
Return list of words&lt;br /&gt;
 my_list = [current_word.lower() for current_word in words]&lt;br /&gt;
&lt;br /&gt;
Utah Python July 2013 Meeting: (http://basepi.net)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Iterative&lt;br /&gt;
squares = []&lt;br /&gt;
for x in range(10):&lt;br /&gt;
    squares.append(x**2)&lt;br /&gt;
# [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]&lt;br /&gt;
&lt;br /&gt;
## Functional&lt;br /&gt;
squares = map(lambda x: x**2, range(10))&lt;br /&gt;
&lt;br /&gt;
## List comprehension&lt;br /&gt;
squares = [x**2 for x in range(10)]&lt;br /&gt;
even_squares = [x**2 for x in range(10) if x%2 == 0]&lt;br /&gt;
&lt;br /&gt;
# get hash of strings in list:&lt;br /&gt;
import sha&lt;br /&gt;
strings = [&#039;Python is cool!&#039;, &#039;I love python&#039;]&lt;br /&gt;
hashes = [sha.sha(x).digest() for x in strings]&lt;br /&gt;
&lt;br /&gt;
# flatten matrix:&lt;br /&gt;
matrix = [[1, 2, 3], [4, 5, 6]]&lt;br /&gt;
[x for row in matrix for x in row]&lt;br /&gt;
# [1, 2, 3, 4, 5, 6]&lt;br /&gt;
&lt;br /&gt;
# build matrix:&lt;br /&gt;
[(x,y) for x in range(10) for y in range(10)]&lt;br /&gt;
# matrix of not both odd and not both even&lt;br /&gt;
[(x,y) for x in range(10) for y in range(10) if x%2 != y%2]&lt;br /&gt;
&lt;br /&gt;
# suck lines of files into list, ignoring commented lines&lt;br /&gt;
[line.strip().split(&amp;quot;\t&amp;quot;) for line in open(&amp;quot;my_file.tab&amp;quot;)&lt;br /&gt;
    if not line.startswith(&#039;#&#039;)]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* 5.1.4. List Comprehensions - Data Structures — Python v2.7.2 documentation - http://docs.python.org/tutorial/datastructures.html#list-comprehensions&lt;br /&gt;
* Utah Python July 2013 Meeting - YouTube - https://www.youtube.com/watch?v=uh9uhzitdvw [http://basepi.net]&lt;br /&gt;
&lt;br /&gt;
=== [http://docs.python.org/reference/expressions#calls Mass Parameter Passing] ===&lt;br /&gt;
&lt;br /&gt;
Using: *args and **kw&lt;br /&gt;
* *args a tuple of remaining unnamed parameters&lt;br /&gt;
* **kw a dictionary of remaining named parameters&lt;br /&gt;
&lt;br /&gt;
 def param_func(a, b=&#039;b&#039;, *args, **kw):&lt;br /&gt;
   print( [a, b, args, kw] )&lt;br /&gt;
&lt;br /&gt;
WARNING: If not careful, this can result in this error: &amp;quot;TypeError: param_func() got multiple values for keyword argument &#039;myvar&#039;&amp;quot;.  Might be better to just use:&lt;br /&gt;
&lt;br /&gt;
 def param_func(*args, **kw):&lt;br /&gt;
   print( [args, kw] )&lt;br /&gt;
&lt;br /&gt;
 param_func(1, 2, 3, 4, 5)  # [1, 2, (3, 4, 5), {}]&lt;br /&gt;
 param_func(1, 2, 3, 4, 5, joe=&#039;test&#039;)  # [1, 2, (3, 4, 5), {&#039;joe&#039;: &#039;test&#039;}]&lt;br /&gt;
 mylist = (&amp;quot;a&amp;quot;, &amp;quot;c&amp;quot;, &amp;quot;g&amp;quot;, &amp;quot;h&amp;quot;, 5)&lt;br /&gt;
 param_func(mylist)  # [(&#039;a&#039;, &#039;c&#039;, &#039;g&#039;, &#039;h&#039;, 5), &#039;b&#039;, (), {}]&lt;br /&gt;
 param_func(*mylist)  # [&#039;a&#039;, &#039;c&#039;, (&#039;g&#039;, &#039;h&#039;, 5), {}]  *tricky*&lt;br /&gt;
 Note: *mydict will strip out just keys and treat like list&lt;br /&gt;
 Note: **mydict will treat like named parameters&lt;br /&gt;
&lt;br /&gt;
 def mywrapper(*args, **kw):&lt;br /&gt;
   # do something before&lt;br /&gt;
   result = function_name(*args, **kw)&lt;br /&gt;
&lt;br /&gt;
Passing arbitrary parameters:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def fun2(**kw):&lt;br /&gt;
  print kw  # {&#039;a&#039;: &#039;1&#039;, &#039;b&#039;: &#039;2&#039;, &#039;c&#039;: &#039;3&#039;}&lt;br /&gt;
&lt;br /&gt;
def fun1(c=&#039;3&#039;, **kw):&lt;br /&gt;
 print kw  # {&#039;a&#039;: &#039;1&#039;, &#039;b&#039;: &#039;2&#039;}&lt;br /&gt;
 fun2(c=&#039;3&#039;, **kw)&lt;br /&gt;
&lt;br /&gt;
fun1(a=&#039;1&#039;, b=&#039;2&#039;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [http://www.python.org/dev/peps/pep-0234/ Iteration Protocol] ===&lt;br /&gt;
&lt;br /&gt;
[http://www.python.org/dev/peps/pep-0234/ PEP 234 -- Iterators]&lt;br /&gt;
&lt;br /&gt;
Making a class iterable:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class mycount(object):&lt;br /&gt;
  def __init__(self, max):&lt;br /&gt;
    self.x = 0&lt;br /&gt;
    self.max = max&lt;br /&gt;
  def __iter__(self):  # return object that implements __next__() or next()&lt;br /&gt;
    return self&lt;br /&gt;
  def next(self):&lt;br /&gt;
    if self.x &amp;lt; self.max:&lt;br /&gt;
      self.x += 1&lt;br /&gt;
      return self.x&lt;br /&gt;
    else:&lt;br /&gt;
      self.x = 0&lt;br /&gt;
      raise StopIteration()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 for i in mycount(10): print i     # 1 ... 10&lt;br /&gt;
 print [x for x in mycount(10) ]   # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]&lt;br /&gt;
&lt;br /&gt;
 c = mycount(10)&lt;br /&gt;
 for i in c: print i    # 1 ... 10&lt;br /&gt;
 [ x for x in c ]       # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]&lt;br /&gt;
&lt;br /&gt;
=== Generators ===&lt;br /&gt;
&lt;br /&gt;
Generators are functions that return to their previous state (using &#039;yield&#039;) when iterated over, which can be used in for loops.&lt;br /&gt;
&lt;br /&gt;
==== Yield ====&lt;br /&gt;
&lt;br /&gt;
Improve on Iterators:&lt;br /&gt;
* Infinite data (infinite iterators)&lt;br /&gt;
* Memory-intensive iteration&lt;br /&gt;
* Cooperative Multi-threading&lt;br /&gt;
&lt;br /&gt;
Generators are functions that return to their previous state when iterated over, which can be used in for loops.&lt;br /&gt;
&lt;br /&gt;
Note: Generators throw StopIteration when completed&lt;br /&gt;
&lt;br /&gt;
Note: the &#039;yield&#039; keyword will stash away the state of the function and return the value. (Continuations)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def gen_range(end):&lt;br /&gt;
  cur = 0&lt;br /&gt;
  while cur &amp;lt; end:&lt;br /&gt;
    yield cur&lt;br /&gt;
    # return here next time&lt;br /&gt;
    cur += 1&lt;br /&gt;
&lt;br /&gt;
# for loop iteration&lt;br /&gt;
for i in gen_range(10):  print i&lt;br /&gt;
&lt;br /&gt;
# manual iteration&lt;br /&gt;
my_gen = gen_range(10)&lt;br /&gt;
try:&lt;br /&gt;
  while True:&lt;br /&gt;
    print my_gen.next()&lt;br /&gt;
except StopIteration:&lt;br /&gt;
  pass&lt;br /&gt;
&lt;br /&gt;
# list comprehension&lt;br /&gt;
numbers = [x for x in gen_range(10)]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: one can place an empty &#039;return&#039; in a generator if needed.  A &#039;return&#039; with argument is invalid.&lt;br /&gt;
&lt;br /&gt;
Making a class generate:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class mycount(object):&lt;br /&gt;
  def __init__(self, max):&lt;br /&gt;
    self.max = max&lt;br /&gt;
  def __iter__(self):&lt;br /&gt;
    return self.next()      # change here&lt;br /&gt;
  def next(self):           # change here&lt;br /&gt;
    x = 0&lt;br /&gt;
    while x &amp;lt; self.max:&lt;br /&gt;
      x += 1&lt;br /&gt;
      yield x&lt;br /&gt;
&lt;br /&gt;
for i in mycount(10): print i     # 1 ... 10&lt;br /&gt;
print [x for x in mycount(10) ]   # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]&lt;br /&gt;
&lt;br /&gt;
c = mycount(10)&lt;br /&gt;
for i in c: print i    # 1 ... 10&lt;br /&gt;
[ x for x in c ]       # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]&lt;br /&gt;
&lt;br /&gt;
itr = mycount(10).next()&lt;br /&gt;
itr.next()  # 1&lt;br /&gt;
itr.next()  # 2  - eventually throws StopIteration exception&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Utah Python July 2013 Meeting: [https://www.youtube.com/watch?v=uh9uhzitdvw] [http://basepi.net]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
* Iterators are used to traverse a list&lt;br /&gt;
* Generators are more powerful Iterators&lt;br /&gt;
&lt;br /&gt;
# simple &#039;n&#039; number in functional form&lt;br /&gt;
def firstn(n):&lt;br /&gt;
    num = 0&lt;br /&gt;
    nums = []&lt;br /&gt;
    while num &amp;lt; n:&lt;br /&gt;
        nums.append(num)&lt;br /&gt;
        num += 1&lt;br /&gt;
    return nums&lt;br /&gt;
&lt;br /&gt;
# simple &#039;n&#039; number in generator form&lt;br /&gt;
def firstn(n):&lt;br /&gt;
    num = 0&lt;br /&gt;
    while num &amp;lt; n:&lt;br /&gt;
        yield num&lt;br /&gt;
        num += 1&lt;br /&gt;
&lt;br /&gt;
-&lt;br /&gt;
&lt;br /&gt;
# Infinite list generator&lt;br /&gt;
def counter():&lt;br /&gt;
    num = 0&lt;br /&gt;
    while True:&lt;br /&gt;
        yield num&lt;br /&gt;
        num += 1&lt;br /&gt;
&lt;br /&gt;
# Fibbonacci generator&lt;br /&gt;
def fib():&lt;br /&gt;
    num1 = 0&lt;br /&gt;
    num2 = 1&lt;br /&gt;
    yield num1&lt;br /&gt;
    while True:&lt;br /&gt;
        num1, num2 = num2, num1 + num2&lt;br /&gt;
        yield num1&lt;br /&gt;
&lt;br /&gt;
# Fibbonacci generator 2&lt;br /&gt;
def fib(n):&lt;br /&gt;
    num1 = 0&lt;br /&gt;
    num2 = 1&lt;br /&gt;
    count = 0&lt;br /&gt;
    yield num1&lt;br /&gt;
    while count &amp;lt; n:&lt;br /&gt;
        count += 1&lt;br /&gt;
        num1, num2 = num2, num1 + num2&lt;br /&gt;
        yield num1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Utah Python July 2013 Meeting: [https://www.youtube.com/watch?v=uh9uhzitdvw] [http://basepi.net]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
## Cooperative Multi-Threading:&lt;br /&gt;
# Cooperative multithreading relies on the threads themselves to relinquish control once they are at a stopping point.&lt;br /&gt;
&lt;br /&gt;
def mythread(name):&lt;br /&gt;
    print(&#039;Starting Thread: {name}...&#039;.format(name=name))&lt;br /&gt;
    counter = 10&lt;br /&gt;
    while counter &amp;gt; 0:&lt;br /&gt;
        print(&#039;Thread: {name} doing some work!&#039;.format(name=name))&lt;br /&gt;
        counter -= 1&lt;br /&gt;
        yield&lt;br /&gt;
&lt;br /&gt;
thread1 = mythread(&#039;Alice&#039;)&lt;br /&gt;
thread2 = mythread(&#039;Bob&#039;)&lt;br /&gt;
thread3 = mythread(&#039;Trudy&#039;)&lt;br /&gt;
&lt;br /&gt;
try:&lt;br /&gt;
    while True:&lt;br /&gt;
        thread1.next()&lt;br /&gt;
        thread2.next()&lt;br /&gt;
        thread3.next()&lt;br /&gt;
except StopIteration:&lt;br /&gt;
    pass&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* Utah Python July 2013 Meeting: [https://www.youtube.com/watch?v=uh9uhzitdvw] [http://basepi.net]&lt;br /&gt;
** http://files.basepi.net/talks/pyarmory.zip&lt;br /&gt;
&lt;br /&gt;
=== dunder methods ===&lt;br /&gt;
&lt;br /&gt;
Some dunder (double under) methods determine what will happen when + (__add__) or other similar numerical symbols used.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class str_add(object):&lt;br /&gt;
    def __init__(self, name):&lt;br /&gt;
        self.name = name&lt;br /&gt;
    def __add__(self, other):&lt;br /&gt;
        self.name += other.name&lt;br /&gt;
        return self&lt;br /&gt;
        # note: only need to return self if you want to go beyond &#039;a + b&#039;&lt;br /&gt;
&lt;br /&gt;
a = str_add(&#039;a_&#039;)&lt;br /&gt;
b = str_add(&#039;b_&#039;)&lt;br /&gt;
c = str_add(&#039;c_&#039;)&lt;br /&gt;
d = a + b + c&lt;br /&gt;
print(a.name)  # a_b_c_&lt;br /&gt;
print(b.name)  # b_&lt;br /&gt;
print(c.name)  # c_&lt;br /&gt;
print(d.name)  # a_b_c_&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Other common methods to override:&lt;br /&gt;
* __add__ for +&lt;br /&gt;
* __sub__ for -&lt;br /&gt;
* __mul__ for *&lt;br /&gt;
* __div__ for /&lt;br /&gt;
* __mod__ for %&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* Emulating numeric types - http://docs.python.org/2/reference/datamodel.html#emulating-numeric-types&lt;br /&gt;
&lt;br /&gt;
=== [http://docs.python.org/library/doctest.html doctest] ===&lt;br /&gt;
&lt;br /&gt;
test.py:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
This is the &amp;quot;example&amp;quot; module.&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; double(5)&lt;br /&gt;
10&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
def double(n):&lt;br /&gt;
  &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  This is double function&lt;br /&gt;
&lt;br /&gt;
  &amp;gt;&amp;gt;&amp;gt; double(3)&lt;br /&gt;
  6&lt;br /&gt;
  &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  return n * 2&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
    import doctest&lt;br /&gt;
    doctest.testmod()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== unittest ===&lt;br /&gt;
&lt;br /&gt;
 unittest.TestCase&lt;br /&gt;
&lt;br /&gt;
Here is a short script to test three functions from the random module:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import random&lt;br /&gt;
import unittest&lt;br /&gt;
&lt;br /&gt;
class TestSequenceFunctions(unittest.TestCase):&lt;br /&gt;
&lt;br /&gt;
    def setUp(self):&lt;br /&gt;
        self.seq = range(10)&lt;br /&gt;
&lt;br /&gt;
    def test_shuffle(self):&lt;br /&gt;
        # make sure the shuffled sequence does not lose any elements&lt;br /&gt;
        random.shuffle(self.seq)&lt;br /&gt;
        self.seq.sort()&lt;br /&gt;
        self.assertEqual(self.seq, range(10))&lt;br /&gt;
&lt;br /&gt;
        # should raise an exception for an immutable sequence&lt;br /&gt;
        self.assertRaises(TypeError, random.shuffle, (1,2,3))&lt;br /&gt;
&lt;br /&gt;
    def test_choice(self):&lt;br /&gt;
        element = random.choice(self.seq)&lt;br /&gt;
        self.assertTrue(element in self.seq)&lt;br /&gt;
&lt;br /&gt;
    def test_sample(self):&lt;br /&gt;
        with self.assertRaises(ValueError):&lt;br /&gt;
            random.sample(self.seq, 20)&lt;br /&gt;
        for element in random.sample(self.seq, 5):&lt;br /&gt;
            self.assertTrue(element in self.seq)&lt;br /&gt;
&lt;br /&gt;
if __name__ == &#039;__main__&#039;:&lt;br /&gt;
    unittest.main()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The unittest module can be used from the command line to run tests from modules, classes or even individual test methods:&lt;br /&gt;
 python -m unittest test_module1 test_module2&lt;br /&gt;
 python -m unittest test_module.TestClass&lt;br /&gt;
 python -m unittest test_module.TestClass.test_method&lt;br /&gt;
 python -m unittest -v test_module  # verbose&lt;br /&gt;
 python -m unittest -h   # help&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* 25.3. unittest — Unit testing framework — Python v2.7.4 documentation - http://docs.python.org/2/library/unittest.html&lt;br /&gt;
* Python Debugging Tips - Google Drive - https://docs.google.com/presentation/d/130Wl--IzbDh9ymF6KHMu0WrsIwz6k32pav1gFbsw7NI/edit?usp=sharing&lt;br /&gt;
&lt;br /&gt;
=== Internet Access ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Python 3&lt;br /&gt;
from urllib.request import urlopen&lt;br /&gt;
for line in urlopen(&#039;http://tycho.usno.navy.mil/cgi-bin/timer.pl&#039;):&lt;br /&gt;
  line = line.decode(&#039;utf-8&#039;)&lt;br /&gt;
  if &#039;EST&#039; in line or &#039;EDT&#039; in line:  # look for eastern time&lt;br /&gt;
    print(line)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Simple SMTP ===&lt;br /&gt;
&lt;br /&gt;
Requires local STMP server.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import smtplib&lt;br /&gt;
server = smtplib.SMTP(&amp;quot;localhost&amp;quot;)&lt;br /&gt;
server.sendmail(&#039;mrken@demo.oeey.com&#039;, &#039;kenneth@demo.oeey.com&#039;,&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;To: kenneth@demo.oeey.com&lt;br /&gt;
From: mrken@demo.oeey.com&lt;br /&gt;
Subject: This is fun&lt;br /&gt;
&lt;br /&gt;
Beware of the dog.&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;)&lt;br /&gt;
server.quit()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
s = smtplib.SMTP(smtp_server)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
with TLS:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
s = smtplib.SMTP(&amp;quot;smtp.gmail.com&amp;quot;,587)&lt;br /&gt;
s.ehlo()&lt;br /&gt;
s.starttls()&lt;br /&gt;
s.ehlo()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
SSL:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
s = smtplib.SMTP_SSL(&#039;smtp.mail.yahoo.com&#039;, 465)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Data Compress ===&lt;br /&gt;
&lt;br /&gt;
zlib, gzip, bz2, zipfile, tarfile&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import zlib&lt;br /&gt;
s = b&#039;hello world&#039;  # only in python &amp;gt;3&lt;br /&gt;
len(s)&lt;br /&gt;
t = zlib.compress(s)&lt;br /&gt;
zlib.decompress(t)&lt;br /&gt;
zlib.crc32(s)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== gzip ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import gzip&lt;br /&gt;
content = &amp;quot;Lots of content here&amp;quot;&lt;br /&gt;
f = gzip.open(&#039;file.txt.gz&#039;, &#039;wb&#039;)&lt;br /&gt;
f.write(content)&lt;br /&gt;
f.close()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import gzip&lt;br /&gt;
f_in = open(&#039;file.txt&#039;, &#039;rb&#039;)&lt;br /&gt;
f_out = gzip.open(&#039;file.txt.gz&#039;, &#039;wb&#039;)&lt;br /&gt;
f_out.writelines(f_in)&lt;br /&gt;
f_out.close()&lt;br /&gt;
f_in.close()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Performance Timer ===&lt;br /&gt;
&lt;br /&gt;
Time a task repeated 10 times:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from timeit import Timer&lt;br /&gt;
Timer(&#039;t=a; a=b; b=t&#039;, &#039;a=1; b=2&#039;).timeit()&lt;br /&gt;
Timer(&#039;print(&amp;quot;hi&amp;quot;)&#039;).timeit(10)  # repeat 10 times and time&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Simple method:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
start_time = int(time.time())&lt;br /&gt;
... task ...&lt;br /&gt;
compute_time = int(time.time()) - start_time&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Python Version Check ===&lt;br /&gt;
&lt;br /&gt;
Solution:&lt;br /&gt;
&lt;br /&gt;
__init__.py:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Check Python Version:&lt;br /&gt;
import sys&lt;br /&gt;
assert sys.version_info &amp;gt;= (2, 6, 0), &#039;requires Python 2.6 or higher&#039;&lt;br /&gt;
del sys&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
resulting error if not &amp;gt; 2.6:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import nucleon&lt;br /&gt;
Traceback (most recent call last):&lt;br /&gt;
  File &amp;quot;&amp;lt;stdin&amp;gt;&amp;quot;, line 1, in ?&lt;br /&gt;
  File &amp;quot;nucleon/__init__.py&amp;quot;, line 9, in ?&lt;br /&gt;
    assert sys.version_info &amp;gt;= (2, 6, 0), &#039;nucleon requires Python 2.6 or higher&#039;&lt;br /&gt;
AssertionError: nucleon requires Python 2.6 or higher&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Other solutions:&lt;br /&gt;
&lt;br /&gt;
Note: this will throw syntax error on 2.4 due to ternary&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import sys&lt;br /&gt;
if sys.version_info &amp;lt; (2, 4):&lt;br /&gt;
    raise &amp;quot;must use python 2.5 or greater&amp;quot;&lt;br /&gt;
else:&lt;br /&gt;
    # syntax error in 2.4, ok in 2.5&lt;br /&gt;
    x = 1 if True else 2&lt;br /&gt;
    print x&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
maybe solution:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
try:&lt;br /&gt;
  eval(&amp;quot;1 if True else 2&amp;quot;)&lt;br /&gt;
except SyntaxError:&lt;br /&gt;
  # doesn&#039;t have ternary&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; try:&lt;br /&gt;
...     from my_module import twoPointSixCode&lt;br /&gt;
... except Exception: &lt;br /&gt;
...     print &amp;quot;can&#039;t import, probably because your python is too old!&amp;quot;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/env/python&lt;br /&gt;
import sys&lt;br /&gt;
if sys.version_info&amp;lt;(2,6,0):&lt;br /&gt;
  sys.stderr.write(&amp;quot;You need python 2.6 or later to run this script\n&amp;quot;)&lt;br /&gt;
  exit(1)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import sys&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; sys.hexversion  # hex printed as integer&lt;br /&gt;
33817584&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; &#039;%x&#039; % sys.hexversion  # output as hex, not zero fill  2.4.3&lt;br /&gt;
&#039;20403f0&#039;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; sys.hexversion &amp;lt; 0x02060000  # test if version less than 2.6&lt;br /&gt;
True&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; print &amp;quot;0x%08x&amp;quot; % sys.hexversion  # print as hex and zero fill and prepend &#039;0x&#039;&lt;br /&gt;
0x020403f0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import sys&lt;br /&gt;
if sys.hexversion &amp;lt; 0x02060500:&lt;br /&gt;
    print &amp;gt;&amp;gt; sys.stderr, &amp;quot;This script requires python 2.6.5 or higher.&amp;quot;&lt;br /&gt;
    exit(1)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import sys&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; sys.version_info&lt;br /&gt;
(2, 6, 4, &#039;final&#039;, 0)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; if not sys.version_info[:2] == (2, 6):&lt;br /&gt;
...    print &amp;quot;Error, I need python 2.6&amp;quot;&lt;br /&gt;
... else:&lt;br /&gt;
...    from my_module import twoPointSixCode&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* http://stackoverflow.com/questions/446052/python-best-way-to-check-for-python-version-in-program-that-uses-new-language-fe&lt;br /&gt;
* http://stackoverflow.com/questions/1093322/how-do-i-check-what-version-of-python-is-running-my-script&lt;br /&gt;
&lt;br /&gt;
=== [http://docs.python.org/library/struct.html Struct - Binary Data Record Layout] ===&lt;br /&gt;
&lt;br /&gt;
Format Characters:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Format	C Type		Python type 	Standard size&lt;br /&gt;
x	pad byte	no value	  	 &lt;br /&gt;
c	char		str of len 1	1	 &lt;br /&gt;
b	signed char	integer		1&lt;br /&gt;
B	unsigned char	integer 	1&lt;br /&gt;
?	_Bool		bool 		1&lt;br /&gt;
h	short		integer 	2&lt;br /&gt;
H	unsigned short 	integer 	2&lt;br /&gt;
i	int		integer 	4&lt;br /&gt;
I	unsigned int 	integer 	4&lt;br /&gt;
l	long		integer 	4&lt;br /&gt;
L	unsigned long	integer		4&lt;br /&gt;
q	long long	integer		8&lt;br /&gt;
Q	unsigned long long    integer	8&lt;br /&gt;
f	float		float		4&lt;br /&gt;
d	double		float		8&lt;br /&gt;
s	char[]		string&lt;br /&gt;
p	char[]		string&lt;br /&gt;
P	void *		integer&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 H  # two byte unassigned number&lt;br /&gt;
 I  # four byte unassigned number&lt;br /&gt;
 &amp;lt;  # standard size and in little-endian byte order&lt;br /&gt;
&lt;br /&gt;
 import struct&lt;br /&gt;
 data = struct.pack(&#039;&amp;lt;IIIHH&#039;, 1, 2, 3, 4, 5)&lt;br /&gt;
 # data = &#039;\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x04\x00\x05\x00&#039;&lt;br /&gt;
 &lt;br /&gt;
 fields = struct.unpack(&#039;&amp;lt;IIIHH&#039;, data)&lt;br /&gt;
 # fields = (1L, 2L, 3L, 4, 5)&lt;br /&gt;
 # using splice: fields = struct.unpack(&#039;&amp;lt;IIIHH&#039;, data[start:start+16])&lt;br /&gt;
 &lt;br /&gt;
 f1, f2, f3, f4, f5 = fields&lt;br /&gt;
 &lt;br /&gt;
 hex(f1)  # hex a field:&lt;br /&gt;
 #  &#039;0x1L&#039;&lt;br /&gt;
&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; struct.pack(&amp;quot;&amp;lt;5sh&amp;quot;, &amp;quot;helloo&amp;quot;, 11)&lt;br /&gt;
 &#039;hello\x0b\x00&#039;&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; struct.unpack(&amp;quot;&amp;lt;5sh&amp;quot;, &#039;hello\x0b\x00&#039;)&lt;br /&gt;
 (&#039;hello&#039;, 11)&lt;br /&gt;
&lt;br /&gt;
=== pdb interactive debugger ===&lt;br /&gt;
&lt;br /&gt;
 # uncomment the following to use the interactive debugger:&lt;br /&gt;
 # import pdb; pdb.set_trace()&lt;br /&gt;
&lt;br /&gt;
=== [http://docs.python.org/library/telnetlib.html Telnet] ===&lt;br /&gt;
&lt;br /&gt;
create:&lt;br /&gt;
 class telnetlib.Telnet([host[, port[, timeout]]])&lt;br /&gt;
&lt;br /&gt;
Note: The instance is initially not connected by default; the open() method must be used to establish a connection. Alternatively, the host name and optional port number can be passed to the constructor, to, in which case the connection to the server will be established before the constructor returns.&lt;br /&gt;
&lt;br /&gt;
open if not initially done so:&lt;br /&gt;
 Telnet.open(host[, port[, timeout]])&lt;br /&gt;
&lt;br /&gt;
Functions:&lt;br /&gt;
 Telnet.read_until(expected[, timeout])   # Read until a given string, expected, is encountered or until timeout seconds have passed.&lt;br /&gt;
                                          # on timeout return whatever is in queue, possibly empty string&lt;br /&gt;
 Telnet.close()         # close connection&lt;br /&gt;
 Telnet.read_all()      # Read all data until EOF; block until connection closed.&lt;br /&gt;
 Telnet.write(buffer)   # Write a string to the socket, doubling any IAC characters. This can block if the connection is blocked.&lt;br /&gt;
 Telnet.expect(list[, timeout])  # Read until one from a list of a regular expressions matches.&lt;br /&gt;
                        # Return a tuple of three items: the index in the list of matches; the match object; and the text read to match.&lt;br /&gt;
&lt;br /&gt;
Read until end of line:&lt;br /&gt;
 line = tn.read_until(&amp;quot;\n&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import getpass&lt;br /&gt;
import sys&lt;br /&gt;
import telnetlib&lt;br /&gt;
&lt;br /&gt;
HOST = &amp;quot;localhost&amp;quot;&lt;br /&gt;
user = raw_input(&amp;quot;Enter your remote account: &amp;quot;)&lt;br /&gt;
password = getpass.getpass()&lt;br /&gt;
&lt;br /&gt;
tn = telnetlib.Telnet(HOST)&lt;br /&gt;
&lt;br /&gt;
tn.read_until(&amp;quot;login: &amp;quot;)&lt;br /&gt;
tn.write(user + &amp;quot;\n&amp;quot;)&lt;br /&gt;
if password:&lt;br /&gt;
    tn.read_until(&amp;quot;Password: &amp;quot;)&lt;br /&gt;
    tn.write(password + &amp;quot;\n&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
tn.write(&amp;quot;ls\n&amp;quot;)&lt;br /&gt;
tn.write(&amp;quot;exit\n&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
print tn.read_all()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
&lt;br /&gt;
import sys&lt;br /&gt;
import telnetlib&lt;br /&gt;
&lt;br /&gt;
HOST = &amp;quot;216.119.193.252&amp;quot;&lt;br /&gt;
USER = &amp;quot;admin&amp;quot;&lt;br /&gt;
PASS = &amp;quot;@lt12345&amp;quot;&lt;br /&gt;
&lt;br /&gt;
tn = telnetlib.Telnet(HOST)&lt;br /&gt;
&lt;br /&gt;
tn.read_until(&amp;quot;login: &amp;quot;)&lt;br /&gt;
tn.write(USER + &amp;quot;\n&amp;quot;)&lt;br /&gt;
tn.read_until(&amp;quot;Password: &amp;quot;)&lt;br /&gt;
tn.write(PASS + &amp;quot;\n&amp;quot;)&lt;br /&gt;
tn.read_until(&amp;quot;# &amp;quot;)&lt;br /&gt;
&lt;br /&gt;
tn.write(&amp;quot;terminal length 0\n&amp;quot;)&lt;br /&gt;
tn.read_until(&amp;quot;# &amp;quot;)&lt;br /&gt;
&lt;br /&gt;
tn.write(&amp;quot;show running-config\n&amp;quot;)&lt;br /&gt;
configlines = tn.read_until(&amp;quot;# &amp;quot;)&lt;br /&gt;
&lt;br /&gt;
tn.write(&amp;quot;exit\n&amp;quot;)&lt;br /&gt;
tn.read_all()&lt;br /&gt;
&lt;br /&gt;
print(configlines)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== SSH ===&lt;br /&gt;
&lt;br /&gt;
Cheap method:&lt;br /&gt;
 os.system(&#039;ssh user@server command&#039;)&lt;br /&gt;
&lt;br /&gt;
SecureShell - PythonInfo Wiki - http://wiki.python.org/moin/SecureShell&lt;br /&gt;
: There are several ways to use Secure Shell (SSH) in Python&lt;br /&gt;
* pyssh - http://pyssh.sourceforge.net/&lt;br /&gt;
* paramiko - Paramiko is a native Python implementation of SSH. - http://www.lag.net/paramiko/&lt;br /&gt;
* conch - conch is another native implementation of SSH and part of the Twisted Matrix project - http://twistedmatrix.com/projects/conch &lt;br /&gt;
* SSH wrapper - Some tools just wrap around existing ssh/sftp implementations&lt;br /&gt;
** keyphrene - http://www.keyphrene.com/products/org.keyphrene/&lt;br /&gt;
** keyphrene SSH wrapper - http://membres.lycos.fr/fredp/python/pyscp.html&lt;br /&gt;
* Fabric - http://docs.fabfile.org/en/1.4.0/index.html&lt;br /&gt;
* pexpect - Noah.org - http://www.noah.org/wiki/Pexpect&lt;br /&gt;
&lt;br /&gt;
SFTP:&lt;br /&gt;
* SFTP in Python: Really Simple SSH | The best of Zeth - http://zeth.net/post/332/&lt;br /&gt;
&lt;br /&gt;
pexpect:&lt;br /&gt;
 wget http://pexpect.sourceforge.net/pexpect-2.3.tar.gz&lt;br /&gt;
 tar xzf pexpect-2.3.tar.gz&lt;br /&gt;
 cd pexpect-2.3&lt;br /&gt;
 sudo python ./setup.py install&lt;br /&gt;
&lt;br /&gt;
=== SFTP ===&lt;br /&gt;
&lt;br /&gt;
SFTP in Python? (platform independent) - Stack Overflow - http://stackoverflow.com/questions/432385/sftp-in-python-platform-independent&lt;br /&gt;
&lt;br /&gt;
paramiko: ssh2 protocol for python - http://www.lag.net/paramiko/&lt;br /&gt;
&lt;br /&gt;
 pip install paramiko&lt;br /&gt;
&lt;br /&gt;
 mkdir -p ~/.src ; cd ~/.src&lt;br /&gt;
 wget http://www.lag.net/paramiko/download/paramiko-1.7.7.1.zip&lt;br /&gt;
 unzip paramiko-1.7.7.1.zip&lt;br /&gt;
 cd paramiko-1.7.7.1&lt;br /&gt;
 python setup.py install&lt;br /&gt;
&lt;br /&gt;
SFTP Methods:&lt;br /&gt;
* chdir&lt;br /&gt;
* chmod&lt;br /&gt;
* chown&lt;br /&gt;
* close&lt;br /&gt;
* file&lt;br /&gt;
* from_transport&lt;br /&gt;
* get&lt;br /&gt;
* get_channel&lt;br /&gt;
* getcwd&lt;br /&gt;
* listdir&lt;br /&gt;
* listdir_attr&lt;br /&gt;
* logger&lt;br /&gt;
* lstat&lt;br /&gt;
* mkdir&lt;br /&gt;
* normalize&lt;br /&gt;
* open&lt;br /&gt;
* put&lt;br /&gt;
* readlink&lt;br /&gt;
* remove&lt;br /&gt;
* rename&lt;br /&gt;
* request_number&lt;br /&gt;
* rmdir&lt;br /&gt;
* sock&lt;br /&gt;
* stat&lt;br /&gt;
* symlink&lt;br /&gt;
* truncate&lt;br /&gt;
* ultra_debug&lt;br /&gt;
* unlink&lt;br /&gt;
* utime&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import paramiko&lt;br /&gt;
&lt;br /&gt;
host = &amp;quot;THEHOST.com&amp;quot;                    #hard-coded&lt;br /&gt;
port = 22&lt;br /&gt;
transport = paramiko.Transport((host, port))&lt;br /&gt;
&lt;br /&gt;
password = &amp;quot;THEPASSWORD&amp;quot;                #hard-coded&lt;br /&gt;
username = &amp;quot;THEUSERNAME&amp;quot;                #hard-coded&lt;br /&gt;
transport.connect(username = username, password = password)&lt;br /&gt;
&lt;br /&gt;
sftp = paramiko.SFTPClient.from_transport(transport)&lt;br /&gt;
&lt;br /&gt;
import sys&lt;br /&gt;
path = &#039;./THETARGETDIRECTORY/&#039; + sys.argv[1]    #hard-coded&lt;br /&gt;
localpath = sys.argv[1]&lt;br /&gt;
sftp.put(localpath, path)&lt;br /&gt;
&lt;br /&gt;
sftp.close()&lt;br /&gt;
transport.close()&lt;br /&gt;
print &#039;Upload done.&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
VMware Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
&lt;br /&gt;
import paramiko&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
host = &amp;quot;sftp2.engx.vmware.com&amp;quot;&lt;br /&gt;
port = 443&lt;br /&gt;
transport = paramiko.Transport((host, port))&lt;br /&gt;
&lt;br /&gt;
username = &amp;quot;xxxx&amp;quot;&lt;br /&gt;
password = &amp;quot;xxx&amp;quot;&lt;br /&gt;
transport.connect(username = username, password = password)&lt;br /&gt;
&lt;br /&gt;
sftp = paramiko.SFTPClient.from_transport(transport)&lt;br /&gt;
&lt;br /&gt;
print dir(sftp)&lt;br /&gt;
&lt;br /&gt;
print sftp.chdir(&amp;quot;build-uploader&amp;quot;)&lt;br /&gt;
print sftp.listdir()&lt;br /&gt;
&lt;br /&gt;
sftp.close()&lt;br /&gt;
transport.close()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== paramiko ===&lt;br /&gt;
&lt;br /&gt;
See [[Python/paramiko]]&lt;br /&gt;
&lt;br /&gt;
=== [http://docs.python.org/library/getpass.html Get Password] ===&lt;br /&gt;
&lt;br /&gt;
Prompt for password:&lt;br /&gt;
 getpass.getpass(prompt=&#039;Password: &#039;)&lt;br /&gt;
&lt;br /&gt;
 import getpass&lt;br /&gt;
 user = raw_input(&amp;quot;Enter your remote account: &amp;quot;)&lt;br /&gt;
 password = getpass.getpass()&lt;br /&gt;
&lt;br /&gt;
=== [http://docs.python.org/library/configparser.html ini files] ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ini_filename = &#039;my.ini&#039;&lt;br /&gt;
&lt;br /&gt;
import ConfigParser&lt;br /&gt;
parser = ConfigParser.SafeConfigParser()&lt;br /&gt;
parser.read(ini_filename)&lt;br /&gt;
&lt;br /&gt;
sections = parser.sections() # get sections&lt;br /&gt;
for section in sections:&lt;br /&gt;
  print &amp;quot;[&amp;quot; + section + &amp;quot;]&amp;quot;&lt;br /&gt;
  for name, value in parser.items(section):&lt;br /&gt;
    print name + &amp;quot; = &amp;quot; + value&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if parser.has_option(section, option):&lt;br /&gt;
  print( parser.get(section, option) )&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To have the option names not convert to lower case:&lt;br /&gt;
 parser.optionxform = str&lt;br /&gt;
&lt;br /&gt;
Ignore section: [http://stackoverflow.com/questions/2885190/using-pythons-configparser-to-read-a-file-without-section-name]&lt;br /&gt;
 ini_str = &#039;[root]\n&#039; + open(ini_path, &#039;r&#039;).read()&lt;br /&gt;
 ini_fp = StringIO.StringIO(ini_str)&lt;br /&gt;
 config = ConfigParser.RawConfigParser()&lt;br /&gt;
 config.readfp(ini_fp)&lt;br /&gt;
&lt;br /&gt;
Get option:&lt;br /&gt;
 config.has_option(&#039;root&#039;, &#039;some_key&#039;)&lt;br /&gt;
 config.get(&#039;root&#039;, &#039;some_key&#039;)&lt;br /&gt;
&lt;br /&gt;
 config.items(&#039;root&#039;)  # list of Key Value tuples&lt;br /&gt;
&lt;br /&gt;
=== optparse - Option Parser ===&lt;br /&gt;
&lt;br /&gt;
[http://docs.python.org/library/optparse.html - Option Parser&lt;br /&gt;
&lt;br /&gt;
Note: Deprecated since version 2.7: The optparse module is deprecated and will not be developed further; development will continue with the argparse module.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import optparse&lt;br /&gt;
parser = optparse.OptionParser()&lt;br /&gt;
&lt;br /&gt;
parser.add_option(&#039;--name&#039;, default=None)&lt;br /&gt;
&lt;br /&gt;
parser.add_option(&lt;br /&gt;
    &#039;-l&#039;, &#039;--loglevel&#039;,&lt;br /&gt;
    help=&#039;Log Level (default: info)&#039;,&lt;br /&gt;
    default=&amp;quot;info&amp;quot;, action=&#039;store&#039;, type=&#039;string&#039;)&lt;br /&gt;
&lt;br /&gt;
(options, args) = parser.parse_args()&lt;br /&gt;
&lt;br /&gt;
# if no parameters passed show help&lt;br /&gt;
if len(sys.argv) == 1:&lt;br /&gt;
    parser.print_help()&lt;br /&gt;
    sys.exit(1)&lt;br /&gt;
&lt;br /&gt;
# if a stand alone parameter passed, override option&lt;br /&gt;
if args:&lt;br /&gt;
  options.target = args[0]&lt;br /&gt;
&lt;br /&gt;
# show option:&lt;br /&gt;
print(options.loglevel)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: Order is important when listing add_options!&lt;br /&gt;
&lt;br /&gt;
Pretty Description:&lt;br /&gt;
 parser = optparse.OptionParser(description=&amp;quot;Purpose: to do something&amp;quot;)&lt;br /&gt;
 # or&lt;br /&gt;
 parser.description = &amp;quot;Purpose: to do something&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Parse arguments:&lt;br /&gt;
 (options, args) = parser.parse_args()&lt;br /&gt;
Note: If you like, you can pass a custom argument list to parse_args(), but that’s rarely necessary: by default it uses sys.argv[1:].&lt;br /&gt;
&lt;br /&gt;
Change Usage Message:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
usage = &amp;quot;%prog [options]&amp;quot;  # default message&lt;br /&gt;
# Usage: &amp;lt;prog&amp;gt; [options]&amp;quot;  # where &amp;lt;prog&amp;gt; is replaced with the script name&lt;br /&gt;
&lt;br /&gt;
parser = OptionParser(usage=usage)&lt;br /&gt;
# or&lt;br /&gt;
parser.usage = usage  # default message&lt;br /&gt;
# or&lt;br /&gt;
parser.set_usage(usage)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Remove option: (does not remove default value from &#039;options&#039; variable!!! - stupid!)&lt;br /&gt;
 parser.remove_option(&#039;--loglevel&#039;)&lt;br /&gt;
&lt;br /&gt;
Modify an option: (changes are saved to parser automatically, unless in an option group)&lt;br /&gt;
 option = parser.get_option(&#039;--loglevel&#039;)&lt;br /&gt;
 option.help = &#039;something else&#039;&lt;br /&gt;
 option.default = &#039;debug&#039;&lt;br /&gt;
&lt;br /&gt;
 # or&lt;br /&gt;
 parser.remove_option(&amp;quot;--loglevel&amp;quot;)&lt;br /&gt;
 parser.add_option(&amp;quot;--loglevel&amp;quot;, help=&amp;quot;something else&amp;quot;, default=&amp;quot;info&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Modify an option in an option group:&lt;br /&gt;
 opt_group = parser.get_option_group(&amp;quot;--loglevel&amp;quot;)&lt;br /&gt;
 opt_group.remove_option(&amp;quot;--loglevel&amp;quot;)&lt;br /&gt;
 opt_group.add_option(&amp;quot;--loglevel&amp;quot;, help=&amp;quot;something else&amp;quot;, default=&amp;quot;info&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Types: &amp;quot;string&amp;quot;, &amp;quot;int&amp;quot;, &amp;quot;long&amp;quot;, &amp;quot;choice&amp;quot;, &amp;quot;float&amp;quot; and &amp;quot;complex&amp;quot; [http://docs.python.org/library/optparse.html#optparse-standard-option-types]&lt;br /&gt;
Defaults:&lt;br /&gt;
* Default actions is &#039;store&#039;.&lt;br /&gt;
* Default type is &#039;string&#039;.&lt;br /&gt;
* Default dest is the long name of the parameter (or short name if no long name provided)&lt;br /&gt;
* Default value is None&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from optparse import OptionParser&lt;br /&gt;
[...]&lt;br /&gt;
parser = OptionParser()&lt;br /&gt;
&lt;br /&gt;
# string&lt;br /&gt;
parser.add_option(&amp;quot;-f&amp;quot;, &amp;quot;--file&amp;quot;, dest=&amp;quot;filename&amp;quot;,&lt;br /&gt;
                  help=&amp;quot;write report to FILE&amp;quot;, metavar=&amp;quot;FILE&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
# boolean - action is what to do when flag found&lt;br /&gt;
parser.add_option(&amp;quot;-q&amp;quot;, &amp;quot;--quiet&amp;quot;,&lt;br /&gt;
                  action=&amp;quot;store_true&amp;quot;, dest=&amp;quot;verbose&amp;quot;, default=False,&lt;br /&gt;
                  help=&amp;quot;don&#039;t print status messages to stdout&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
# integer&lt;br /&gt;
parser.add_option(&lt;br /&gt;
    &amp;quot;-m&amp;quot;, &amp;quot;--minutes&amp;quot;,&lt;br /&gt;
    help=&amp;quot;Minutes (default: 60)&amp;quot;,&lt;br /&gt;
    default=60, type=&#039;int&#039;)&lt;br /&gt;
&lt;br /&gt;
(options, args) = parser.parse_args()&lt;br /&gt;
&lt;br /&gt;
print &amp;quot;Filename: &amp;quot; + options.filename&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
fake handling of required option:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if not option.filename:&lt;br /&gt;
    parser.print_help()&lt;br /&gt;
    parser.error(&amp;quot;filename is required&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
change default usage:&lt;br /&gt;
  parser = OptionParser(usage=&amp;quot;Usage: %prog [args] arg1 arg2&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Really ugly way to print help usage  :-(&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def Usage():&lt;br /&gt;
    pname = sys.argv[0]&lt;br /&gt;
    cmd=&#039;%s -h&#039; % (pname)&lt;br /&gt;
    os.system(cmd)&lt;br /&gt;
&lt;br /&gt;
if (len(sys.argv) &amp;lt; 2):&lt;br /&gt;
    Usage()&lt;br /&gt;
    sys.exit(1)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Groups:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#  OptionGroup(parser, title, description=None)&lt;br /&gt;
group = OptionGroup(parser, &amp;quot;Dangerous Options&amp;quot;,&lt;br /&gt;
                    &amp;quot;Caution: use these options at your own risk.  &amp;quot;&lt;br /&gt;
                    &amp;quot;It is believed that some of them bite.&amp;quot;)&lt;br /&gt;
group.add_option(&amp;quot;-g&amp;quot;, action=&amp;quot;store_true&amp;quot;, help=&amp;quot;Group option.&amp;quot;)&lt;br /&gt;
parser.add_option_group(group)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hide an option:&lt;br /&gt;
* Option.help&lt;br /&gt;
: &amp;quot;Help text to print for this option when listing all available options after the user supplies a help option (such as --help). If no help text is supplied, the option will be listed without help text. To hide this option, use the special value optparse.SUPPRESS_HELP.&amp;quot;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
parser.add_option(&amp;quot;--secret&amp;quot;, help=SUPPRESS_HELP)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Issues with Option Parser:&lt;br /&gt;
* No handling for positional arguments&lt;br /&gt;
* No adding help for positional arguments&lt;br /&gt;
* No handling for required field&lt;br /&gt;
&lt;br /&gt;
=== argparse ===&lt;br /&gt;
&lt;br /&gt;
argparse - http://docs.python.org/library/argparse.html&lt;br /&gt;
&lt;br /&gt;
argparse — Parser for command-line options, arguments and sub-commands&lt;br /&gt;
&lt;br /&gt;
NOTE: MUCH MORE POWERFUL THAN OPTION PARSER!&lt;br /&gt;
&lt;br /&gt;
Note: New in version 2.7.&lt;br /&gt;
&lt;br /&gt;
Installation on &amp;lt;= 2.6&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Install argparse: - http://code.google.com/p/argparse/&lt;br /&gt;
# REQUIRES SETUPTOOLS&lt;br /&gt;
mkdir -p ~/.src ; cd ~/.src&lt;br /&gt;
wget http://argparse.googlecode.com/files/argparse-1.2.1.tar.gz&lt;br /&gt;
tar -zvxf argparse-1.2.1.tar.gz&lt;br /&gt;
cd argparse-1.2.1&lt;br /&gt;
sudo python setup.py install&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The argparse module makes it easy to write user-friendly command-line interfaces. The program defines what arguments it requires, and argparse will figure out how to parse those out of sys.argv. The argparse module also automatically generates help and usage messages and issues errors when users give the program invalid arguments.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import argparse&lt;br /&gt;
&lt;br /&gt;
parser = argparse.ArgumentParser(description=&#039;Process some integers.&#039;)&lt;br /&gt;
parser.add_argument(&#039;integers&#039;, metavar=&#039;N&#039;, type=int, nargs=&#039;+&#039;,&lt;br /&gt;
                   help=&#039;an integer for the accumulator&#039;)&lt;br /&gt;
parser.add_argument(&#039;--sum&#039;, dest=&#039;accumulate&#039;, action=&#039;store_const&#039;,&lt;br /&gt;
                   const=sum, default=max,&lt;br /&gt;
                   help=&#039;sum the integers (default: find the max)&#039;)&lt;br /&gt;
&lt;br /&gt;
args = parser.parse_args()&lt;br /&gt;
print args.accumulate(args.integers)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import argparse&lt;br /&gt;
&lt;br /&gt;
argparser = demoproject.util.argparse.ArgumentParser(&lt;br /&gt;
    usage=&#039;Kick off demoproject benchmarks.&#039;)&lt;br /&gt;
argparser.add_argument(&lt;br /&gt;
    &#039;--card&#039;,&lt;br /&gt;
    help=&#039;What cards to run on.  Depends on Jenkins NODE_LABEL environment&#039;&lt;br /&gt;
        &#039;variable for correct mappings.&#039;)&lt;br /&gt;
argparser.add_argument(&lt;br /&gt;
    &#039;--suite&#039;, metavar=&#039;SUITE&#039;,&lt;br /&gt;
    help=&#039;Specify the appropriate benchmark suite as defined in &#039;&lt;br /&gt;
        &#039;the benchmark ini file.  Defaults to standard_perf&#039;,&lt;br /&gt;
    default=&#039;standard_perf&#039;)&lt;br /&gt;
args = argparser.parse_args()&lt;br /&gt;
&lt;br /&gt;
print args.card&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Remove an argument: [http://stackoverflow.com/questions/32807319/disable-remove-argument-in-argparse]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def remove_options(parser, options):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot; remove_options(parser, [&#039;--some-option&#039;, &#039;--some-option2&#039;]) &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    for option in options:&lt;br /&gt;
        for action in parser._actions:&lt;br /&gt;
            if vars(action)[&#039;option_strings&#039;][0] == option:&lt;br /&gt;
                parser._handle_conflict_resolve(None,[(option,action)])&lt;br /&gt;
                break&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [http://docs.python.org/library/commands.html commands] ===&lt;br /&gt;
&lt;br /&gt;
35.16. commands — Utilities for running commands — Python v2.7.1 documentation - http://docs.python.org/library/commands.html&lt;br /&gt;
&lt;br /&gt;
Note: Deprecated since version 2.6: The commands module has been removed in Python 3.0. Use the subprocess module instead.&lt;br /&gt;
&lt;br /&gt;
The commands module contains wrapper functions for os.popen() which take a system command as a string and return any output generated by the command and, optionally, the exit status.&lt;br /&gt;
&lt;br /&gt;
Get status and output:&lt;br /&gt;
 status, output = commands.getstatusoutput(cmd)&lt;br /&gt;
&lt;br /&gt;
Get output ignoring status:&lt;br /&gt;
 output = commands.getoutput(cmd)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
NOTE: DO NOT USE getstatus() AS IT DOES NOT DO WHAT YOU THINK IT DOES!&lt;br /&gt;
 status = commands.getstatus(file)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import commands&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; commands.getstatusoutput(&#039;ls /bin/ls&#039;)&lt;br /&gt;
(0, &#039;/bin/ls&#039;)&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; commands.getstatusoutput(&#039;cat /bin/junk&#039;)&lt;br /&gt;
(256, &#039;cat: /bin/junk: No such file or directory&#039;)&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; commands.getstatusoutput(&#039;/bin/junk&#039;)&lt;br /&gt;
(256, &#039;sh: /bin/junk: not found&#039;)&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; commands.getoutput(&#039;ls /bin/ls&#039;)&lt;br /&gt;
&#039;/bin/ls&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; commands.getstatus(&#039;/bin/ls&#039;)&lt;br /&gt;
&#039;-rwxr-xr-x  1 root        13352 Oct 14  1994 /bin/ls&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [http://docs.python.org/library/_winreg.html Windows Registry] ===&lt;br /&gt;
&lt;br /&gt;
Note: The _winreg module has been renamed to winreg in Python 3.0.&lt;br /&gt;
&lt;br /&gt;
* 32.3. winreg – Windows registry access — Python v3.2 documentation - http://docs.python.org/py3k/library/winreg.html&lt;br /&gt;
* 34.3. _winreg – Windows registry access — Python v2.7.1 documentation - http://docs.python.org/library/_winreg.html&lt;br /&gt;
&lt;br /&gt;
Read from registry:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from _winreg import *&lt;br /&gt;
key = OpenKey(HKEY_LOCAL_MACHINE, r&#039;Software\Microsoft\Outlook Express&#039;, 0, KEY_ALL_ACCESS)&lt;br /&gt;
QueryValueEx(key, &amp;quot;InstallRoot&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Write to registry:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
keyVal = r&#039;Software\Microsoft\Internet Explorer\Main&#039;&lt;br /&gt;
try:&lt;br /&gt;
    key = OpenKey(HKEY_CURRENT_USER, keyVal, 0, KEY_ALL_ACCESS)&lt;br /&gt;
except:&lt;br /&gt;
    key = CreateKey(HKEY_CURRENT_USER, keyVal)&lt;br /&gt;
SetValueEx(key, &amp;quot;Start Page&amp;quot;, 0, REG_SZ, &amp;quot;http://www.blog.pythonlibrary.org/&amp;quot;)&lt;br /&gt;
CloseKey(key)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Enumerate registry keys:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from _winreg import EnumKey, HKEY_USERS&lt;br /&gt;
 &lt;br /&gt;
try:&lt;br /&gt;
    i = 0&lt;br /&gt;
    while True:&lt;br /&gt;
        subkey = EnumKey(HKEY_USERS, i)&lt;br /&gt;
        print subkey&lt;br /&gt;
        i += 1&lt;br /&gt;
except WindowsError:&lt;br /&gt;
    # WindowsError: [Errno 259] No more data is available    &lt;br /&gt;
    pass&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Another enumeration example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# File: winreg-example-1.py&lt;br /&gt;
&lt;br /&gt;
import _winreg&lt;br /&gt;
&lt;br /&gt;
explorer = _winreg.OpenKey(&lt;br /&gt;
    _winreg.HKEY_CURRENT_USER,&lt;br /&gt;
    &amp;quot;Software\\Microsoft\\Windows\\CurrentVersion\\Explorer&amp;quot;&lt;br /&gt;
    )&lt;br /&gt;
&lt;br /&gt;
# list values owned by this registry key&lt;br /&gt;
try:&lt;br /&gt;
    i = 0&lt;br /&gt;
    while 1:&lt;br /&gt;
        name, value, type = _winreg.EnumValue(explorer, i)&lt;br /&gt;
        print repr(name),&lt;br /&gt;
        i += 1&lt;br /&gt;
except WindowsError:&lt;br /&gt;
    print&lt;br /&gt;
&lt;br /&gt;
value, type = _winreg.QueryValueEx(explorer, &amp;quot;Logon User Name&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
print&lt;br /&gt;
print &amp;quot;user is&amp;quot;, repr(value)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Enable Remote Desktop Example: (by Kenneth)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from _winreg import *&lt;br /&gt;
key = OpenKey(HKEY_LOCAL_MACHINE, r&#039;SYSTEM\CurrentControlSet\Control\Terminal Server&#039;, 0, KEY_ALL_ACCESS)&lt;br /&gt;
SetValueEx(key, &amp;quot;fDenyTSConnections&amp;quot;, 0, REG_DWORD, 0)&lt;br /&gt;
ValueTypeTuple = QueryValueEx(key, &amp;quot;fDenyTSConnections&amp;quot;)   # (0, 4)&lt;br /&gt;
print(&amp;quot;Please reboot the system to complete the changes&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* Python’s _winreg: Editing the Windows Registry « The Mouse Vs. The Python - http://www.blog.pythonlibrary.org/2010/03/20/pythons-_winreg-editing-the-windows-registry/&lt;br /&gt;
&lt;br /&gt;
=== JSON ===&lt;br /&gt;
&lt;br /&gt;
JSON - http://docs.python.org/library/json.html&lt;br /&gt;
&lt;br /&gt;
ENCODING TO JSON STRING (type str)&lt;br /&gt;
&lt;br /&gt;
 import json&lt;br /&gt;
 json.dumps([&#039;foo&#039;, {&#039;bar&#039;: (&#039;baz&#039;, None, 1.0, 2)}])&lt;br /&gt;
 # &#039;[&amp;quot;foo&amp;quot;, {&amp;quot;bar&amp;quot;: [&amp;quot;baz&amp;quot;, null, 1.0, 2]}]&#039;&lt;br /&gt;
&lt;br /&gt;
compact encoding:&lt;br /&gt;
 import json&lt;br /&gt;
 json.dumps([1,2,3,{&#039;4&#039;: 5, &#039;6&#039;: 7}], separators=(&#039;,&#039;,&#039;:&#039;))&lt;br /&gt;
 # &#039;[1,2,3,{&amp;quot;4&amp;quot;:5,&amp;quot;6&amp;quot;:7}]&#039;&lt;br /&gt;
&lt;br /&gt;
Pretty printing:&lt;br /&gt;
 import json&lt;br /&gt;
 print json.dumps({&#039;4&#039;: 5, &#039;6&#039;: 7}, sort_keys=True, indent=4)&lt;br /&gt;
 # {&lt;br /&gt;
 #     &amp;quot;4&amp;quot;: 5,&lt;br /&gt;
 #     &amp;quot;6&amp;quot;: 7&lt;br /&gt;
 # }&lt;br /&gt;
&lt;br /&gt;
DECODING JSON STRING TO PYTHON LIST OR DICTIONARY OBJECT&lt;br /&gt;
&lt;br /&gt;
 import json&lt;br /&gt;
 json.loads(&#039;[&amp;quot;foo&amp;quot;, {&amp;quot;bar&amp;quot;:[&amp;quot;baz&amp;quot;, null, 1.0, 2]}]&#039;)&lt;br /&gt;
 # [u&#039;foo&#039;, {u&#039;bar&#039;: [u&#039;baz&#039;, None, 1.0, 2]}]&lt;br /&gt;
&lt;br /&gt;
Load from file:&lt;br /&gt;
 f = open(filename)&lt;br /&gt;
 j = json.load(f)&lt;br /&gt;
 print j[&amp;quot;kind&amp;quot;]  # &amp;quot;dual-controller-adapter&amp;quot;&lt;br /&gt;
 #{&lt;br /&gt;
 #   &amp;quot;kind&amp;quot;: &amp;quot;dual-controller-adapter&amp;quot;,&lt;br /&gt;
 #}&lt;br /&gt;
&lt;br /&gt;
From Command Line:&lt;br /&gt;
 echo &#039;{&amp;quot;foo&amp;quot;: &amp;quot;lorem&amp;quot;, &amp;quot;bar&amp;quot;: &amp;quot;ipsum&amp;quot;}&#039; | python -mjson.tool&lt;br /&gt;
&lt;br /&gt;
 # get value&lt;br /&gt;
 echo &#039;{&amp;quot;test&amp;quot;:1,&amp;quot;test2&amp;quot;:2}&#039; | python -c &#039;import sys,json;data=json.loads(sys.stdin.read()); print data[&amp;quot;test&amp;quot;]&#039;&lt;br /&gt;
&lt;br /&gt;
 # read large file&lt;br /&gt;
 python -c &amp;quot;import json;f=open(&#039;file.json&#039;);data=json.load(f);print json.dumps(data,indent=2)&amp;quot;&lt;br /&gt;
 python -c &amp;quot;import json;print json.dumps(json.load(open(&#039;file.json&#039;)),indent=2)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Load from web:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import httplib&lt;br /&gt;
import json&lt;br /&gt;
&lt;br /&gt;
def get_http_json(server, path):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot; This performs an HTTP GET against a server and path and returns the&lt;br /&gt;
        resulting page data.&lt;br /&gt;
&lt;br /&gt;
        server The server we&#039;re hitting, e.g. demo.com&lt;br /&gt;
        path   The path we&#039;re hitting, e.g. api/part/MA12345/&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    connection = httplib.HTTPConnection(server)&lt;br /&gt;
    try:&lt;br /&gt;
        url = &#039;http://%s/%s&#039; % (server, path)&lt;br /&gt;
        print &#039;Querying url %s&#039; % url&lt;br /&gt;
        connection.request(&#039;GET&#039;, url)&lt;br /&gt;
        response = connection.getresponse()&lt;br /&gt;
        if response.status == httplib.OK:&lt;br /&gt;
            return json.loads(response.read())&lt;br /&gt;
        else:&lt;br /&gt;
            print &#039;Unable to get %s. %s %s&#039; % (url, response.reason,&lt;br /&gt;
                    response.status)&lt;br /&gt;
            return None&lt;br /&gt;
    finally:&lt;br /&gt;
        connection.close()&lt;br /&gt;
&lt;br /&gt;
j = get_http_json(server, path)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pretty printing from the command line:&lt;br /&gt;
 echo &#039;{&amp;quot;json&amp;quot;:&amp;quot;obj&amp;quot;}&#039; | python -mjson.tool&lt;br /&gt;
 #{&lt;br /&gt;
 #   &amp;quot;json&amp;quot;: &amp;quot;obj&amp;quot;&lt;br /&gt;
 #}&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* 18.2. json — JSON encoder and decoder — Python v2.7.1 documentation - http://docs.python.org/library/json.html&lt;br /&gt;
&lt;br /&gt;
=== Sockets ===&lt;br /&gt;
&lt;br /&gt;
See [[Python/Sockets]]&lt;br /&gt;
&lt;br /&gt;
=== [http://docs.python.org/library/base64.html base64] ===&lt;br /&gt;
&lt;br /&gt;
 import base64&lt;br /&gt;
&lt;br /&gt;
Encode:&lt;br /&gt;
 encoded = base64.b64encode(&#039;data to be encoded&#039;)&lt;br /&gt;
&lt;br /&gt;
Decode:&lt;br /&gt;
 base64.b64decode(encoded)&lt;br /&gt;
&lt;br /&gt;
=== daemonize ===&lt;br /&gt;
&lt;br /&gt;
Creating a daemon the Python way « Python recipes « ActiveState Code - http://code.activestate.com/recipes/278731-creating-a-daemon-the-python-way/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import os&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
try:&lt;br /&gt;
    pid = os.fork()&lt;br /&gt;
except OSError, e:&lt;br /&gt;
    raise Exception, &amp;quot;%s [%d]&amp;quot; % (e.strerror, e.errno)&lt;br /&gt;
&lt;br /&gt;
if (pid != 0):  # parent&lt;br /&gt;
    os._exit(0)&lt;br /&gt;
&lt;br /&gt;
# create new process session&lt;br /&gt;
os.setsid()&lt;br /&gt;
&lt;br /&gt;
# redirect stdin, stdout, stderr&lt;br /&gt;
os.open(&#039;/dev/null&#039;, os.O_RDWR)&lt;br /&gt;
os.dup2(0, 1)&lt;br /&gt;
os.dup2(0, 2)&lt;br /&gt;
&lt;br /&gt;
#... tasks ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
My Solution:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import os&lt;br /&gt;
import sys&lt;br /&gt;
import signal&lt;br /&gt;
import syslog&lt;br /&gt;
&lt;br /&gt;
HUP = False&lt;br /&gt;
&lt;br /&gt;
def log(msg):&lt;br /&gt;
    syslog.syslog(str(msg))&lt;br /&gt;
syslog.openlog(&#039;[WATER]&#039;)&lt;br /&gt;
&lt;br /&gt;
def kill_signal_handler(signal, frame):&lt;br /&gt;
    log(&amp;quot;Being killed off: {0} {1}&amp;quot;.format(signal, frame))&lt;br /&gt;
    log(&amp;quot;Shutting Down!&amp;quot;)&lt;br /&gt;
    sys.exit(0)&lt;br /&gt;
signal.signal(signal.SIGTERM, kill_signal_handler)&lt;br /&gt;
signal.signal(signal.SIGALRM, kill_signal_handler)&lt;br /&gt;
&lt;br /&gt;
def hup_signal_handler(signal, frame):&lt;br /&gt;
    global HUP&lt;br /&gt;
    log(&amp;quot;Signal reload received: {0} {1}&amp;quot;.format(signal, frame))&lt;br /&gt;
    HUP=True&lt;br /&gt;
signal.signal(signal.SIGHUP, hup_signal_handler)&lt;br /&gt;
&lt;br /&gt;
def main_loop():&lt;br /&gt;
    global HUP&lt;br /&gt;
&lt;br /&gt;
    while True:&lt;br /&gt;
        #  ... handle HUP=True ...&lt;br /&gt;
&lt;br /&gt;
        # ... main code ...&lt;br /&gt;
&lt;br /&gt;
        # wait 60 seconds before we start the next loop&lt;br /&gt;
        time.sleep(60)  # signals will interrupt this&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
    log(&amp;quot;Starting Daemon...&amp;quot;)&lt;br /&gt;
    child_id = os.fork()&lt;br /&gt;
    if child_id:&lt;br /&gt;
        log(&amp;quot;Daemonized!&amp;quot;)&lt;br /&gt;
        sys.exit(0)&lt;br /&gt;
    os.setsid()&lt;br /&gt;
    # redirect stdin, stdout, stderr&lt;br /&gt;
    os.open(&#039;/dev/null&#039;, os.O_RDWR)&lt;br /&gt;
    os.dup2(0, 1)&lt;br /&gt;
    os.dup2(0, 2)&lt;br /&gt;
&lt;br /&gt;
    # write pid&lt;br /&gt;
    with open(&amp;quot;water.pid&amp;quot;, &amp;quot;w&amp;quot;) as f:&lt;br /&gt;
        f.write(str(os.getpid()))&lt;br /&gt;
&lt;br /&gt;
    while True:&lt;br /&gt;
        try:&lt;br /&gt;
            main_loop()&lt;br /&gt;
        except Exception as e:&lt;br /&gt;
            log(&amp;quot;Critical Failure Caught: %s&amp;quot; % str(e))&lt;br /&gt;
            log(&amp;quot;Critical Failure - Restarting!&amp;quot;)&lt;br /&gt;
            time.sleep(30)&lt;br /&gt;
            #raise e&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 ln -s /opt/pyton27/bin/python pyton-water&lt;br /&gt;
 ./python-water water.py&lt;br /&gt;
 killall python-water&lt;br /&gt;
&lt;br /&gt;
==== fork ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import os&lt;br /&gt;
import sys&lt;br /&gt;
import time&lt;br /&gt;
&lt;br /&gt;
child_id = os.fork()&lt;br /&gt;
if child_id:&lt;br /&gt;
  print &amp;quot;parent exiting&amp;quot;&lt;br /&gt;
  sys.exit(0)&lt;br /&gt;
&lt;br /&gt;
while True:&lt;br /&gt;
    time.sleep(3)&lt;br /&gt;
    print &amp;quot;child&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For windows, to hide the console, see [[#Hide Console]]&lt;br /&gt;
&lt;br /&gt;
=== csv ===&lt;br /&gt;
&lt;br /&gt;
13.1. csv — CSV File Reading and Writing — Python v2.7.2 documentation - http://docs.python.org/library/csv.html&lt;br /&gt;
&lt;br /&gt;
Read:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import csv&lt;br /&gt;
spamReader = csv.reader(open(&#039;eggs.csv&#039;, &#039;rb&#039;), delimiter=&#039; &#039;, quotechar=&#039;|&#039;)&lt;br /&gt;
for row in spamReader:&lt;br /&gt;
  print &#039;, &#039;.join(row)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Write:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import csv&lt;br /&gt;
spamWriter = csv.writer(open(&#039;eggs.csv&#039;, &#039;wb&#039;), delimiter=&#039; &#039;,&lt;br /&gt;
    quotechar=&#039;|&#039;, quoting=csv.QUOTE_MINIMAL)&lt;br /&gt;
spamWriter.writerow([&#039;Spam&#039;] * 5 + [&#039;Baked Beans&#039;])&lt;br /&gt;
spamWriter.writerow([&#039;Spam&#039;, &#039;Lovely Spam&#039;, &#039;Wonderful Spam&#039;])&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== SQLite ===&lt;br /&gt;
&lt;br /&gt;
11.13. sqlite3 — DB-API 2.0 interface for SQLite databases — Python v2.7.2 documentation - http://docs.python.org/library/sqlite3.html&lt;br /&gt;
&lt;br /&gt;
sqlite3 - New in version 2.5.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import sqlite3&lt;br /&gt;
&lt;br /&gt;
conn = sqlite3.connect(&#039;/tmp/example&#039;)&lt;br /&gt;
&lt;br /&gt;
c = conn.cursor()&lt;br /&gt;
&lt;br /&gt;
# Create table&lt;br /&gt;
c.execute(&#039;&#039;&#039;create table stocks&lt;br /&gt;
(date text, trans text, symbol text,&lt;br /&gt;
 qty real, price real)&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
# Insert a row of data&lt;br /&gt;
c.execute(&amp;quot;&amp;quot;&amp;quot;insert into stocks&lt;br /&gt;
          values (&#039;2006-01-05&#039;,&#039;BUY&#039;,&#039;RHAT&#039;,100,35.14)&amp;quot;&amp;quot;&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
# Show affected row count&lt;br /&gt;
print c.rowcount&lt;br /&gt;
&lt;br /&gt;
# Save (commit) the changes&lt;br /&gt;
conn.commit()&lt;br /&gt;
&lt;br /&gt;
# We can also close the cursor if we are done with it&lt;br /&gt;
c.close()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
parameter substitution:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Never do this -- insecure!&lt;br /&gt;
symbol = &#039;IBM&#039;&lt;br /&gt;
c.execute(&amp;quot;... where symbol = &#039;%s&#039;&amp;quot; % symbol)&lt;br /&gt;
&lt;br /&gt;
# Do this instead&lt;br /&gt;
t = (symbol,)&lt;br /&gt;
c.execute(&#039;select * from stocks where symbol=?&#039;, t)&lt;br /&gt;
c.execute(&#039;select * from stocks where symbol=?&#039;, (symbol,))&lt;br /&gt;
&lt;br /&gt;
# Larger example&lt;br /&gt;
for t in [(&#039;2006-03-28&#039;, &#039;BUY&#039;, &#039;IBM&#039;, 1000, 45.00),&lt;br /&gt;
          (&#039;2006-04-05&#039;, &#039;BUY&#039;, &#039;MSOFT&#039;, 1000, 72.00),&lt;br /&gt;
          (&#039;2006-04-06&#039;, &#039;SELL&#039;, &#039;IBM&#039;, 500, 53.00),&lt;br /&gt;
         ]:&lt;br /&gt;
    c.execute(&#039;insert into stocks values (?,?,?,?,?)&#039;, t)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
select results:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
c = conn.cursor()&lt;br /&gt;
c.execute(&#039;select * from stocks order by price&#039;)&lt;br /&gt;
&lt;br /&gt;
for row in c:&lt;br /&gt;
  print row  # row is a tuple&lt;br /&gt;
&lt;br /&gt;
# OR (but not both)&lt;br /&gt;
&lt;br /&gt;
rows = c.fetchall()    # rows is list of tuples&lt;br /&gt;
print len(rows)&lt;br /&gt;
for row in rows:&lt;br /&gt;
  print row&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Show which version of sqlite3: [http://zetcode.com/db/sqlitepythontutorial/]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/python&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&lt;br /&gt;
import sqlite3 as lite&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
con = None&lt;br /&gt;
&lt;br /&gt;
try:&lt;br /&gt;
    con = lite.connect(&#039;test.db&#039;)&lt;br /&gt;
&lt;br /&gt;
    cur = con.cursor()&lt;br /&gt;
    cur.execute(&#039;SELECT SQLITE_VERSION()&#039;)&lt;br /&gt;
&lt;br /&gt;
    data = cur.fetchone()&lt;br /&gt;
&lt;br /&gt;
    print &amp;quot;SQLite version: %s&amp;quot; % data&lt;br /&gt;
&lt;br /&gt;
except lite.Error, e:&lt;br /&gt;
&lt;br /&gt;
    print &amp;quot;Error %s:&amp;quot; % e.args[0]&lt;br /&gt;
    sys.exit(1)&lt;br /&gt;
&lt;br /&gt;
finally:&lt;br /&gt;
&lt;br /&gt;
    if con:&lt;br /&gt;
        con.close()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Or simply: [http://stackoverflow.com/questions/1545479/force-python-to-forego-native-sqlite3-and-use-the-installed-latest-sqlite3-ver]&lt;br /&gt;
 # echo -e &amp;quot;import sqlite3\nprint sqlite3.sqlite_version_info&amp;quot; | python&lt;br /&gt;
 (3, 3, 6)&lt;br /&gt;
&lt;br /&gt;
=== MySQL Database ===&lt;br /&gt;
&lt;br /&gt;
Ubuntu packages:&lt;br /&gt;
* python-mysqldb - Python interface to MySQL&lt;br /&gt;
* python-mysql.connector - pure Python implementation of MySQL Client/Server protocol&lt;br /&gt;
&lt;br /&gt;
 apt-get install python-mysqldb&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; import _mysql&lt;br /&gt;
&lt;br /&gt;
 apt-get install python-mysql.connector&lt;br /&gt;
 &lt;br /&gt;
PIP:&lt;br /&gt;
* https://pypi.python.org/pypi/MySQL-python&lt;br /&gt;
* https://pypi.python.org/pypi/mysqlclient&lt;br /&gt;
&lt;br /&gt;
 pip install MySQL-python&lt;br /&gt;
&lt;br /&gt;
 pip install mysqlclient&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
_mysql - http://mysql-python.sourceforge.net/MySQLdb.html&lt;br /&gt;
&lt;br /&gt;
 apt-get install python-mysqldb&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import _mysql&lt;br /&gt;
&lt;br /&gt;
db=_mysql.connect(host=&amp;quot;localhost&amp;quot;,user=&amp;quot;user&amp;quot;,&lt;br /&gt;
                  passwd=&amp;quot;pass&amp;quot;,db=&amp;quot;db&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
db.query(&amp;quot;&amp;quot;&amp;quot;SELECT spam, eggs, sausage FROM breakfast&lt;br /&gt;
         WHERE price &amp;lt; 5&amp;quot;&amp;quot;&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
r=db.store_result()&lt;br /&gt;
# ...or...&lt;br /&gt;
r=db.use_result()&lt;br /&gt;
&lt;br /&gt;
row = r.fetch_row()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== couchdb ===&lt;br /&gt;
&lt;br /&gt;
Getting started with couchdb-python — couchdb-python v0.8 documentation - http://packages.python.org/CouchDB/getting-started.html&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
couch = couchdb.Server(&#039;http://127.0.0.1:5984/&#039;)&lt;br /&gt;
&lt;br /&gt;
# database&lt;br /&gt;
db = couch.create(&#039;test&#039;) # create new&lt;br /&gt;
db = couch[&#039;mydb&#039;] # or get existing&lt;br /&gt;
&lt;br /&gt;
# print databases:&lt;br /&gt;
for db in couch:&lt;br /&gt;
  print db&lt;br /&gt;
&lt;br /&gt;
doc = {&#039;foo&#039;: &#039;bar&#039;}&lt;br /&gt;
doc_id, doc_rev = db.save(doc)&lt;br /&gt;
# (u&#039;9278f7691c3421227a9f8436540008f9&#039;, u&#039;1-4c6114c65e295552ab1019e2b046b10e&#039;)&lt;br /&gt;
# note: this also updates doc with _rev and _id&lt;br /&gt;
doc = db[&#039;9278f7691c3421227a9f8436540008f9&#039;]&lt;br /&gt;
&lt;br /&gt;
# better to create a document using an id you want, instead of the randomly generated one&lt;br /&gt;
db[doc.id] = doc  # this will write immediately to the database&lt;br /&gt;
&lt;br /&gt;
# print all docs:&lt;br /&gt;
for id in db:&lt;br /&gt;
  print id&lt;br /&gt;
&lt;br /&gt;
# delete doc&lt;br /&gt;
db.delete(doc)&lt;br /&gt;
&lt;br /&gt;
# delete database&lt;br /&gt;
couch.delete(&#039;test&#039;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Search database:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# show all records&lt;br /&gt;
map_fun = &#039;&#039;&#039;function(doc) { emit(doc.name, null); }&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
# row = &amp;lt;Row id=u&#039;12341234123412341234&#039;, key=None, value=None&amp;gt;&lt;br /&gt;
# emit(key, value) - returns the values for key and value&lt;br /&gt;
&lt;br /&gt;
map_fun = &#039;&#039;&#039;&lt;br /&gt;
function(doc) {&lt;br /&gt;
  if (doc.username == &#039;virt-01&#039;)&lt;br /&gt;
     emit(doc.username, null);&lt;br /&gt;
}&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
# row = &amp;lt;Row id=u&#039;12341234123412341234&#039;, key=None, value=None&amp;gt;&lt;br /&gt;
for row in db.query(map_fun):&lt;br /&gt;
  print row.id&lt;br /&gt;
&lt;br /&gt;
for row in db.query(map_fun, descending=True):&lt;br /&gt;
  print row.id&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
couchdb-python - CouchDB Python Library - Google Project Hosting - http://code.google.com/p/couchdb-python/&lt;br /&gt;
&lt;br /&gt;
Installation:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir -p ~/.src ; cd ~/.src&lt;br /&gt;
wget http://pypi.python.org/packages/source/C/CouchDB/CouchDB-0.8.tar.gz#md5=e32b39e459e1fa2586ea252712a11a59&lt;br /&gt;
tar -zvxf CouchDB-0.8.tar.gz&lt;br /&gt;
cd CouchDB-0.8&lt;br /&gt;
python setup.py install&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Test:&lt;br /&gt;
 echo &amp;quot;import couchdb&amp;quot; | python&lt;br /&gt;
&lt;br /&gt;
=== nose ===&lt;br /&gt;
&lt;br /&gt;
nose: nose extends unittest to make testing easier&lt;br /&gt;
&lt;br /&gt;
nose : Python Package Index - http://pypi.python.org/pypi/nose&lt;br /&gt;
&lt;br /&gt;
Install:&lt;br /&gt;
 mkdir -p ~/.src ; cd ~/.src&lt;br /&gt;
 wget http://pypi.python.org/packages/source/n/nose/nose-1.1.2.tar.gz#md5=144f237b615e23f21f6a50b2183aa817&lt;br /&gt;
 tar -zvxf nose-1.1.2.tar.gz&lt;br /&gt;
 cd nose-1.1.2&lt;br /&gt;
 sudo python setup.py install&lt;br /&gt;
&lt;br /&gt;
skeleton:&lt;br /&gt;
 mkdir skeleton&lt;br /&gt;
 cd skeleton&lt;br /&gt;
 mkdir bin NAME tests docs&lt;br /&gt;
 touch NAME/__init__.py&lt;br /&gt;
 touch tests/__init__.py&lt;br /&gt;
 touch tests/NAME_tests.py&lt;br /&gt;
&lt;br /&gt;
nose test skeleton:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# tests/NAME_tests.py&lt;br /&gt;
from nose.tools import *&lt;br /&gt;
import klib&lt;br /&gt;
&lt;br /&gt;
def setup():&lt;br /&gt;
    print &amp;quot;SETUP!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
def teardown():&lt;br /&gt;
    print &amp;quot;TEAR DOWN!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
def test_basic():&lt;br /&gt;
    print &amp;quot;I RAN!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# def test_something_else():&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
 nosetests&lt;br /&gt;
&lt;br /&gt;
See Also:&lt;br /&gt;
* [[#doctest]]&lt;br /&gt;
* [[#unittest]]&lt;br /&gt;
&lt;br /&gt;
=== pydoc ===&lt;br /&gt;
&lt;br /&gt;
25.1. pydoc — Documentation generator and online help system — Python v2.7.2 documentation - http://docs.python.org/library/pydoc.html&lt;br /&gt;
&lt;br /&gt;
pydoc - The pydoc module automatically generates documentation from Python modules.&lt;br /&gt;
&lt;br /&gt;
pydoc - same as &#039;import [library], help([library])&#039;&lt;br /&gt;
 $ pydoc [library]&lt;br /&gt;
&lt;br /&gt;
Note: lists some special &#039;module metadata variables&#039; separately (e.g. version, author).&lt;br /&gt;
&lt;br /&gt;
special pydoc recognized metadata sections:&lt;br /&gt;
 __version__&lt;br /&gt;
 __author__&lt;br /&gt;
 __credits__&lt;br /&gt;
 __date__&lt;br /&gt;
&lt;br /&gt;
==== pydoc function module ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Help on package klib:&lt;br /&gt;
&lt;br /&gt;
NAME&lt;br /&gt;
    klib - This is the name&lt;br /&gt;
&lt;br /&gt;
FILE&lt;br /&gt;
    /root/klib/klib/__init__.py&lt;br /&gt;
&lt;br /&gt;
DESCRIPTION&lt;br /&gt;
    These are module doc strings&lt;br /&gt;
        that give helpful details&lt;br /&gt;
&lt;br /&gt;
PACKAGE CONTENTS&lt;br /&gt;
    markone&lt;br /&gt;
&lt;br /&gt;
FUNCTIONS&lt;br /&gt;
    func1()&lt;br /&gt;
        This is a doc string&lt;br /&gt;
        for func1&lt;br /&gt;
&lt;br /&gt;
DATA&lt;br /&gt;
    PI = 3.141&lt;br /&gt;
    __all__ = [&#039;func1&#039;, &#039;PI&#039;]&lt;br /&gt;
    __author__ = &#039;Kenneth &amp;lt;kenneth@oeey.com&amp;gt;&#039;&lt;br /&gt;
    __copyright__ = &#039;Copyright 2007, The Project&#039;&lt;br /&gt;
    __credits__ = &#039;Credits go to me&#039;&lt;br /&gt;
    __date__ = &#039;26 February 2001&#039;&lt;br /&gt;
    __email__ = &#039;ken@oeey.com&#039;&lt;br /&gt;
    __license__ = &#039;GPL&#039;&lt;br /&gt;
    __maintainer__ = &#039;Ken&#039;&lt;br /&gt;
    __status__ = &#039;Production&#039;&lt;br /&gt;
    __version__ = &#039;$Revision: 83492 $&#039;&lt;br /&gt;
&lt;br /&gt;
VERSION&lt;br /&gt;
    83492&lt;br /&gt;
&lt;br /&gt;
DATE&lt;br /&gt;
    26 February 2001&lt;br /&gt;
&lt;br /&gt;
AUTHOR&lt;br /&gt;
    Kenneth &amp;lt;kenneth@oeey.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
CREDITS&lt;br /&gt;
    Credits go to me&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Source:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
This is the name&lt;br /&gt;
&lt;br /&gt;
These are module doc strings&lt;br /&gt;
    that give helpful details&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#__version__ = &amp;quot;1.0&amp;quot;&lt;br /&gt;
__version__ = &amp;quot;$Revision: 83492 $&amp;quot;&lt;br /&gt;
__author__ = &amp;quot;Kenneth &amp;lt;kenneth@oeey.com&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
__date__ = &amp;quot;26 February 2001&amp;quot;&lt;br /&gt;
__credits__ = &amp;quot;Credits go to me&amp;quot;&lt;br /&gt;
&lt;br /&gt;
__all__ = [&#039;func1&#039;, &#039;PI&#039;]&lt;br /&gt;
&lt;br /&gt;
PI = 3.141&lt;br /&gt;
&lt;br /&gt;
__copyright__ = &#039;hello license&#039;&lt;br /&gt;
__license__ = &amp;quot;GPL&amp;quot;&lt;br /&gt;
__copyright__ = &amp;quot;Copyright 2007, The Project&amp;quot;&lt;br /&gt;
__maintainer__ = &amp;quot;Ken&amp;quot;&lt;br /&gt;
__email__ = &amp;quot;ken@oeey.com&amp;quot;&lt;br /&gt;
__status__ = &amp;quot;Production&amp;quot;&lt;br /&gt;
&lt;br /&gt;
def func1():&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    This is a doc string&lt;br /&gt;
    for func1&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== pydoc class module ====&lt;br /&gt;
&lt;br /&gt;
Sample:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Help on module class_pydoc:&lt;br /&gt;
&lt;br /&gt;
NAME&lt;br /&gt;
    class_pydoc - This is the name&lt;br /&gt;
&lt;br /&gt;
FILE&lt;br /&gt;
    /root/class_pydoc.py&lt;br /&gt;
&lt;br /&gt;
DESCRIPTION&lt;br /&gt;
    These are module doc strings&lt;br /&gt;
        that give helpful details&lt;br /&gt;
&lt;br /&gt;
CLASSES&lt;br /&gt;
    Toad&lt;br /&gt;
&lt;br /&gt;
    class Toad&lt;br /&gt;
     |  doc string for object&lt;br /&gt;
     |&lt;br /&gt;
     |  Methods defined here:&lt;br /&gt;
     |&lt;br /&gt;
     |  __init___(self, name)&lt;br /&gt;
     |      Constructor&lt;br /&gt;
     |&lt;br /&gt;
     |  instance_function(self)&lt;br /&gt;
     |      Instance Function&lt;br /&gt;
     |&lt;br /&gt;
     |  ----------------------------------------------------------------------&lt;br /&gt;
     |  Class methods defined here:&lt;br /&gt;
     |&lt;br /&gt;
     |  class_function(cls) from __builtin__.classobj&lt;br /&gt;
     |      Class Function&lt;br /&gt;
     |&lt;br /&gt;
     |  ----------------------------------------------------------------------&lt;br /&gt;
     |  Data and other attributes defined here:&lt;br /&gt;
     |&lt;br /&gt;
     |  my_class_attribute = &#039;sample class attribute&#039;&lt;br /&gt;
&lt;br /&gt;
DATA&lt;br /&gt;
    PI = 3.141&lt;br /&gt;
    __author__ = &#039;Kenneth &amp;lt;kenneth@oeey.com&amp;gt;&#039;&lt;br /&gt;
    __copyright__ = &#039;Copyright 2007, The Project&#039;&lt;br /&gt;
    __credits__ = &#039;Credits go to me&#039;&lt;br /&gt;
    __date__ = &#039;26 February 2001&#039;&lt;br /&gt;
    __email__ = &#039;ken@oeey.com&#039;&lt;br /&gt;
    __license__ = &#039;GPL&#039;&lt;br /&gt;
    __maintainer__ = &#039;Ken&#039;&lt;br /&gt;
    __status__ = &#039;Production&#039;&lt;br /&gt;
    __version__ = &#039;1.0&#039;&lt;br /&gt;
&lt;br /&gt;
VERSION&lt;br /&gt;
    1.0&lt;br /&gt;
&lt;br /&gt;
DATE&lt;br /&gt;
    26 February 2001&lt;br /&gt;
&lt;br /&gt;
AUTHOR&lt;br /&gt;
    Kenneth &amp;lt;kenneth@oeey.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
CREDITS&lt;br /&gt;
    Credits go to me&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Code:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
This is the name&lt;br /&gt;
&lt;br /&gt;
These are module doc strings&lt;br /&gt;
    that give helpful details&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
__version__ = &amp;quot;1.0&amp;quot;&lt;br /&gt;
#__version__ = &amp;quot;$Revision: 83492 $&amp;quot;&lt;br /&gt;
__author__ = &amp;quot;Kenneth &amp;lt;kenneth@oeey.com&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
__date__ = &amp;quot;26 February 2001&amp;quot;&lt;br /&gt;
__credits__ = &amp;quot;Credits go to me&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#__all__ = [&#039;func1&#039;, &#039;PI&#039;]&lt;br /&gt;
&lt;br /&gt;
PI = 3.141&lt;br /&gt;
&lt;br /&gt;
__copyright__ = &#039;hello license&#039;&lt;br /&gt;
__license__ = &amp;quot;GPL&amp;quot;&lt;br /&gt;
__copyright__ = &amp;quot;Copyright 2007, The Project&amp;quot;&lt;br /&gt;
__maintainer__ = &amp;quot;Ken&amp;quot;&lt;br /&gt;
__email__ = &amp;quot;ken@oeey.com&amp;quot;&lt;br /&gt;
__status__ = &amp;quot;Production&amp;quot;&lt;br /&gt;
&lt;br /&gt;
class Toad:&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot; doc string for object &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    my_class_attribute = &#039;sample class attribute&#039;&lt;br /&gt;
&lt;br /&gt;
    def __init___(self, name):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot; Constructor &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    def instance_function(self):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot; Instance Function &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    @classmethod&lt;br /&gt;
    def class_function(cls):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot; Class Function &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== username ===&lt;br /&gt;
&lt;br /&gt;
User ID:&lt;br /&gt;
 os.getuid()&lt;br /&gt;
&lt;br /&gt;
User Name:&lt;br /&gt;
 # fails it stdin piped to program&lt;br /&gt;
 os.getlogin()&lt;br /&gt;
&lt;br /&gt;
User Name:&lt;br /&gt;
 import sys&lt;br /&gt;
 import pwd&lt;br /&gt;
 def get_username():&lt;br /&gt;
     return pwd.getpwuid( os.getuid() )[ 0 ]&lt;br /&gt;
&lt;br /&gt;
Environment:&lt;br /&gt;
 os.environ[&#039;USER&#039;]&lt;br /&gt;
&lt;br /&gt;
=== hostname ===&lt;br /&gt;
&lt;br /&gt;
 import socket&lt;br /&gt;
 print(socket.gethostname())&lt;br /&gt;
&lt;br /&gt;
 os.uname()[1]&lt;br /&gt;
&lt;br /&gt;
 hostname = os.system(&#039;hostname&#039;)&lt;br /&gt;
&lt;br /&gt;
=== Networking ===&lt;br /&gt;
&lt;br /&gt;
==== Get Hostname ====&lt;br /&gt;
&lt;br /&gt;
 import socket&lt;br /&gt;
 print(socket.gethostname())&lt;br /&gt;
&lt;br /&gt;
==== Convert hostname to ip address ====&lt;br /&gt;
&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; socket.gethostbyaddr(&#039;demo&#039;)&lt;br /&gt;
 (&#039;demo.oeey.com&#039;, [], [&#039;10.10.10.10&#039;])&lt;br /&gt;
&lt;br /&gt;
/usr/local/bin/whatip: (or nametoip)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
# whatip - convert hostname to ip address&lt;br /&gt;
# author: Kenneth Burgener &amp;lt;kenneth@oeey.com&amp;gt; (FEB 2012)&lt;br /&gt;
#&lt;br /&gt;
&lt;br /&gt;
import socket&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
if len(sys.argv) != 2:&lt;br /&gt;
  print &amp;quot;Convert Hostname to IP Address&amp;quot;&lt;br /&gt;
  print &amp;quot;Usage: %s HOSTNAME&amp;quot; % sys.argv[0].split(&#039;/&#039;)[-1]&lt;br /&gt;
  sys.exit(1)&lt;br /&gt;
&lt;br /&gt;
hostname = sys.argv[1]&lt;br /&gt;
try:&lt;br /&gt;
  result = socket.gethostbyaddr(hostname)&lt;br /&gt;
  print result[2][0]&lt;br /&gt;
except (socket.gaierror, socket.herror) as e:&lt;br /&gt;
  print &amp;quot;Error: Unable to resolve &#039;%s&#039;&amp;quot; % hostname&lt;br /&gt;
  sys.exit(1)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Get Public IP Address ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)&lt;br /&gt;
s.connect((&amp;quot;gmail.com&amp;quot;,80))&lt;br /&gt;
print(s.getsockname()[0])&lt;br /&gt;
s.close()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
networking - Finding local IP addresses using Python&#039;s stdlib - Stack Overflow - http://stackoverflow.com/questions/166506/finding-local-ip-addresses-using-pythons-stdlib&lt;br /&gt;
&lt;br /&gt;
==== Python Network Server ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/python           # This is server.py file&lt;br /&gt;
&lt;br /&gt;
import socket               # Import socket module&lt;br /&gt;
&lt;br /&gt;
s = socket.socket()         # Create a socket object&lt;br /&gt;
host = socket.gethostname() # Get local machine name&lt;br /&gt;
port = 12345                # Reserve a port for your service.&lt;br /&gt;
s.bind((host, port))        # Bind to the port&lt;br /&gt;
&lt;br /&gt;
s.listen(5)                 # Now wait for client connection.&lt;br /&gt;
while True:&lt;br /&gt;
   c, addr = s.accept()     # Establish connection with client.&lt;br /&gt;
   print &#039;Got connection from&#039;, addr&lt;br /&gt;
   c.send(&#039;Thank you for connecting&#039;)&lt;br /&gt;
   c.close()                # Close the connection&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Source: http://www.tutorialspoint.com/python/python_networking.htm&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* 17.2. socket — Low-level networking interface — Python v2.7.5 documentation - http://docs.python.org/2/library/socket.html&lt;br /&gt;
&lt;br /&gt;
==== Python Network Client ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/python           # This is client.py file&lt;br /&gt;
&lt;br /&gt;
import socket               # Import socket module&lt;br /&gt;
&lt;br /&gt;
s = socket.socket()         # Create a socket object&lt;br /&gt;
host = socket.gethostname() # Get local machine name&lt;br /&gt;
port = 12345                # Reserve a port for your service.&lt;br /&gt;
&lt;br /&gt;
s.connect((host, port))&lt;br /&gt;
print s.recv(1024)&lt;br /&gt;
s.close                     # Close the socket when done&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Source: http://www.tutorialspoint.com/python/python_networking.htm&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* 17.2. socket — Low-level networking interface — Python v2.7.5 documentation - http://docs.python.org/2/library/socket.html&lt;br /&gt;
&lt;br /&gt;
=== Run Library Module as Script ===&lt;br /&gt;
&lt;br /&gt;
Run python with -m option:&lt;br /&gt;
 -m mod : run library module as a script (terminates option list)&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
 cat [json_file] | python -m json.tool&lt;br /&gt;
 # same as:&lt;br /&gt;
 cat [json_file] | python /opt/python26/lib/python2.6/json/tool.py&lt;br /&gt;
&lt;br /&gt;
Good for when library is buried deep in the library directories&lt;br /&gt;
&lt;br /&gt;
=== Hex ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hex(10)  # print integer as hex string&lt;br /&gt;
&#039;0xa&#039;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; sys.hexversion  # python version as integer&lt;br /&gt;
33817584&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hex(sys.hexversion)  # python version as hex&lt;br /&gt;
&#039;0x20403f0&#039;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; print &amp;quot;0x%08x&amp;quot; % sys.hexversion  # python version as hex&lt;br /&gt;
&#039;0x20403f0&#039;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; int(&#039;0xa&#039;, 16)  # hex string to integer&lt;br /&gt;
10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; int(&#039;0a&#039;, 16)  # hex string to integer&lt;br /&gt;
10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; int(&#039;0xa&#039;, 0)  # hex string to integer auto detected du to &#039;0x&#039;&lt;br /&gt;
10&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Binary ===&lt;br /&gt;
&lt;br /&gt;
Integer to Binary String with Negative Number Support: (2&#039;s complement)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# source: http://www.gossamer-threads.com/lists/python/python/645216&lt;br /&gt;
def bin(x):&lt;br /&gt;
    if x &amp;lt; -32768 or x &amp;gt; 65535:&lt;br /&gt;
        raise Exception(&amp;quot;Out of Range Error: %d&amp;quot; % x)&lt;br /&gt;
    if x &amp;lt; 0:&lt;br /&gt;
        x = 65535 + x + 1&lt;br /&gt;
    bin_str = &#039;&#039;&lt;br /&gt;
    bin_str += &#039;&#039;.join(x &amp;amp; (1 &amp;lt;&amp;lt; i) and &#039;1&#039; or &#039;0&#039; for i in range(15, 11, -1))&lt;br /&gt;
    bin_str += &#039; &#039;&lt;br /&gt;
    bin_str += &#039;&#039;.join(x &amp;amp; (1 &amp;lt;&amp;lt; i) and &#039;1&#039; or &#039;0&#039; for i in range(11, 7, -1))&lt;br /&gt;
    bin_str += &#039; &#039;&lt;br /&gt;
    bin_str += &#039;&#039;.join(x &amp;amp; (1 &amp;lt;&amp;lt; i) and &#039;1&#039; or &#039;0&#039; for i in range(7, 3, -1))&lt;br /&gt;
    bin_str += &#039; &#039;&lt;br /&gt;
    bin_str += &#039;&#039;.join(x &amp;amp; (1 &amp;lt;&amp;lt; i) and &#039;1&#039; or &#039;0&#039; for i in range(3, -1, -1))&lt;br /&gt;
    return bin_str&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Integer to Binary String:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# source: http://www.gossamer-threads.com/lists/python/python/645216&lt;br /&gt;
def bin(x):&lt;br /&gt;
    if x &amp;lt; 0 or x &amp;gt; 65535:&lt;br /&gt;
        raise Exception(&amp;quot;Out of Range Error: %d&amp;quot; % x)&lt;br /&gt;
    bin_str = &#039;&#039;&lt;br /&gt;
    bin_str = &#039;&#039;.join(x &amp;amp; (1 &amp;lt;&amp;lt; i) and &#039;1&#039; or &#039;0&#039; for i in range(15, 7, -1))&lt;br /&gt;
    bin_str = bin_str + &#039; &#039;&lt;br /&gt;
    bin_str = bin_str + &#039;&#039;.join(x &amp;amp; (1 &amp;lt;&amp;lt; i) and &#039;1&#039; or &#039;0&#039; for i in range(7, -1, -1))&lt;br /&gt;
    return bin_str&lt;br /&gt;
&lt;br /&gt;
print bin(0)      # &#039;00000000 00000000&#039;&lt;br /&gt;
print bin(1)      # &#039;00000000 00000001&#039;&lt;br /&gt;
print bin(255)    # &#039;00000000 11111111&#039;&lt;br /&gt;
print bin(256)    # &#039;00000001 00000000&#039;&lt;br /&gt;
print bin(43690)  # &#039;10101010 10101010&#039;&lt;br /&gt;
print bin(65535)  # &#039;11111111 11111111&#039;&lt;br /&gt;
print bin(65536)  # &#039;00000000 00000000&#039; - rolled over to next set!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Integer to Binary:&lt;br /&gt;
 bin(170)  # &#039;0b10101010&#039;&lt;br /&gt;
&lt;br /&gt;
Binary to Integer:&lt;br /&gt;
 int(&#039;10101010&#039;, 2)  # 170&lt;br /&gt;
&lt;br /&gt;
=== bitwise ===&lt;br /&gt;
&lt;br /&gt;
See [[#Binary]]&lt;br /&gt;
&lt;br /&gt;
BitwiseOperators - Python Wiki - http://wiki.python.org/moin/BitwiseOperators&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
The Operators:&lt;br /&gt;
&lt;br /&gt;
x &amp;lt;&amp;lt; y&lt;br /&gt;
    Returns x with the bits shifted to the left by y places (and new bits on the right-hand-side are zeros). This is the same as multiplying x by 2**y. &lt;br /&gt;
x &amp;gt;&amp;gt; y&lt;br /&gt;
    Returns x with the bits shifted to the right by y places. This is the same as //&#039;ing x by 2**y. &lt;br /&gt;
x &amp;amp; y&lt;br /&gt;
    AND - Does a &amp;quot;bitwise and&amp;quot;. Each bit of the output is 1 if the corresponding bit of x AND of y is 1, otherwise it&#039;s 0. &lt;br /&gt;
x | y&lt;br /&gt;
    OR - Does a &amp;quot;bitwise or&amp;quot;. Each bit of the output is 0 if the corresponding bit of x AND of y is 0, otherwise it&#039;s 1. &lt;br /&gt;
~ x&lt;br /&gt;
    Returns the complement of x - the number you get by switching each 1 for a 0 and each 0 for a 1. This is the same as -x - 1. &lt;br /&gt;
x ^ y&lt;br /&gt;
    XOR - Does a &amp;quot;bitwise exclusive or&amp;quot;. Each bit of the output is the same as the corresponding bit in x if that bit in y is 0, and it&#039;s the complement of the bit in x if that bit in y is 1. &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Script Path ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
    # Change directory to where this script lives so we can find relative&lt;br /&gt;
    # paths from here regardless of where the working directory was when we&lt;br /&gt;
    # ran the script.&lt;br /&gt;
    # APP_DIR = os.path.dirname(sys.argv[0])&lt;br /&gt;
    APP_DIR = os.path.dirname(os.path.abspath(sys.argv[0))&lt;br /&gt;
    if APP_DIR:&lt;br /&gt;
        os.chdir(APP_DIR)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 normpath(path)  # Normalize path, eliminating double slashes, etc.&lt;br /&gt;
 abspath(path)   # Return an absolute path&lt;br /&gt;
&lt;br /&gt;
Path to a module: [http://stackoverflow.com/questions/247770/retrieving-python-module-path] (couldn&#039;t fine a_module)&lt;br /&gt;
 import a_module&lt;br /&gt;
 import os&lt;br /&gt;
 path = os.path.dirname(a_module.__file__)&lt;br /&gt;
&lt;br /&gt;
Path to module: [http://stackoverflow.com/questions/50499/in-python-how-do-i-get-the-path-and-name-of-the-file-that-is-currently-executin]&lt;br /&gt;
 import inspect, os&lt;br /&gt;
 print inspect.getfile(inspect.currentframe()) # script filename (usually with path)&lt;br /&gt;
 print os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) # script directory&lt;br /&gt;
&lt;br /&gt;
Even better:&lt;br /&gt;
 print os.path.realpath(__file__)&lt;br /&gt;
 print os.path.dirname(__file__)&lt;br /&gt;
 print os.path.basename(__file__)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
references:&lt;br /&gt;
* http://stackoverflow.com/questions/595305/python-path-of-script&lt;br /&gt;
&lt;br /&gt;
keywords: scriptpath script path program path pathname&lt;br /&gt;
&lt;br /&gt;
=== Singleton ===&lt;br /&gt;
&lt;br /&gt;
GLOBAL OBJECT!&lt;br /&gt;
&lt;br /&gt;
None is a singleton (Python only has one copy of None in the interpreter).&lt;br /&gt;
&lt;br /&gt;
Make your own singleton:&lt;br /&gt;
&lt;br /&gt;
override the new method like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Singleton(object):&lt;br /&gt;
    _instance = None&lt;br /&gt;
    def __new__(cls, *args, **kwargs):&lt;br /&gt;
        if not cls._instance:&lt;br /&gt;
            cls._instance = super(Singleton, cls).__new__(&lt;br /&gt;
                                cls, *args, **kwargs)&lt;br /&gt;
        return cls._instance&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
if __name__ == &#039;__main__&#039;:&lt;br /&gt;
    s1=Singleton()&lt;br /&gt;
    s2=Singleton()&lt;br /&gt;
    if(id(s1)==id(s2)):&lt;br /&gt;
        print &amp;quot;Same&amp;quot;&lt;br /&gt;
    else:&lt;br /&gt;
        print &amp;quot;Different&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Using decorator -implementation from PEP318? Implementing the singleton pattern with a decorator:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def singleton(cls):&lt;br /&gt;
    instances = {}&lt;br /&gt;
    def getinstance():&lt;br /&gt;
        if cls not in instances:&lt;br /&gt;
            instances[cls] = cls()&lt;br /&gt;
        return instances[cls]&lt;br /&gt;
    return getinstance&lt;br /&gt;
&lt;br /&gt;
@singleton&lt;br /&gt;
class MyClass:&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Python and the Singleton Pattern - Stack Overflow - http://stackoverflow.com/questions/42558/python-and-the-singleton-pattern&lt;br /&gt;
&lt;br /&gt;
=== XML ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from xml.dom.minidom import parse, parseString&lt;br /&gt;
&lt;br /&gt;
dom1 = parse(&#039;c:\\temp\\mydata.xml&#039;) # parse an XML file by name&lt;br /&gt;
&lt;br /&gt;
datasource = open(&#039;c:\\temp\\mydata.xml&#039;)&lt;br /&gt;
dom2 = parse(datasource)   # parse an open file&lt;br /&gt;
&lt;br /&gt;
dom3 = parseString(&#039;&amp;lt;myxml&amp;gt;Some data&amp;lt;empty/&amp;gt; some more data&amp;lt;/myxml&amp;gt;&#039;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pretty Print: [http://stackoverflow.com/questions/749796/pretty-printing-xml-in-python]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import xml.dom.minidom&lt;br /&gt;
&lt;br /&gt;
xml = xml.dom.minidom.parse(xml_fname) # or xml.dom.minidom.parseString(xml_string)&lt;br /&gt;
pretty_xml_as_string = xml.toprettyxml()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pretty Print with etree [http://stackoverflow.com/questions/749796/pretty-printing-xml-in-python]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import lxml.etree as etree&lt;br /&gt;
&lt;br /&gt;
x = etree.parse(&amp;quot;filename&amp;quot;)&lt;br /&gt;
print etree.tostring(x, pretty_print = True)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* 19.7. xml.dom.minidom — Lightweight DOM implementation — Python v2.7.3 documentation - http://docs.python.org/library/xml.dom.minidom.html&lt;br /&gt;
* Pretty printing XML in python - Stack Overflow - http://stackoverflow.com/questions/749796/pretty-printing-xml-in-python&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
Simply don&#039;t include self.output.startElement and self.output.endElement for elements you don&#039;t want:&lt;br /&gt;
&lt;br /&gt;
simple_filter_parser.py: (my version of [http://freegeographytools.com/2010/removin-time-data-out-of-a-gpx-or-kml-file-to-make-it-work-right-in-google-earth])&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# this parses out the time element of a gpx for Google Earth&lt;br /&gt;
import os&lt;br /&gt;
import sys&lt;br /&gt;
import optparse&lt;br /&gt;
import fnmatch&lt;br /&gt;
from sys import argv&lt;br /&gt;
import xml.sax, xml.sax.saxutils&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
class my_filter_xml(xml.sax.ContentHandler):&lt;br /&gt;
    def __init__(self, outfile, verbose=False):&lt;br /&gt;
        self.output = xml.sax.saxutils.XMLGenerator(outfile, &#039;utf-8&#039;)&lt;br /&gt;
        self.indent = 0&lt;br /&gt;
        self.ignore = False&lt;br /&gt;
        self.output.startDocument()&lt;br /&gt;
&lt;br /&gt;
    def startElement(self, name, attrs):&lt;br /&gt;
        print &amp;quot; &amp;quot; * self.indent + &amp;quot;start: &amp;quot; + name&lt;br /&gt;
        if attrs.keys():&lt;br /&gt;
            keys = &amp;quot; &amp;quot; * (self.indent + 2) + &amp;quot;attrs:&amp;quot;&lt;br /&gt;
            for key in attrs.keys():&lt;br /&gt;
                keys = keys + &amp;quot; &amp;quot; + key + &amp;quot;=&amp;quot; + attrs[key]&lt;br /&gt;
            print keys&lt;br /&gt;
        self.indent = self.indent + 2&lt;br /&gt;
        #self.output.startElement(name, {})&lt;br /&gt;
        if name == &amp;quot;time&amp;quot;:&lt;br /&gt;
            self.ignore = True&lt;br /&gt;
        #if not self.ignore:&lt;br /&gt;
        self.output.startElement(name, attrs)&lt;br /&gt;
&lt;br /&gt;
    def characters(self, ch):&lt;br /&gt;
        if ch.strip():&lt;br /&gt;
            print &amp;quot; &amp;quot; * self.indent + &amp;quot;ch: &amp;quot; + ch.strip()&lt;br /&gt;
            if not self.ignore:&lt;br /&gt;
                self.output.characters(ch)&lt;br /&gt;
        else:&lt;br /&gt;
            if not self.ignore:&lt;br /&gt;
                self.output.characters(&amp;quot;\n&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    def endElement(self, name):&lt;br /&gt;
        self.indent = self.indent - 2&lt;br /&gt;
        print &amp;quot; &amp;quot; * self.indent + &amp;quot;/end: &amp;quot; + name&lt;br /&gt;
        #if not self.ignore:&lt;br /&gt;
        self.output.endElement(name)&lt;br /&gt;
        if name == &amp;quot;time&amp;quot;:&lt;br /&gt;
            self.ignore = False&lt;br /&gt;
&lt;br /&gt;
if __name__ == &#039;__main__&#039;:&lt;br /&gt;
    source = open(&amp;quot;tracks.gpx&amp;quot;)&lt;br /&gt;
    dest = open(&amp;quot;tracks_out.gpx&amp;quot;, &#039;w+&#039;)&lt;br /&gt;
    xml.sax.parse(source, my_filter_xml(dest, True))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
fixdescriptor.py:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import os&lt;br /&gt;
import sys&lt;br /&gt;
import optparse&lt;br /&gt;
import fnmatch&lt;br /&gt;
from sys import argv&lt;br /&gt;
import xml.sax, xml.sax.saxutils&lt;br /&gt;
&lt;br /&gt;
class fix_descriptor(xml.sax.ContentHandler):&lt;br /&gt;
    def __init__(self, outfile, verbose=False):&lt;br /&gt;
        self._outfile = outfile&lt;br /&gt;
        self._verbose = verbose&lt;br /&gt;
        self.output = xml.sax.saxutils.XMLGenerator(outfile, &#039;utf-8&#039;)&lt;br /&gt;
        self._filter = [ &#039;payload&#039;,&lt;br /&gt;
                         &#039;payloads&#039;,&lt;br /&gt;
                         &#039;file-list&#039;,&lt;br /&gt;
                         &#039;file&#039;,&lt;br /&gt;
                         &#039;checksum&#039; ]&lt;br /&gt;
        self._keep = [ &#039;vib&#039;,&lt;br /&gt;
                       &#039;maintenance-mode&#039; ]&lt;br /&gt;
        self._inside = None&lt;br /&gt;
&lt;br /&gt;
    def startElement(self, name, attrs):&lt;br /&gt;
        # Certain elements are kept unchanged&lt;br /&gt;
        if name in self._keep:&lt;br /&gt;
            if self._verbose:&lt;br /&gt;
                print &#039;%s element start found&#039; % (name)&lt;br /&gt;
            self.output.startElement(name, {})&lt;br /&gt;
            if name == &#039;maintenance-mode&#039;:&lt;br /&gt;
                if self._verbose:&lt;br /&gt;
                    print &#039;inside maintenance-mode&#039;&lt;br /&gt;
                self._inside = name&lt;br /&gt;
            return&lt;br /&gt;
        # Other elements are filtered (removed)&lt;br /&gt;
        elif name in self._filter:&lt;br /&gt;
            if self._verbose:&lt;br /&gt;
                print &#039;%s element start found&#039; % (name)&lt;br /&gt;
            self._inside = name&lt;br /&gt;
            return&lt;br /&gt;
        self.output.startElement(name, attrs)&lt;br /&gt;
&lt;br /&gt;
    def characters(self, ch):&lt;br /&gt;
        if self._inside == &#039;maintenance-mode&#039;:&lt;br /&gt;
            if self._verbose:&lt;br /&gt;
                print &#039;new content for maintenance-mode&#039;&lt;br /&gt;
            self.output.characters(&#039;false&#039;)&lt;br /&gt;
        elif self._inside not in self._filter:&lt;br /&gt;
            self.output.characters(ch)&lt;br /&gt;
&lt;br /&gt;
    def endElement(self, name):&lt;br /&gt;
        # If it&#039;s not a checksum element, only print it&lt;br /&gt;
        if name in self._filter + self._keep:&lt;br /&gt;
            self._inside = None&lt;br /&gt;
            if self._verbose:&lt;br /&gt;
                print &#039;%s element end found&#039; % (name)&lt;br /&gt;
            if name in self._filter:&lt;br /&gt;
                return&lt;br /&gt;
        self.output.endElement(name)&lt;br /&gt;
&lt;br /&gt;
if __name__ == &#039;__main__&#039;:&lt;br /&gt;
    #&lt;br /&gt;
    parser = optparse.OptionParser(usage=&#039;%prog ...&#039;)&lt;br /&gt;
    parser.add_option(&#039;-v&#039;, &#039;--verbose&#039;,&lt;br /&gt;
                       action=&#039;store_true&#039;, default=False,&lt;br /&gt;
                       help=&#039;Print more information.&#039;)&lt;br /&gt;
    parser.add_option(&#039;--input-xml&#039;,&lt;br /&gt;
                       type=&#039;str&#039;, default=&#039;descriptor.xml&#039;,&lt;br /&gt;
                       help=&#039;Name of input XML [default: %default]&#039;)&lt;br /&gt;
    parser.add_option(&#039;--output-xml&#039;,&lt;br /&gt;
                       type=&#039;str&#039;, default=&#039;fixed_descriptor.xml&#039;,&lt;br /&gt;
                       help=&#039;Name of output XML [default: %default]&#039;)&lt;br /&gt;
    opts, args = parser.parse_args(argv[1:])&lt;br /&gt;
    source = open(opts.input_xml)&lt;br /&gt;
    dest = open(opts.output_xml, &#039;w+&#039;)&lt;br /&gt;
    xml.sax.parse(source, fix_descriptor(dest, opts.verbose))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--&lt;br /&gt;
&lt;br /&gt;
Simple read and output parsing:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import os&lt;br /&gt;
import sys&lt;br /&gt;
import optparse&lt;br /&gt;
import fnmatch&lt;br /&gt;
from sys import argv&lt;br /&gt;
import xml.sax, xml.sax.saxutils&lt;br /&gt;
&lt;br /&gt;
class fix_descriptor(xml.sax.ContentHandler):&lt;br /&gt;
    def __init__(self, outfile, verbose=False):&lt;br /&gt;
        self._outfile = outfile&lt;br /&gt;
        self._verbose = verbose&lt;br /&gt;
        self.output = xml.sax.saxutils.XMLGenerator(outfile, &#039;utf-8&#039;)&lt;br /&gt;
        self._inside = None&lt;br /&gt;
&lt;br /&gt;
    def startElement(self, name, attrs):&lt;br /&gt;
        # attrs.items() is a list of tuples (name, value)&lt;br /&gt;
        print &amp;quot;start:&amp;quot;, name, &amp;quot;/&amp;quot;, attrs.items()&lt;br /&gt;
        self.output.startElement(name, attrs)&lt;br /&gt;
&lt;br /&gt;
    def characters(self, ch):&lt;br /&gt;
        print &amp;quot;char:&amp;quot;, self._inside, &amp;quot;/&amp;quot;, ch&lt;br /&gt;
        self.output.characters(ch)&lt;br /&gt;
&lt;br /&gt;
    def endElement(self, name):&lt;br /&gt;
        print &amp;quot;end:&amp;quot;, name&lt;br /&gt;
        self.output.endElement(name)&lt;br /&gt;
&lt;br /&gt;
if __name__ == &#039;__main__&#039;:&lt;br /&gt;
    parser = optparse.OptionParser(usage=&#039;%prog ...&#039;)&lt;br /&gt;
    parser.add_option(&#039;-v&#039;, &#039;--verbose&#039;,&lt;br /&gt;
                       action=&#039;store_true&#039;, default=False,&lt;br /&gt;
                       help=&#039;Print more information.&#039;)&lt;br /&gt;
    parser.add_option(&#039;--input-xml&#039;,&lt;br /&gt;
                       type=&#039;str&#039;, default=&#039;descriptor.xml&#039;,&lt;br /&gt;
                       help=&#039;Name of input XML [default: %default]&#039;)&lt;br /&gt;
    parser.add_option(&#039;--output-xml&#039;,&lt;br /&gt;
                       type=&#039;str&#039;, default=&#039;fixed_descriptor.xml&#039;,&lt;br /&gt;
                       help=&#039;Name of output XML [default: %default]&#039;)&lt;br /&gt;
    opts, args = parser.parse_args(argv[1:])&lt;br /&gt;
    source = open(opts.input_xml)&lt;br /&gt;
    dest = open(opts.output_xml, &#039;w+&#039;)&lt;br /&gt;
    xml.sax.parse(source, fix_descriptor(dest, opts.verbose))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Unicode ===&lt;br /&gt;
&lt;br /&gt;
Unicode string:&lt;br /&gt;
 u&#039;Hello World !&#039;&lt;br /&gt;
&lt;br /&gt;
Raw Unicode string:&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; ur&#039;Hello\u0020World !&#039;&lt;br /&gt;
 u&#039;Hello World !&#039;&lt;br /&gt;
&lt;br /&gt;
Convert:&lt;br /&gt;
 u = u&#039;hello\xe4&#039;&lt;br /&gt;
 str(u)  # UnicodeEncodeError: &#039;ascii&#039; codec can&#039;t encode character u&#039;\xe4&#039; in position 5: ordinal not in range(128)&lt;br /&gt;
 s = u.encode(&#039;utf8&#039;)  # &#039;s&#039; is now type str&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* Introduction to Unicode Strings - http://docs.python.org/tutorial/introduction.html#unicode-strings&lt;br /&gt;
&lt;br /&gt;
=== Zip ===&lt;br /&gt;
&lt;br /&gt;
See [[Python/Zip]]&lt;br /&gt;
&lt;br /&gt;
=== signals ===&lt;br /&gt;
&lt;br /&gt;
 signal.SIGTERM  : kill  [pid]&lt;br /&gt;
 signal.SIGALRM  : kill -ALRM  [pid]&lt;br /&gt;
 signal.SIGHUP   : kill -HUP  [pid]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import signal, os&lt;br /&gt;
&lt;br /&gt;
def handler(signum, frame):&lt;br /&gt;
    print &#039;Signal handler called with signal&#039;, signum&lt;br /&gt;
    raise IOError(&amp;quot;Couldn&#039;t open device!&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
# Set the signal handler and a 5-second alarm&lt;br /&gt;
signal.signal(signal.SIGALRM, handler)&lt;br /&gt;
signal.alarm(5)&lt;br /&gt;
&lt;br /&gt;
# This open() may hang indefinitely&lt;br /&gt;
fd = os.open(&#039;/dev/ttyS0&#039;, os.O_RDWR)&lt;br /&gt;
&lt;br /&gt;
signal.alarm(0)          # Disable the alarm&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: use signal.SIGTERM to handle &amp;quot;kill&amp;quot; command&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* 17.4. signal — Set handlers for asynchronous events — Python v2.7.5 documentation - http://docs.python.org/2/library/signal.html&lt;br /&gt;
&lt;br /&gt;
==== Ctrl+C ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
import signal&lt;br /&gt;
import sys&lt;br /&gt;
def signal_handler(signal, frame):&lt;br /&gt;
        print &#039;You pressed Ctrl+C!&#039;&lt;br /&gt;
        sys.exit(0)&lt;br /&gt;
signal.signal(signal.SIGINT, signal_handler)&lt;br /&gt;
print &#039;Press Ctrl+C&#039;&lt;br /&gt;
&lt;br /&gt;
# linux only:&lt;br /&gt;
signal.pause()&lt;br /&gt;
&lt;br /&gt;
# windows alternative:&lt;br /&gt;
#import time&lt;br /&gt;
#time.sleep(60)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* control - How do I capture SIGINT in Python? - Stack Overflow - http://stackoverflow.com/questions/1112343/how-do-i-capture-sigint-in-python&lt;br /&gt;
&lt;br /&gt;
==== Non-blocking raw_input for Python ====&lt;br /&gt;
&lt;br /&gt;
Non-blocking raw_input for Python:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# source: http://www.garyrobinson.net/2009/10/non-blocking-raw_input-for-python.html&lt;br /&gt;
&lt;br /&gt;
import signal&lt;br /&gt;
&lt;br /&gt;
class AlarmException(Exception):&lt;br /&gt;
    pass&lt;br /&gt;
&lt;br /&gt;
def alarmHandler(signum, frame):&lt;br /&gt;
    raise AlarmException&lt;br /&gt;
&lt;br /&gt;
def nonBlockingRawInput(prompt=&#039;&#039;, timeout=20):&lt;br /&gt;
    signal.signal(signal.SIGALRM, alarmHandler)&lt;br /&gt;
    signal.alarm(timeout)&lt;br /&gt;
    try:&lt;br /&gt;
        text = raw_input(prompt)&lt;br /&gt;
        signal.alarm(0)&lt;br /&gt;
        return text&lt;br /&gt;
    except AlarmException:&lt;br /&gt;
        print &#039;\nPrompt timeout. Continuing...&#039;&lt;br /&gt;
    signal.signal(signal.SIGALRM, signal.SIG_IGN)&lt;br /&gt;
    return &#039;&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== email ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import smtplib&lt;br /&gt;
import email.mime.text&lt;br /&gt;
&lt;br /&gt;
msg_text = &amp;quot;Hello World&amp;quot;&lt;br /&gt;
msg = email.mime.text.MIMEText(msg_text)&lt;br /&gt;
&lt;br /&gt;
# me == the sender&#039;s email address&lt;br /&gt;
# you == the recipient&#039;s email address&lt;br /&gt;
msg[&#039;Subject&#039;] = &#039;The contents of %s&#039; % textfile&lt;br /&gt;
msg[&#039;From&#039;] = me&lt;br /&gt;
msg[&#039;To&#039;] = you&lt;br /&gt;
&lt;br /&gt;
# Send the message via our own SMTP server, but don&#039;t include the&lt;br /&gt;
# envelope header.&lt;br /&gt;
s = smtplib.SMTP(&#039;localhost&#039;)&lt;br /&gt;
s.sendmail(me, [you], msg.as_string())&lt;br /&gt;
s.quit()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
my nagios fake /bin/mail:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
&lt;br /&gt;
import smtplib&lt;br /&gt;
import email.mime.text&lt;br /&gt;
import optparse&lt;br /&gt;
import os&lt;br /&gt;
import sys&lt;br /&gt;
import pwd&lt;br /&gt;
&lt;br /&gt;
os.system(&#039;logger mail called&#039;)&lt;br /&gt;
&lt;br /&gt;
parser = optparse.OptionParser()&lt;br /&gt;
parser.add_option(&lt;br /&gt;
    &#039;-s&#039;, &#039;--subject&#039;,&lt;br /&gt;
    help=&#039;Subject&#039;,&lt;br /&gt;
    default=&amp;quot;&amp;quot;)&lt;br /&gt;
parser.add_option(&lt;br /&gt;
    &#039;-t&#039;, &#039;--to&#039;,&lt;br /&gt;
    help=&#039;To&#039;,&lt;br /&gt;
    dest=&amp;quot;send_to&amp;quot;,&lt;br /&gt;
    default=None)&lt;br /&gt;
parser.add_option(&lt;br /&gt;
    &#039;-f&#039;, &#039;--from&#039;,&lt;br /&gt;
    help=&#039;From&#039;,&lt;br /&gt;
    dest=&amp;quot;send_from&amp;quot;,&lt;br /&gt;
    default=None)&lt;br /&gt;
parser.add_option(&lt;br /&gt;
    &#039;-S&#039;, &#039;--server&#039;,&lt;br /&gt;
    help=&#039;server&#039;,&lt;br /&gt;
    default=&amp;quot;prime&amp;quot;)&lt;br /&gt;
(options, args) = parser.parse_args()&lt;br /&gt;
&lt;br /&gt;
def get_username():&lt;br /&gt;
    return pwd.getpwuid( os.getuid() )[ 0 ]&lt;br /&gt;
&lt;br /&gt;
if options.send_to:&lt;br /&gt;
    send_to = options.send_to&lt;br /&gt;
else:&lt;br /&gt;
    if len(args) == 1:&lt;br /&gt;
        send_to = args[0]&lt;br /&gt;
    else:&lt;br /&gt;
        parser.print_help()&lt;br /&gt;
        sys.exit(1)&lt;br /&gt;
&lt;br /&gt;
if options.send_from:&lt;br /&gt;
    send_from = options.send_from&lt;br /&gt;
else:&lt;br /&gt;
    username = get_username()&lt;br /&gt;
    hostname = os.uname()[1]&lt;br /&gt;
    send_from = username + &amp;quot;@&amp;quot; + hostname&lt;br /&gt;
&lt;br /&gt;
msg_text = sys.stdin.read()&lt;br /&gt;
msg = email.mime.text.MIMEText(msg_text)&lt;br /&gt;
&lt;br /&gt;
msg[&#039;Subject&#039;] = options.subject&lt;br /&gt;
msg[&#039;From&#039;] = send_from&lt;br /&gt;
msg[&#039;To&#039;] = send_to&lt;br /&gt;
&lt;br /&gt;
s = smtplib.SMTP(options.server)&lt;br /&gt;
s.sendmail(send_from, [send_to], msg.as_string())&lt;br /&gt;
s.quit()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Authenticated (with gmail):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import smtplib&lt;br /&gt;
import email.mime.text&lt;br /&gt;
&lt;br /&gt;
# from_email = &amp;quot;kenneth@demo.oeey.com&amp;quot;&lt;br /&gt;
# to_email = &amp;quot;kenneth@demo.oeey.com&amp;quot;&lt;br /&gt;
from_email = &amp;quot;Kenneth Burgener &amp;lt;kenneth@demo.oeey.com&amp;gt;&amp;quot;&lt;br /&gt;
to_emails = [&amp;quot;Kenneth Burgener &amp;lt;kenneth@demo.oeey.com&amp;gt;&amp;quot;, &amp;quot;Kenneth Cell &amp;lt;xxx@xxx.com&amp;gt;&amp;quot;]&lt;br /&gt;
&lt;br /&gt;
msg_text = &amp;quot;hello world&amp;quot;&lt;br /&gt;
msg = email.mime.text.MIMEText(msg_text)&lt;br /&gt;
msg[&#039;Subject&#039;] = &#039;Test text&#039;&lt;br /&gt;
msg[&#039;From&#039;] = from_email&lt;br /&gt;
# msg[&#039;To&#039;] = to_email&lt;br /&gt;
msg[&#039;To&#039;] = &amp;quot;, &amp;quot;.join(to_emails)&lt;br /&gt;
# s = smtplib.SMTP(&#039;localhost&#039;)&lt;br /&gt;
print &amp;quot;sending...&amp;quot;&lt;br /&gt;
s = smtplib.SMTP_SSL(&#039;smtp.gmail.com&#039;, &#039;465&#039;)&lt;br /&gt;
s.login(&#039;xxx&#039;, &#039;xxx&#039;)&lt;br /&gt;
# s.sendmail(from_email, [to_email], msg.as_string())&lt;br /&gt;
s.sendmail(from_email, to_emails, msg.as_string())&lt;br /&gt;
s.quit()&lt;br /&gt;
print &amp;quot;sent!&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Source: &lt;br /&gt;
* 20.12. smtplib — SMTP protocol client — Python v2.7.5 documentation - http://docs.python.org/2/library/smtplib.html&lt;br /&gt;
* 18.1.11. email: Examples — Python v2.7.5 documentation - http://docs.python.org/2/library/email-examples.html&lt;br /&gt;
&lt;br /&gt;
=== pprint ===&lt;br /&gt;
&lt;br /&gt;
8.18. pprint — Data pretty printer — Python v2.7.5 documentation - http://docs.python.org/2/library/pprint.html&lt;br /&gt;
&lt;br /&gt;
 import pprint&lt;br /&gt;
 pprint.pprint(myVar)&lt;br /&gt;
&lt;br /&gt;
 import pprint&lt;br /&gt;
 pp = pprint.PrettyPrinter(indent=4)&lt;br /&gt;
 pp.pprint(myVar)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Note: Useless on objects!&lt;br /&gt;
&lt;br /&gt;
Dump object:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def dumpobject(obj):&lt;br /&gt;
    print &amp;quot;&amp;lt;&amp;lt;&amp;lt;---&amp;quot;&lt;br /&gt;
    print type(obj), obj.__class__.__name__&lt;br /&gt;
    for attr in dir(obj):&lt;br /&gt;
        if attr[0] == &amp;quot;_&amp;quot;: continue  # ignore under/dunder properties&lt;br /&gt;
        if str(type(getattr(obj, attr))) == &amp;quot;&amp;lt;type &#039;instancemethod&#039;&amp;gt;&amp;quot;:&lt;br /&gt;
            print attr, &amp;quot;: METHOD&amp;quot;&lt;br /&gt;
        else:&lt;br /&gt;
            print attr, &amp;quot;:&amp;quot;, type(getattr(obj, attr)), &amp;quot;:&amp;quot;, getattr(obj, attr)&lt;br /&gt;
    print &amp;quot;END ---&amp;gt;&amp;gt;&amp;gt;&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Curses ===&lt;br /&gt;
&lt;br /&gt;
Curses Programming with Python — Python v3.3.2 documentation - http://docs.python.org/3/howto/curses.html&lt;br /&gt;
&lt;br /&gt;
&amp;quot;The curses library supplies a terminal-independent screen-painting and keyboard-handling facility for text-based terminals; such terminals include VT100s, the Linux console, and the simulated terminal provided by various programs. Display terminals support various control codes to perform common operations such as moving the cursor, scrolling the screen, and erasing areas. Different terminals use widely differing codes, and often have their own minor quirks.&lt;br /&gt;
&lt;br /&gt;
In a world of graphical displays, one might ask “why bother”? It’s true that character-cell display terminals are an obsolete technology, but there are niches in which being able to do fancy things with them are still valuable. One niche is on small-footprint or embedded Unixes that don’t run an X server. Another is tools such as OS installers and kernel configurators that may have to run before any graphical support is available.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
Thread from Utah Python User&#039;s Group mailing list:&lt;br /&gt;
&lt;br /&gt;
-&lt;br /&gt;
&lt;br /&gt;
Hello, I am trying to learn more about curses in python for a desktop application. Does anybody have any recommendations on tutorials or documentation? &lt;br /&gt;
&lt;br /&gt;
-Corban&lt;br /&gt;
&lt;br /&gt;
-&lt;br /&gt;
&lt;br /&gt;
We&#039;ve use urwid at work. Seems to be a good approach if you aren&#039;t already tied to something. Learning curve can be a bit steep (well, compared to what you&#039;d think it should be). Good luck!&lt;br /&gt;
&lt;br /&gt;
 http://excess.org/urwid/&lt;br /&gt;
&lt;br /&gt;
Gabriel Gunderson&lt;br /&gt;
&lt;br /&gt;
-&lt;br /&gt;
&lt;br /&gt;
This video series looks pretty good:&lt;br /&gt;
&lt;br /&gt;
http://www.youtube.com/user/pythoncursestutorial?feature=watch&lt;br /&gt;
&lt;br /&gt;
Official HOWTOs from the python.org site:&lt;br /&gt;
&lt;br /&gt;
http://docs.python.org/2/howto/curses.html&lt;br /&gt;
http://docs.python.org/3/howto/curses.html&lt;br /&gt;
&lt;br /&gt;
As Gabe mentioned, there are other libraries that provide similar or&lt;br /&gt;
greater functionality, so if you aren&#039;t doing this specifically to&lt;br /&gt;
learn curses, it&#039;s worth at least looking at a few of them to compare.&lt;br /&gt;
&lt;br /&gt;
There&#039;s a brief comparison of three possibilities here:&lt;br /&gt;
&lt;br /&gt;
http://stackoverflow.com/questions/8349085/python-ncurses-cdk-urwid-difference&lt;br /&gt;
&lt;br /&gt;
Daniel Fackrell&lt;br /&gt;
&lt;br /&gt;
-&lt;br /&gt;
&lt;br /&gt;
Here&#039;s another option that looks promising:&lt;br /&gt;
&lt;br /&gt;
https://pypi.python.org/pypi/blessings/&lt;br /&gt;
&lt;br /&gt;
Daniel Fackrell&lt;br /&gt;
&lt;br /&gt;
=== dialog ===&lt;br /&gt;
&lt;br /&gt;
pythondialog - http://pythondialog.sourceforge.net/&lt;br /&gt;
: &amp;quot;pythondialog is a Python wrapper for the dialog utility originally written by Savio Lam, and later rewritten by Thomas E. Dickey. Its purpose is to provide an easy to use, pythonic and comprehensive Python interface to dialog. This allows one to make simple text-mode user interfaces on Unix-like systems (including Linux). &amp;quot;&lt;br /&gt;
&lt;br /&gt;
Note: The latest versions (2.12 and later) only support Python 3; users who really want to stick to Python 2 should use version 2.11 for now.&lt;br /&gt;
&lt;br /&gt;
Install:&lt;br /&gt;
 # latest:&lt;br /&gt;
 # wget http://sourceforge.net/projects/pythondialog/files/latest/download?source=dlp&lt;br /&gt;
&lt;br /&gt;
 wget http://sourceforge.net/projects/pythondialog/files/pythondialog/2.11/python2-pythondialog-2.11.tar.gz/download&lt;br /&gt;
 tar -zvxf python2-pythondialog-2.11.tar.gz&lt;br /&gt;
 cd pythondialog-2.11&lt;br /&gt;
&lt;br /&gt;
 import dialog&lt;br /&gt;
 d = dialog.Dialog()&lt;br /&gt;
 if d.yesno(&amp;quot;Continue?&amp;quot;) == d.DIALOG_OK:&lt;br /&gt;
  print &amp;quot;Continuing...&amp;quot;&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
My solution&lt;br /&gt;
&lt;br /&gt;
kiloforce / dialog / source / — Bitbucket - https://bitbucket.org/kiloforce/dialog&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot; Wrapper for Linux &#039;dialog&#039; command &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
__author__ = &amp;quot;Kenneth Burgener &amp;lt;kenneth@k.ttak.org&amp;gt;&amp;quot;&lt;br /&gt;
__copyright__ = &amp;quot;(c) 2013&amp;quot;&lt;br /&gt;
__date__ = &amp;quot;$Sep 27, 2013$&amp;quot;&lt;br /&gt;
__version__ = &amp;quot;1.0&amp;quot;&lt;br /&gt;
__credits__ = r&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
XXXXXXXXXXXXXXXXXX&lt;br /&gt;
X Dialog Wrapper #&lt;br /&gt;
##################&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
import subprocess&lt;br /&gt;
import time&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
class Dialog():&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot; Python wrapper for Linux &#039;dialog&#039; command&lt;br /&gt;
&lt;br /&gt;
    dialog - display dialog boxes from shell scripts&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import dialog&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dlg = dialog.Dialog()&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; rc = dlg.msgbox(&#039;hello world&#039;)&lt;br /&gt;
&lt;br /&gt;
    Return codes:&lt;br /&gt;
        YES = 0&lt;br /&gt;
        OK = 0&lt;br /&gt;
        EXIT = 0&lt;br /&gt;
        NO = 1&lt;br /&gt;
        CANCEL = 1&lt;br /&gt;
        ESC = 255&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    YES = 0&lt;br /&gt;
    OK = 0&lt;br /&gt;
    EXIT = 0&lt;br /&gt;
    NO = 1&lt;br /&gt;
    CANCEL = 1&lt;br /&gt;
    ESC = 255&lt;br /&gt;
&lt;br /&gt;
    def __init__(self):&lt;br /&gt;
        rc = self._exe(&#039;which dialog &amp;gt; /dev/null&#039;)[0]&lt;br /&gt;
        if rc != 0:&lt;br /&gt;
            print &amp;quot;Error: failed to find Linux dialog command&amp;quot;&lt;br /&gt;
            sys.exit(1)&lt;br /&gt;
&lt;br /&gt;
    def _exe(self, cmd, strip=True):&lt;br /&gt;
        p = subprocess.Popen(cmd, shell=True, stderr=subprocess.PIPE)&lt;br /&gt;
        output = &amp;quot;\n&amp;quot;.join(p.stderr.readlines())&lt;br /&gt;
        if strip:&lt;br /&gt;
            output = output.strip()&lt;br /&gt;
        rc = p.wait()&lt;br /&gt;
        return (rc, output)&lt;br /&gt;
&lt;br /&gt;
    def rc_to_str(self, rc):&lt;br /&gt;
        if rc == 0:&lt;br /&gt;
            return &amp;quot;YES&amp;quot;&lt;br /&gt;
        elif rc == 1:&lt;br /&gt;
            return &amp;quot;NO&amp;quot;&lt;br /&gt;
        elif rc == 255:&lt;br /&gt;
            return &amp;quot;ESX&amp;quot;&lt;br /&gt;
        else:&lt;br /&gt;
            raise Exception(&amp;quot;Unknown return code: %s&amp;quot; % rc)&lt;br /&gt;
&lt;br /&gt;
    def clear(self):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Clear screen&lt;br /&gt;
&lt;br /&gt;
        Example:&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt; dialog.clear()&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        rc, output = self._exe(&#039;clear&#039;)&lt;br /&gt;
        assert rc in (0,), &amp;quot;clear rc&amp;quot;&lt;br /&gt;
        return rc&lt;br /&gt;
&lt;br /&gt;
    def msgbox(self, msg):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Simple message box&lt;br /&gt;
&lt;br /&gt;
        @param msg (str) = display message&lt;br /&gt;
        @return: rc (int)&lt;br /&gt;
&lt;br /&gt;
        Example:&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt; rc = dialog.msgbox(&#039;hello world&#039;)&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        rc, output = self._exe(&#039;dialog --msgbox &amp;quot;{msg}&amp;quot; 0 0&#039;.format(msg=msg))&lt;br /&gt;
        assert rc in (self.YES, self.ESC), &amp;quot;msgbox rc&amp;quot;&lt;br /&gt;
        return rc&lt;br /&gt;
&lt;br /&gt;
    def yesno(self, msg):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Yes/No dialog&lt;br /&gt;
&lt;br /&gt;
        @param msg (str) = display message&lt;br /&gt;
        @return: rc (int)&lt;br /&gt;
&lt;br /&gt;
        Example:&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt; rc = dialog.yesno(&#039;continue&#039;)&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        rc, output = self._exe(&#039;dialog --yesno &amp;quot;{msg}&amp;quot; 0 0&#039;.format(msg=msg))&lt;br /&gt;
        assert rc in (self.YES, self.NO, self.ESC), &amp;quot;yesno rc&amp;quot;&lt;br /&gt;
        return rc&lt;br /&gt;
&lt;br /&gt;
    def infobox(self, msg):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Dialog that does not wait for user&#039;s response&lt;br /&gt;
        (do your own pause)&lt;br /&gt;
&lt;br /&gt;
        @param msg (str) = display message&lt;br /&gt;
        @return: rc (int) always zero&lt;br /&gt;
&lt;br /&gt;
        Example:&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt; for i in range(10):&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt;   dialog.infobox(&#039;counting: &#039; + str(i))&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt;   time.sleep(3)&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        rc, output = self._exe(&#039;dialog --infobox &amp;quot;{msg}&amp;quot; 0 0&#039;.format(msg=msg))&lt;br /&gt;
        assert rc in (self.YES,), &amp;quot;infobox rc&amp;quot;&lt;br /&gt;
        return rc&lt;br /&gt;
&lt;br /&gt;
    def inputbox(self, msg):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Get user input&lt;br /&gt;
&lt;br /&gt;
        @param msg (str) = display message&lt;br /&gt;
        @return: rc (int), output (str/None)&lt;br /&gt;
&lt;br /&gt;
        Example:&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt; rc, output = dialog.inputbox(&#039;name:&#039;)&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        rc, output = self._exe(&#039;dialog --inputbox &amp;quot;{msg}&amp;quot; 0 0&#039;.format(msg=msg))&lt;br /&gt;
        assert rc in (self.YES, self.NO, self.ESC), &amp;quot;inputbox rc&amp;quot;&lt;br /&gt;
        if not output:&lt;br /&gt;
            output = None&lt;br /&gt;
        return rc, output&lt;br /&gt;
&lt;br /&gt;
    def textbox(self, filename):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Display a file&lt;br /&gt;
&lt;br /&gt;
        @param filename (str) = file to display&lt;br /&gt;
        @return: rc (int)&lt;br /&gt;
&lt;br /&gt;
        Example:&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt; dialog.textbox(&#039;/etc/passwd&#039;)&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        rc, output = self._exe(&#039;dialog --textbox {filename} 0 0&#039;.format(filename=filename))&lt;br /&gt;
        assert rc in (self.YES, self.ESC), &amp;quot;textbox rc&amp;quot;&lt;br /&gt;
        return rc&lt;br /&gt;
&lt;br /&gt;
    def menu(self, msg, item_list):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Single selection checkbox menu&lt;br /&gt;
&lt;br /&gt;
        @param msg (str) = display message&lt;br /&gt;
        @param item_list (str list) = list of items to display&lt;br /&gt;
        @return: rc (int), selection (int/None)&lt;br /&gt;
&lt;br /&gt;
        Example:&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt; rc, selection = dialog.menu(&#039;Select multiple options:&#039;,&lt;br /&gt;
        ...     (&#039;option 1&#039;, &#039;option 2&#039;))&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        item_str = &amp;quot;&amp;quot;&lt;br /&gt;
        for i in range(len(item_list)):&lt;br /&gt;
            item_str += &amp;quot; &amp;quot; + str(i+1) + &amp;quot; \&amp;quot;&amp;quot; + item_list[i] + &amp;quot;\&amp;quot;&amp;quot;&lt;br /&gt;
        rc, output = self._exe(&#039;dialog --menu &amp;quot;{msg}&amp;quot; 0 0 0 {item_str}&#039;.format(msg=msg, item_str=item_str))&lt;br /&gt;
        if output:&lt;br /&gt;
            selection = int(output)&lt;br /&gt;
        else:&lt;br /&gt;
            selection = None&lt;br /&gt;
        assert rc in (self.YES, self.NO, self.ESC), &amp;quot;menu rc&amp;quot;&lt;br /&gt;
        return rc, selection&lt;br /&gt;
&lt;br /&gt;
    def checklist(self, msg, item_list, checked_list=None):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Multiple selection checkbox menu&lt;br /&gt;
&lt;br /&gt;
        @param msg (str) = display message&lt;br /&gt;
        @param item_list (str list) = list of items&lt;br /&gt;
        @param checked_list (int list) = default items to check&lt;br /&gt;
        @return: rc (int), selections (int list/None)&lt;br /&gt;
&lt;br /&gt;
        Example:&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt; rc, selections = dialog.checklist(&#039;Select multiple options:&#039;,&lt;br /&gt;
        ...     (&#039;option 1&#039;, &#039;option 2&#039;)&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        item_str = &amp;quot;&amp;quot;&lt;br /&gt;
        assert type(item_list) in (type(None), type(()), type([])), &amp;quot;checklist: item_list must be a list&amp;quot;&lt;br /&gt;
        assert type(checked_list) in (type(None), type(()), type([])), &amp;quot;checklist: checked_list must be a list&amp;quot;&lt;br /&gt;
        for i in range(len(item_list)):&lt;br /&gt;
            item_str += &amp;quot; &amp;quot; + str(i+1) + &amp;quot; \&amp;quot;&amp;quot; + item_list[i] + &amp;quot;\&amp;quot;&amp;quot;&lt;br /&gt;
            if checked_list and i+1 in checked_list:&lt;br /&gt;
                item_str += &amp;quot; on&amp;quot;&lt;br /&gt;
            else:&lt;br /&gt;
                item_str += &amp;quot; off&amp;quot;&lt;br /&gt;
        rc, output = self._exe(&#039;dialog --checklist &amp;quot;{msg}&amp;quot; 0 0 0 {item_str}&#039;.format(msg=msg, item_str=item_str))&lt;br /&gt;
        print item_str&lt;br /&gt;
        selections = []&lt;br /&gt;
        for choice in output.split(&#039;&amp;quot;&#039;):&lt;br /&gt;
            if choice.strip():&lt;br /&gt;
                selections.append(int(choice))&lt;br /&gt;
        if selections:&lt;br /&gt;
            selections = tuple(selections)&lt;br /&gt;
        else:&lt;br /&gt;
            selections = None&lt;br /&gt;
        assert rc in (self.YES, self.NO, self.ESC), &amp;quot;checklist rc&amp;quot;&lt;br /&gt;
        return rc, selections&lt;br /&gt;
&lt;br /&gt;
    def radiolist(self, msg, item_list, checked_item=None):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Single selection radio menu, with default&lt;br /&gt;
&lt;br /&gt;
        @param msg (str) = display message&lt;br /&gt;
        @param item_list (str list) = list of items&lt;br /&gt;
        @param checked_item (int) = default item to select&lt;br /&gt;
        @return: rc (int), selection (int)&lt;br /&gt;
&lt;br /&gt;
        Example:&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt; rc, selection = dialog.radiolist(&#039;Select one option:&#039;,&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt;     (&#039;option 1&#039;, &#039;option 2&#039;), 2)&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        item_str = &amp;quot;&amp;quot;&lt;br /&gt;
        for i in range(len(item_list)):&lt;br /&gt;
            item_str += &amp;quot; &amp;quot; + str(i+1) + &amp;quot; \&amp;quot;&amp;quot; + item_list[i] + &amp;quot;\&amp;quot;&amp;quot;&lt;br /&gt;
            if checked_item and i+1 == int(checked_item):&lt;br /&gt;
                item_str += &amp;quot; on&amp;quot;&lt;br /&gt;
            else:&lt;br /&gt;
                item_str += &amp;quot; off&amp;quot;&lt;br /&gt;
        rc, selection = self._exe(&#039;dialog --radiolist &amp;quot;{msg}&amp;quot; 0 0 0 {item_str}&#039;.format(msg=msg, item_str=item_str))&lt;br /&gt;
        if not selection:&lt;br /&gt;
            selection = None&lt;br /&gt;
        assert rc in (self.YES, self.NO, self.ESC), &amp;quot;radiolist rc&amp;quot;&lt;br /&gt;
        return rc, selection&lt;br /&gt;
&lt;br /&gt;
    def gauge(self, msg, percent):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Progress bar (does not wait for user&#039;s input)&lt;br /&gt;
&lt;br /&gt;
        @param msg (str) = display message&lt;br /&gt;
        @param percent (int) = progress&lt;br /&gt;
        @return: rc (int) always zero&lt;br /&gt;
&lt;br /&gt;
        Example:&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt; for i in range(0, 100+1, 2):&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt;   dialog.gauge(&#039;Progress:&#039;, i)&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt;   time.sleep(.1)&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        rc, output = self._exe(&#039;echo {percent} | dialog --gauge &amp;quot;{msg}&amp;quot; 0 0&#039;.format(percent=percent, msg=msg))&lt;br /&gt;
        assert rc in (self.YES,), &amp;quot;guage rc&amp;quot;&lt;br /&gt;
        return rc&lt;br /&gt;
&lt;br /&gt;
    def progress(self, msg, percent):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Alias for self.guage()&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        return self.gauge(msg=msg, percent=percent)&lt;br /&gt;
&lt;br /&gt;
    def form(self, msg, item_list):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Multiple item entry form&lt;br /&gt;
&lt;br /&gt;
        @param msg (str) = display message&lt;br /&gt;
        @param item_list (str list) = list of items&lt;br /&gt;
        @return: rc (int), answers (str list)&lt;br /&gt;
&lt;br /&gt;
        Example:&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt; rc, answers = dialog.form(&#039;Enter details&#039;,&lt;br /&gt;
        ...     (&#039;first name&#039;, &#039;last name&#039;))&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        item_str = &amp;quot;&amp;quot;&lt;br /&gt;
        name_len = 1&lt;br /&gt;
        for i in range(len(item_list)):&lt;br /&gt;
            if len(item_list[i])+3 &amp;gt; name_len:&lt;br /&gt;
                name_len = len(item_list[i])+3&lt;br /&gt;
        for i in range(len(item_list)):&lt;br /&gt;
            item_str += &amp;quot; \&amp;quot;&amp;quot; + item_list[i] + &amp;quot;:\&amp;quot; &amp;quot; + str(i+1) + &amp;quot; 1 \&amp;quot;\&amp;quot; &amp;quot; + str(i+1) +\&lt;br /&gt;
                &amp;quot; &amp;quot; + str(name_len) + &amp;quot; 40 0&amp;quot;&lt;br /&gt;
        rc, answers = self._exe(&#039;dialog --form &amp;quot;{msg}&amp;quot; 0 0 0 {item_str}&#039;.format(msg=msg, item_str=item_str),&lt;br /&gt;
                                strip=False)&lt;br /&gt;
        answers = answers.split(&#039;\n\n&#039;)&lt;br /&gt;
        if not answers:&lt;br /&gt;
            answers = None&lt;br /&gt;
        assert rc in (self.YES, self.NO, self.ESC), &amp;quot;form rc&amp;quot;&lt;br /&gt;
        return rc, answers&lt;br /&gt;
&lt;br /&gt;
    def test(self):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Test features&lt;br /&gt;
&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt; import dialog&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt; dlg = dialog.Dialog()&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt; dlg.test()&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
        def wait_user(msg):&lt;br /&gt;
            self.msgbox(&amp;quot;%s&amp;quot; % msg)&lt;br /&gt;
&lt;br /&gt;
        # rc_to_str&lt;br /&gt;
        wait_user(&amp;quot;Testing return code...&amp;quot;)&lt;br /&gt;
        print self.rc_to_str(self.YES)  # YES&lt;br /&gt;
        print self.rc_to_str(self.NO)  # NO&lt;br /&gt;
        print self.rc_to_str(self.ESC)  # ESX&lt;br /&gt;
        try:&lt;br /&gt;
            print self.rc_to_str(111)  # exception&lt;br /&gt;
            raise Exception(&amp;quot;Did not throw exception&amp;quot;)&lt;br /&gt;
        except Exception as rc:&lt;br /&gt;
            pass&lt;br /&gt;
&lt;br /&gt;
        # msgbox&lt;br /&gt;
        wait_user(&amp;quot;Testing msgbox...&amp;quot;)&lt;br /&gt;
        rc = self.msgbox(&amp;quot;msgbox&amp;quot;)&lt;br /&gt;
        if rc not in (self.YES, self.ESC):&lt;br /&gt;
            raise Exception(&amp;quot;Unknown return code for msgbox: %s&amp;quot; % rc)&lt;br /&gt;
&lt;br /&gt;
        # yesno&lt;br /&gt;
        wait_user(&amp;quot;Testing yesno...&amp;quot;)&lt;br /&gt;
        rc = self.yesno(&amp;quot;yesno&amp;quot;)&lt;br /&gt;
        if rc not in (self.YES, self.NO, self.ESC):&lt;br /&gt;
            raise Exception(&amp;quot;Unknown return code for yesno: %s&amp;quot; % rc)&lt;br /&gt;
&lt;br /&gt;
        # infobox&lt;br /&gt;
        wait_user(&amp;quot;Testing infobox...&amp;quot;)&lt;br /&gt;
        rc = self.infobox(&amp;quot;infobox sleep 1 sec&amp;quot;)&lt;br /&gt;
        if rc not in (self.YES,):&lt;br /&gt;
            raise Exception(&amp;quot;Unknown return code for infobox %s&amp;quot; % rc)&lt;br /&gt;
        time.sleep(1)&lt;br /&gt;
&lt;br /&gt;
        # inputbox&lt;br /&gt;
        wait_user(&amp;quot;Testing inputbox...&amp;quot;)&lt;br /&gt;
        rc, output = self.inputbox(&amp;quot;inputbox&amp;quot;)&lt;br /&gt;
        if rc not in (self.YES, self.NO, self.ESC):&lt;br /&gt;
            raise Exception(&amp;quot;Unknown return code for inputbox: %s&amp;quot; % rc)&lt;br /&gt;
        wait_user(&amp;quot;Result: %s&amp;quot; % output)&lt;br /&gt;
&lt;br /&gt;
        # textbox&lt;br /&gt;
        wait_user(&amp;quot;Testing textbox...&amp;quot;)&lt;br /&gt;
        rc = self.textbox(&amp;quot;/etc/passwd&amp;quot;)&lt;br /&gt;
        if rc not in (self.YES, self.ESC):&lt;br /&gt;
            raise Exception(&amp;quot;Unknown return code for textbox: %s&amp;quot; % rc)&lt;br /&gt;
&lt;br /&gt;
        # menu&lt;br /&gt;
        wait_user(&amp;quot;Testing menu...&amp;quot;)&lt;br /&gt;
        rc, selection = self.menu(&amp;quot;menu&amp;quot;, (&amp;quot;option 1&amp;quot;, &amp;quot;option 2&amp;quot;))&lt;br /&gt;
        if rc not in (self.YES, self.NO, self.ESC):&lt;br /&gt;
            raise Exception(&amp;quot;Unknown return code for menu: %s&amp;quot; % rc)&lt;br /&gt;
        wait_user(&amp;quot;Result: %s&amp;quot; % selection)&lt;br /&gt;
&lt;br /&gt;
        # checklist&lt;br /&gt;
        wait_user(&amp;quot;Testing checklist...&amp;quot;)&lt;br /&gt;
        rc, selection = self.checklist(&amp;quot;menu&amp;quot;, [&amp;quot;option 1&amp;quot;, &amp;quot;option 2&amp;quot;])&lt;br /&gt;
        if rc not in (self.YES, self.NO, self.ESC):&lt;br /&gt;
            raise Exception(&amp;quot;Unknown return code for checklist: %s&amp;quot; % rc)&lt;br /&gt;
        wait_user(&amp;quot;Result: %s&amp;quot; % str(selection))&lt;br /&gt;
        wait_user(&amp;quot;Testing checklist with default selection...&amp;quot;)&lt;br /&gt;
        rc, selection = self.checklist(&amp;quot;menu&amp;quot;, [&amp;quot;option 1&amp;quot;, &amp;quot;option 2&amp;quot;], [1, 2])&lt;br /&gt;
        if rc not in (self.YES, self.NO, self.ESC):&lt;br /&gt;
            raise Exception(&amp;quot;Unknown return code for checklist: %s&amp;quot; % rc)&lt;br /&gt;
        wait_user(&amp;quot;Result: %s&amp;quot; % str(selection))&lt;br /&gt;
&lt;br /&gt;
        # radiolist&lt;br /&gt;
        wait_user(&amp;quot;Testing radiolist...&amp;quot;)&lt;br /&gt;
        rc, selection = self.radiolist(&amp;quot;menu&amp;quot;, [&amp;quot;option 1&amp;quot;, &amp;quot;option 2&amp;quot;])&lt;br /&gt;
        if rc not in (self.YES, self.NO, self.ESC):&lt;br /&gt;
            raise Exception(&amp;quot;Unknown return code for radiolist: %s&amp;quot; % rc)&lt;br /&gt;
        wait_user(&amp;quot;Result: %s&amp;quot; % str(selection))&lt;br /&gt;
        wait_user(&amp;quot;Testing radiolist with default selection...&amp;quot;)&lt;br /&gt;
        rc, selection = self.radiolist(&amp;quot;menu&amp;quot;, [&amp;quot;option 1&amp;quot;, &amp;quot;option 2&amp;quot;], 2)&lt;br /&gt;
        if rc not in (self.YES, self.NO, self.ESC):&lt;br /&gt;
            raise Exception(&amp;quot;Unknown return code for radiolist: %s&amp;quot; % rc)&lt;br /&gt;
        wait_user(&amp;quot;Result: %s&amp;quot; % str(selection))&lt;br /&gt;
&lt;br /&gt;
        # guage&lt;br /&gt;
        wait_user(&amp;quot;Testing guage...&amp;quot;)&lt;br /&gt;
        for i in range(4+1):&lt;br /&gt;
            rc = self.gauge(&amp;quot;test guage&amp;quot;, i*25)&lt;br /&gt;
            # rc = self.progress(&amp;quot;test progress&amp;quot;, i*25)&lt;br /&gt;
            if rc not in (self.YES,):&lt;br /&gt;
                raise Exception(&amp;quot;Unknown return code for guage: %s&amp;quot; % rc)&lt;br /&gt;
            time.sleep(1)&lt;br /&gt;
&lt;br /&gt;
        # form&lt;br /&gt;
        wait_user(&amp;quot;Testing form...&amp;quot;)&lt;br /&gt;
        rc, answers = self.form(&amp;quot;form&amp;quot;, [&amp;quot;option 1&amp;quot;, &amp;quot;option 2&amp;quot;])&lt;br /&gt;
        if rc not in (self.YES, self.NO, self.ESC):&lt;br /&gt;
            raise Exception(&amp;quot;Unknown return code for form: %s&amp;quot; % rc)&lt;br /&gt;
        wait_user(&amp;quot;Result: %s&amp;quot; % str(answers))&lt;br /&gt;
&lt;br /&gt;
        # done with test, cleanup&lt;br /&gt;
        wait_user(&amp;quot;Done with tests...&amp;quot;)&lt;br /&gt;
        self.clear()&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
    # dialog = Dialog()&lt;br /&gt;
    # dialog.test()&lt;br /&gt;
    pass&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Busy Loop and Thread.yield() ===&lt;br /&gt;
&lt;br /&gt;
&amp;quot;I want to tell my Python threads to yield, and so avoid hogging the CPU unnecessarily. In Java, you could do that using the Thread.yield() function&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Solution:&lt;br /&gt;
 time.sleep(0)&lt;br /&gt;
 time.sleep(0.00001)&lt;br /&gt;
 time.sleep(epsilon)&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* multithreading - In there something similar to Java&#039;s Thread.yield() in Python? Does that even make sense? - Stack Overflow - http://stackoverflow.com/questions/1908206/in-there-something-similar-to-javas-thread-yield-in-python-does-that-even-ma&lt;br /&gt;
* multithreading - How does a threading.Thread yield the rest of its quantum in Python? - Stack Overflow - http://stackoverflow.com/questions/787803/how-does-a-threading-thread-yield-the-rest-of-its-quantum-in-python&lt;br /&gt;
&lt;br /&gt;
=== USB ===&lt;br /&gt;
&lt;br /&gt;
Programming with PyUSB 1.0 - http://pyusb.sourceforge.net/docs/1.0/tutorial.html&lt;br /&gt;
&lt;br /&gt;
PyUSB - http://pyusb.sourceforge.net/&lt;br /&gt;
&lt;br /&gt;
 git clone https://github.com/walac/pyusb&lt;br /&gt;
&lt;br /&gt;
 import usb.core&lt;br /&gt;
 dev = usb.core.find()&lt;br /&gt;
&lt;br /&gt;
 # find our device&lt;br /&gt;
 dev = usb.core.find(idVendor=0xfffe, idProduct=0x0001)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&#039;&#039;&#039;Dealing with multiple identical devices&#039;&#039;&#039; - Sometimes you may have two identical devices connected to the computer. How can you differentiate them? Device objects come with two additional attributes which are not part of the USB Spec, but are very useful: bus and address attributes. First of all, it is worth to say that these attributes come from the backend and a backend is free to not support them, in which case they are set to None. That said, these attributes represent the bus number and bus address of the device and, as you might already have imagined, can be used to differentiate two devices with the same idVendor and idProduct attributes.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Tkinter ===&lt;br /&gt;
&lt;br /&gt;
Python GUI Bitcoin: [http://bitcoin.stackexchange.com/questions/10594/simplest-way-of-obtaining-mtgox-exchange-rate-via-an-api]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import json&lt;br /&gt;
import urllib2&lt;br /&gt;
from Tkinter import *&lt;br /&gt;
&lt;br /&gt;
url=&#039;http://api.bitcoincharts.com/v1/markets.json&#039;&lt;br /&gt;
req=urllib2.Request(url)&lt;br /&gt;
response=urllib2.urlopen(req).read()&lt;br /&gt;
output=json.loads(response)&lt;br /&gt;
&lt;br /&gt;
mtusd_price = output[-10][&#039;avg&#039;]&lt;br /&gt;
mteur_price = output[31][&#039;avg&#039;]&lt;br /&gt;
mtgbp_price = output[44][&#039;avg&#039;]&lt;br /&gt;
&lt;br /&gt;
MTUSD= &#039;USD&#039; + &#039; &#039; + str(mtusd_price)&lt;br /&gt;
MTEUR= &#039;EUR&#039; + &#039; &#039; + str(mteur_price)&lt;br /&gt;
MTGBP = &#039;GBP&#039; + &#039; &#039; + str(mtgbp_price)&lt;br /&gt;
&lt;br /&gt;
root= Tk()&lt;br /&gt;
root.title(&amp;quot;Bitcoin Price&amp;quot;)&lt;br /&gt;
root.geometry(&amp;quot;250x100&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
USD = Label(root, text=MTUSD)&lt;br /&gt;
EUR = Label(root, text=MTEUR)&lt;br /&gt;
GBP = Label(root, text=MTGBP)&lt;br /&gt;
USD.pack()&lt;br /&gt;
EUR.pack()&lt;br /&gt;
GBP.pack()&lt;br /&gt;
mainloop()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== ctypes ===&lt;br /&gt;
&lt;br /&gt;
&amp;quot;ctypes is a foreign function library for Python. It provides C compatible data types, and allows calling functions in DLLs or shared libraries. It can be used to wrap these libraries in pure Python.&amp;quot;&lt;br /&gt;
:-- 15.17. ctypes — A foreign function library for Python — Python v2.7.7 documentation - https://docs.python.org/2/library/ctypes.html&lt;br /&gt;
&lt;br /&gt;
Use &amp;quot;c scope&amp;quot; to build a database of symbols to see what options are available.&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
testlib.c&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void myprint(void);&lt;br /&gt;
&lt;br /&gt;
void myprint()&lt;br /&gt;
{&lt;br /&gt;
    printf(&amp;quot;hello world\n&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Compile:&lt;br /&gt;
 gcc -shared -Wl,-soname,testlib -o testlib.so -fPIC testlib.c&lt;br /&gt;
&lt;br /&gt;
testlibwrapper.py&lt;br /&gt;
&lt;br /&gt;
Python:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import ctypes&lt;br /&gt;
&lt;br /&gt;
testlib = ctypes.CDLL(&#039;/full/path/to/testlib.so&#039;)&lt;br /&gt;
testlib.myprint()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Source: python - ctypes - Beginner - Stack Overflow - http://stackoverflow.com/questions/5081875/ctypes-beginner&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
nzjrs&#039;s Gists - https://gist.github.com/nzjrs&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int sum(double *x,int n)&lt;br /&gt;
{&lt;br /&gt;
  int i;&lt;br /&gt;
  double counter;&lt;br /&gt;
  counter = 0;&lt;br /&gt;
  for(i=0;i&amp;lt;n;i++)&lt;br /&gt;
    {&lt;br /&gt;
      counter=counter+x[i];&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
  return counter;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -c sum.c&lt;br /&gt;
gcc -shared -o sum.so sum.o&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from ctypes import *&lt;br /&gt;
my_sum=CDLL(&#039;sum.so&#039;)&lt;br /&gt;
a=numpy.array(range(10),dtype=float)&lt;br /&gt;
my_sum.sum(a.ctypes.data_as(c_void_p),int(10))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
a=(c_double*10)()&lt;br /&gt;
for i in range(10):&lt;br /&gt;
   a[i]=i&lt;br /&gt;
my_sum.sum(a,int(10))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Source: Ctypes — Numerical Computing with Sage v6.2 - http://www.sagemath.org/doc/numerical_sage/ctypes.html&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
=== Warnings ===&lt;br /&gt;
&lt;br /&gt;
 if sys.version_info &amp;gt;= (1, 0, 0):&lt;br /&gt;
   warnings.warn(&amp;quot;Danger Will Robinson: trying Phi on untested Python 3.0!&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
=== enum ===&lt;br /&gt;
&lt;br /&gt;
Python 3: https://docs.python.org/3/library/enum.html&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from enum import Enum&lt;br /&gt;
&lt;br /&gt;
# class syntax&lt;br /&gt;
class Color(Enum):&lt;br /&gt;
    RED = 1&lt;br /&gt;
    GREEN = 2&lt;br /&gt;
    BLUE = 3&lt;br /&gt;
&lt;br /&gt;
# functional syntax&lt;br /&gt;
Color = Enum(&#039;Color&#039;, [&#039;RED&#039;, &#039;GREEN&#039;, &#039;BLUE&#039;])&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
Python 2: [http://stackoverflow.com/questions/36932/how-can-i-represent-an-enum-in-python]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Enum(set):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot; Basic enumerated type&lt;br /&gt;
    &lt;br /&gt;
    Example&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt; Animals = phi.Enum([&amp;quot;DOG&amp;quot;, &amp;quot;CAT&amp;quot;, &amp;quot;HORSE&amp;quot;])&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt; Animals.DOG&lt;br /&gt;
        &#039;DOG&#039;&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt; &#039;HORSE&#039; in Animals&lt;br /&gt;
        True&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    def __getattr__(self, name):&lt;br /&gt;
        if name in self:&lt;br /&gt;
            return name&lt;br /&gt;
        raise AttributeError(&amp;quot;Missing Enum property: %s&amp;quot; % name)&lt;br /&gt;
    def __setattr__(self, name, value):  # this makes it read-only&lt;br /&gt;
        raise AttributeError(&amp;quot;Unable to modify Enum property: %s (%s)&amp;quot; % (name, value))&lt;br /&gt;
&lt;br /&gt;
Animals = Enum([&amp;quot;DOG&amp;quot;, &amp;quot;CAT&amp;quot;, &amp;quot;HORSE&amp;quot;])&lt;br /&gt;
&lt;br /&gt;
print(Animals.DOG)  # &#039;DOG&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----------&lt;br /&gt;
&lt;br /&gt;
Alternative:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Stationery:&lt;br /&gt;
    Pen, Pencil, Eraser = range(0, 3)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
One liner:&lt;br /&gt;
 class Enum(tuple): __getattr__ = tuple.index&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; State = Enum([&#039;Unclaimed&#039;, &#039;Claimed&#039;])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; State.Claimed&lt;br /&gt;
1&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; State[1]&lt;br /&gt;
&#039;Claimed&#039;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; State&lt;br /&gt;
(&#039;Unclaimed&#039;, &#039;Claimed&#039;)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; range(len(State))&lt;br /&gt;
[0, 1]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; [(k, State[k]) for k in range(len(State))]&lt;br /&gt;
[(0, &#039;Unclaimed&#039;), (1, &#039;Claimed&#039;)]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; [(k, getattr(State, k)) for k in State]&lt;br /&gt;
[(&#039;Unclaimed&#039;, 0), (&#039;Claimed&#039;, 1)]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Python 3 supports enum natively with the enum.Enum library:&lt;br /&gt;
&lt;br /&gt;
=== pySerial ===&lt;br /&gt;
&lt;br /&gt;
https://pythonhosted.org/pyserial/&lt;br /&gt;
&lt;br /&gt;
&amp;quot;This module encapsulates the access for the serial port. It provides backends for Python running on Windows, OSX, Linux, BSD (possibly any POSIX compliant system) and IronPython. The module named “serial” automatically selects the appropriate backend.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
https://github.com/pyserial/&lt;br /&gt;
&lt;br /&gt;
Intro - https://pythonhosted.org/pyserial/shortintro.html&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import serial&lt;br /&gt;
import time&lt;br /&gt;
&lt;br /&gt;
ser = serial.Serial(&lt;br /&gt;
    port=&#039;COM4&#039;,\&lt;br /&gt;
    baudrate=9600,\&lt;br /&gt;
    parity=serial.PARITY_NONE,\&lt;br /&gt;
    stopbits=serial.STOPBITS_ONE,\&lt;br /&gt;
    bytesize=serial.EIGHTBITS,\&lt;br /&gt;
        timeout=0)&lt;br /&gt;
&lt;br /&gt;
print(&amp;quot;connected to: &amp;quot; + ser.portstr)&lt;br /&gt;
&lt;br /&gt;
#this will store the line&lt;br /&gt;
seq = []&lt;br /&gt;
count = 1&lt;br /&gt;
&lt;br /&gt;
while True:&lt;br /&gt;
    for c in ser.read():&lt;br /&gt;
        seq.append(chr(c)) #convert from ANSII&lt;br /&gt;
        joined_seq = &#039;&#039;.join(str(v) for v in seq) #Make a string from array&lt;br /&gt;
&lt;br /&gt;
        if chr(c) == &#039;\n&#039;:&lt;br /&gt;
            print(&amp;quot;Line &amp;quot; + str(count) + &#039;: &#039; + joined_seq)&lt;br /&gt;
            seq = []&lt;br /&gt;
            count += 1&lt;br /&gt;
            break&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ser.close()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ref: http://stackoverflow.com/questions/16077912/python-serial-how-to-use-the-read-or-readline-function-to-read-more-than-1-char&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
I modified the code to monitor a COM port: (Windows)&lt;br /&gt;
&lt;br /&gt;
Monitor Serial:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import serial, time, sys&lt;br /&gt;
&lt;br /&gt;
logger = open(&amp;quot;serial.txt&amp;quot;, &amp;quot;w&amp;quot;)&lt;br /&gt;
timer = time.time()&lt;br /&gt;
&lt;br /&gt;
def log(msg, head=False):&lt;br /&gt;
    msg = msg.strip()&lt;br /&gt;
    if head:&lt;br /&gt;
      msg = &amp;quot;&amp;gt;&amp;gt;&amp;gt; &amp;quot; + msg&lt;br /&gt;
    logger.write(msg + &amp;quot;\n&amp;quot;)&lt;br /&gt;
    sys.stdout.write(msg + &amp;quot;\n&amp;quot;)&lt;br /&gt;
    newtime = time.time()&lt;br /&gt;
    if newtime &amp;gt; timer + 1:&lt;br /&gt;
        logger.flush()&lt;br /&gt;
        sys.stdout.flush()&lt;br /&gt;
&lt;br /&gt;
while True:&lt;br /&gt;
&lt;br /&gt;
    ser = None&lt;br /&gt;
    try:&lt;br /&gt;
        ser = serial.Serial(&lt;br /&gt;
            port=&#039;COM1&#039;,\&lt;br /&gt;
            baudrate=115200,\&lt;br /&gt;
            parity=serial.PARITY_NONE,\&lt;br /&gt;
            stopbits=serial.STOPBITS_ONE,\&lt;br /&gt;
            bytesize=serial.EIGHTBITS,\&lt;br /&gt;
                timeout=0)&lt;br /&gt;
    except serial.serialutil.SerialException as e:&lt;br /&gt;
        log(str(e), True)&lt;br /&gt;
        time.sleep(1)&lt;br /&gt;
        continue&lt;br /&gt;
&lt;br /&gt;
    log(&amp;quot;Connected to: &amp;quot; + ser.portstr, True)&lt;br /&gt;
    count=1&lt;br /&gt;
&lt;br /&gt;
    try:&lt;br /&gt;
        line = []&lt;br /&gt;
        while True:&lt;br /&gt;
            for c in ser.readline():&lt;br /&gt;
                line.append(c)&lt;br /&gt;
                if c == &amp;quot;\n&amp;quot;:&lt;br /&gt;
                    log(&amp;quot;&amp;quot;.join(line))&lt;br /&gt;
                    line = []&lt;br /&gt;
    except serial.serialutil.SerialException as e:&lt;br /&gt;
        log(str(e), True)&lt;br /&gt;
        time.sleep(1)&lt;br /&gt;
    ser.close()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== MyBool ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; class NewBool(int):&lt;br /&gt;
...    def __new__(cls, value):&lt;br /&gt;
...        return int.__new__(cls, bool(value))&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; y = NewBool(2)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; y == 1&lt;br /&gt;
True&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
https://jfine-python-classes.readthedocs.io/en/latest/subclass-int.html&lt;br /&gt;
&lt;br /&gt;
Also check out the __cmp__&lt;br /&gt;
&lt;br /&gt;
== md5 ==&lt;br /&gt;
&lt;br /&gt;
 import md5&lt;br /&gt;
 md5.new(&amp;quot;Nobody inspects the spammish repetition&amp;quot;).hexdigest()&lt;br /&gt;
 # &#039;bb649c83dd1ea5c9d9dec9a18df0ffe9&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ echo -n &amp;quot;Nobody inspects the spammish repetition&amp;quot; | md5sum&lt;br /&gt;
bb649c83dd1ea5c9d9dec9a18df0ffe9  -&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== External Libraries ==&lt;br /&gt;
&lt;br /&gt;
=== execnet ===&lt;br /&gt;
&lt;br /&gt;
Python Package Index - execnet - https://pypi.python.org/pypi/execnet&lt;br /&gt;
&lt;br /&gt;
Examples - http://codespeak.net/execnet/examples.html&lt;br /&gt;
* basic local and remote communication - http://codespeak.net/execnet/example/test_info.html&lt;br /&gt;
&lt;br /&gt;
Execute source code in subprocess, communicate through a channel:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import execnet&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; gw = execnet.makegateway()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; channel = gw.remote_exec(&amp;quot;channel.send(channel.receive()+1)&amp;quot;)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; channel.send(1)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; channel.receive()&lt;br /&gt;
2&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Compare current working directories&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import execnet, os&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; gw = execnet.makegateway()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; ch = gw.remote_exec(&amp;quot;import os; channel.send(os.getcwd())&amp;quot;)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; res = ch.receive()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; assert res == os.getcwd()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Get information from remote ssh account&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import execnet, os&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; gw = execnet.makegateway(&amp;quot;ssh=codespeak.net&amp;quot;)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; channel = gw.remote_exec(&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
...     import sys, os&lt;br /&gt;
...     channel.send((sys.platform, sys.version_info, os.getpid()))&lt;br /&gt;
... &amp;quot;&amp;quot;&amp;quot;)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; platform, version_info, remote_pid = channel.receive()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; platform&lt;br /&gt;
&#039;linux2&#039;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; version_info&lt;br /&gt;
(2, 4, 2, &#039;final&#039;, 0)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
remote-exec a function (avoiding inlined source part I)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import execnet&lt;br /&gt;
&lt;br /&gt;
def multiplier(channel, factor):&lt;br /&gt;
    while not channel.isclosed():&lt;br /&gt;
        param = channel.receive()&lt;br /&gt;
        channel.send(param * factor)&lt;br /&gt;
&lt;br /&gt;
gw = execnet.makegateway()&lt;br /&gt;
channel = gw.remote_exec(multiplier, factor=10)&lt;br /&gt;
&lt;br /&gt;
for i in range(5):&lt;br /&gt;
    channel.send(i)&lt;br /&gt;
    result = channel.receive()&lt;br /&gt;
    assert result == i * 10&lt;br /&gt;
&lt;br /&gt;
gw.exit()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
remote-exec a module (avoiding inlined source part II)&lt;br /&gt;
:&amp;quot;You can pass a module object to remote_exec in which case its source code will be sent. No dependencies will be transferred so the module must be self-contained or only use modules that are installed on the “other” side. Module code can detect if it is running in a remote_exec situation by checking for the special __name__ attribute.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# content of a module remote1.py&lt;br /&gt;
&lt;br /&gt;
if __name__ == &#039;__channelexec__&#039;:&lt;br /&gt;
    channel.send(&#039;initialization complete&#039;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import execnet, remote1&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; gw = execnet.makegateway()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; ch = gw.remote_exec(remote1)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; print (ch.receive())&lt;br /&gt;
initialization complete&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use a callback instead of receive() and wait for completion&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import execnet&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; gw = execnet.makegateway()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; channel = gw.remote_exec(&amp;quot;for i in range(10): channel.send(i)&amp;quot;)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; l = []&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; channel.setcallback(l.append, endmarker=None)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; channel.waitclose() # waits for closing, i.e. remote exec finish&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; l&lt;br /&gt;
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, None]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
a simple command loop pattern&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# contents of: remotecmd.py&lt;br /&gt;
import os&lt;br /&gt;
&lt;br /&gt;
def simple(arg):&lt;br /&gt;
    return arg + 1&lt;br /&gt;
&lt;br /&gt;
def listdir(path):&lt;br /&gt;
    return os.listdir(path)&lt;br /&gt;
    &lt;br /&gt;
if __name__ == &#039;__channelexec__&#039;:&lt;br /&gt;
    for item in channel:&lt;br /&gt;
        channel.send(eval(item))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import execnet, remotecmd&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; gw = execnet.makegateway()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; ch = gw.remote_exec(remotecmd)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; ch.send(&#039;simple(10)&#039;) # execute func-call remotely&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; ch.receive()&lt;br /&gt;
11&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== evdev ===&lt;br /&gt;
&lt;br /&gt;
Install:&lt;br /&gt;
 apt-get install python-setuptools python-dev&lt;br /&gt;
 easy_install pip&lt;br /&gt;
 pip install evdev&lt;br /&gt;
&lt;br /&gt;
Simple read usage:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from evdev import InputDevice&lt;br /&gt;
from evdev import ecodes&lt;br /&gt;
&lt;br /&gt;
# look for a /dev/input/by-id/usb...kbd or similar&lt;br /&gt;
DEVICE = &amp;quot;/dev/input/by-id/usb-ORTEK_USB_Keyboard_Hub-event-kbd&amp;quot;&lt;br /&gt;
&lt;br /&gt;
dev = InputDevice(DEVICE)&lt;br /&gt;
&lt;br /&gt;
while True:&lt;br /&gt;
    r, w, x = select([dev], [], [], 5)&lt;br /&gt;
    for event in dev.read():&lt;br /&gt;
        if event.type == 1 and event.value == 1:&lt;br /&gt;
            print event.code&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
List LED states:&lt;br /&gt;
 dev.leds()&lt;br /&gt;
 dev.leds(verbose=True)&lt;br /&gt;
&lt;br /&gt;
Inject usage: (does not appear to really work)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from evdev import InputDevice&lt;br /&gt;
from evdev import ecodes&lt;br /&gt;
from evdev import UInput&lt;br /&gt;
&lt;br /&gt;
DEVICE = &amp;quot;/dev/input/by-id/usb-ORTEK_USB_Keyboard_Hub-event-kbd&amp;quot;&lt;br /&gt;
dev = InputDevice(DEVICE)&lt;br /&gt;
&lt;br /&gt;
ui = UInput()&lt;br /&gt;
&lt;br /&gt;
ui.write(ecodes.EV_KEY, ecodes.KEY_4, 1)&lt;br /&gt;
ui.write(ecodes.EV_KEY, ecodes.KEY_4, 0)&lt;br /&gt;
ui.syn()&lt;br /&gt;
&lt;br /&gt;
ui.write(ecodes.EV_KEY, ecodes.KEY_NUMLOCK, 1)&lt;br /&gt;
ui.write(ecodes.EV_KEY, ecodes.KEY_NUMLOCK, 0)&lt;br /&gt;
ui.syn()&lt;br /&gt;
&lt;br /&gt;
ui.close()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Tutorial:&lt;br /&gt;
* evdev documentation — python-evdev 0.4.3 documentation - http://pythonhosted.org/evdev/index.html&lt;br /&gt;
References:&lt;br /&gt;
* python-evdev/doc/tutorial.rst at master · gvalkov/python-evdev · GitHub - https://github.com/gvalkov/python-evdev/blob/master/doc/tutorial.rst&lt;br /&gt;
&lt;br /&gt;
=== ldap-python ===&lt;br /&gt;
&lt;br /&gt;
python-ldap: LDAP client API for Python - http://www.python-ldap.org/&lt;br /&gt;
&lt;br /&gt;
Index of Packages : Python Package Index - https://pypi.python.org/pypi/python-ldap/&lt;br /&gt;
&lt;br /&gt;
 yum install python-devel openldap-devel&lt;br /&gt;
 pip install python-ldap&lt;br /&gt;
&lt;br /&gt;
Articles:&lt;br /&gt;
* Python LDAP Applications: Part 1 - Installing and Configuring the Python-LDAP Library and Binding to an LDAP Directory | Packt Publishing - http://www.packtpub.com/article/installing-and-configuring-the-python-ldap-library-and-binding-to-an-ldap-directory&lt;br /&gt;
&lt;br /&gt;
=== xmmp ===&lt;br /&gt;
&lt;br /&gt;
PDF:&lt;br /&gt;
* XMPP: The Definitive Guide - Oreilly - http://oriolrius.cat/blog/wp-content/uploads/2009/10/Oreilly.XMPP.The.Definitive.Guide.May.2009.pdf&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
xmmp is the Jabber protocol&lt;br /&gt;
&lt;br /&gt;
Best options:&lt;br /&gt;
&lt;br /&gt;
MIT libraries.&lt;br /&gt;
* sleekxmpp (was: sleekxmpp) is pretty popular and is used for examples in Peter Saint-Andre&#039;s XMPP book from O&#039;Reilly. It reportedly works well, and finally got an email list in April 2010, and has a chat room at sleek@conference.jabber.org.&lt;br /&gt;
&lt;br /&gt;
GPL libraries.&lt;br /&gt;
* xmpppy is used by gajim.&lt;br /&gt;
&lt;br /&gt;
LPGL libraries.&lt;br /&gt;
* pyxmpp is pretty good and uses libxml2 internally for xml parsing.&lt;br /&gt;
* pyxmpp2 is the next version of pyxmpp, runs on python 2.7 and 3.2, and removes the libxml2 requirement. Like many, it requires dnspython.&lt;br /&gt;
* jabberpy is the original and still works for a lot of tasks, but is thoroughly unmaintained.&lt;br /&gt;
&lt;br /&gt;
Other libraries.&lt;br /&gt;
* Wokkel, mentioned in another post. That&#039;s a new one for me, based on twisted.&lt;br /&gt;
&lt;br /&gt;
chat - Best python XMPP / Jabber client library? - Stack Overflow - http://stackoverflow.com/questions/1901828/best-python-xmpp-jabber-client-library&lt;br /&gt;
&lt;br /&gt;
=== xmpppy ===&lt;br /&gt;
&lt;br /&gt;
xmpppy: the jabber python project - http://xmpppy.sourceforge.net/&lt;br /&gt;
&lt;br /&gt;
&amp;quot;xmpppy is a Python library that is targeted to provide easy scripting with Jabber. Similar projects are Twisted Words and jabber.py.&lt;br /&gt;
&lt;br /&gt;
This library was not designed from scratch. It inherits some code from jabberpy and have very similar API in many places. Though it is separate project since it have almost completely different architecture and primarily aims to work with jabberd2 - the new Open Source Jabber Server.&lt;br /&gt;
&lt;br /&gt;
xmpppy is distributed under the terms of GNU General Public License and can be freely redistributed without any charge.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 wget http://sourceforge.net/projects/xmpppy/files/xmpppy/0.4.1/xmpppy-0.4.1.tar.gz/download -O xmpppy-0.4.1.tar.gz&lt;br /&gt;
 tar -zvxf xmpppy-0.4.1.tar.gz&lt;br /&gt;
 pip install pydns&lt;br /&gt;
&lt;br /&gt;
--- basic connection ---&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
 &lt;br /&gt;
import xmpp&lt;br /&gt;
 &lt;br /&gt;
user=&amp;quot;username@gmail.com&amp;quot;&lt;br /&gt;
password=&amp;quot;password&amp;quot;&lt;br /&gt;
server=&amp;quot;gmail.com&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
jid = xmpp.JID(user)&lt;br /&gt;
connection = xmpp.Client(server,debug=[])&lt;br /&gt;
connection.connect()&lt;br /&gt;
result = connection.auth(jid.getNode(), password,&amp;quot;LFY-client&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
connection.sendInitPresence()&lt;br /&gt;
 &lt;br /&gt;
while connection.Process(1):&lt;br /&gt;
    pass&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* Use XMPP to Create Your Own Google Talk Client - LINUX For You - http://www.linuxforu.com/2012/06/use-xmpp-to-create-your-own-google-talk-client/&lt;br /&gt;
&lt;br /&gt;
--- basic receive ---&lt;br /&gt;
&lt;br /&gt;
Print messages when received:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
 &lt;br /&gt;
import xmpp&lt;br /&gt;
 &lt;br /&gt;
user=&amp;quot;username@gmail.com&amp;quot;&lt;br /&gt;
password=&amp;quot;password&amp;quot;&lt;br /&gt;
server=&amp;quot;gmail.com&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
def message_handler(connect_object, message_node):&lt;br /&gt;
        message = &amp;quot;Welcome to my first Gtalk Bot :)&amp;quot;&lt;br /&gt;
        connect_object.send( xmpp.Message( message_node.getFrom() ,message))&lt;br /&gt;
 &lt;br /&gt;
jid = xmpp.JID(user)&lt;br /&gt;
connection = xmpp.Client(server)&lt;br /&gt;
connection.connect()&lt;br /&gt;
result = connection.auth(jid.getNode(), password, &amp;quot;LFY-client&amp;quot;)&lt;br /&gt;
connection.RegisterHandler(&#039;message&#039;, message_handler)&lt;br /&gt;
 &lt;br /&gt;
connection.sendInitPresence()&lt;br /&gt;
 &lt;br /&gt;
while connection.Process(1):&lt;br /&gt;
    pass&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* Use XMPP to Create Your Own Google Talk Client - LINUX For You - http://www.linuxforu.com/2012/06/use-xmpp-to-create-your-own-google-talk-client/&lt;br /&gt;
&lt;br /&gt;
--- remote-control shell bot ---&lt;br /&gt;
&lt;br /&gt;
Replace the simple bot’s message_handler() function with this new one:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def message_handler(connect_object,message_node):&lt;br /&gt;
        command = str(message_node.getBody())&lt;br /&gt;
 &lt;br /&gt;
        process = subprocess.Popen(command,shell=True,stdout=subprocess.PIPE, stderr=subprocess.PIPE)&lt;br /&gt;
        message = process.stdout.read()&lt;br /&gt;
        if message==&amp;quot;&amp;quot;:&lt;br /&gt;
            message=process.stderr.read()&lt;br /&gt;
 &lt;br /&gt;
        connect_object.send( xmpp.Message( message_node.getFrom() ,message))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* Use XMPP to Create Your Own Google Talk Client - LINUX For You - http://www.linuxforu.com/2012/06/use-xmpp-to-create-your-own-google-talk-client/&lt;br /&gt;
&lt;br /&gt;
--- roster ---&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import xmpp&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
userID   = &#039;myname@gmail.com&#039; &lt;br /&gt;
password = &#039;mypassword&#039;&lt;br /&gt;
ressource = &#039;Script&#039;&lt;br /&gt;
&lt;br /&gt;
jid  = xmpp.protocol.JID(userID)&lt;br /&gt;
jabber  = xmpp.Client(jid.getDomain(), debug=[])&lt;br /&gt;
&lt;br /&gt;
connection = jabber.connect((&#039;talk.google.com&#039;,5222))&lt;br /&gt;
auth = jabber.auth(jid.getNode(), password, ressource)&lt;br /&gt;
&lt;br /&gt;
jabber.sendInitPresence(requestRoster=1)&lt;br /&gt;
myroster = jabber.getRoster()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To get status, you have to wait for the other clients to send you their status:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
jabber.RegisterHandler(&#039;presence&#039;, myPresenceHandler)&lt;br /&gt;
&lt;br /&gt;
def myPresenceHandler(con, event):&lt;br /&gt;
  fromjid = event.getFrom().getStripped()&lt;br /&gt;
  status = myroster.getStatus(fromjid)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
python - XMPP chat: accessing contacts&#039; status messages with xmppPy&#039;s Roster - Stack Overflow - http://stackoverflow.com/questions/2381597/xmpp-chat-accessing-contacts-status-messages-with-xmpppys-roster&lt;br /&gt;
&lt;br /&gt;
--- full roster script ---&lt;br /&gt;
&lt;br /&gt;
kparal/jabber-roster · GitHub - https://github.com/kparal/jabber-roster&lt;br /&gt;
&lt;br /&gt;
A simple Python tool for listing your Jabber roster contacts. You can use it to easily backup list of your buddies.&lt;br /&gt;
&lt;br /&gt;
This program is maintained, but not further developed. Bugs will be fixed, but no new features will be added. If you want to work on this program, don&#039;t hesitate to contact me, I will gladly assign you to the development team.&lt;br /&gt;
&lt;br /&gt;
 git clone https://github.com/kparal/jabber-roster&lt;br /&gt;
 python jabber_roster.py&lt;br /&gt;
&lt;br /&gt;
https://pypi.python.org/pypi/jabber-roster&lt;br /&gt;
&lt;br /&gt;
--- vcard ---&lt;br /&gt;
&lt;br /&gt;
This information is not in the roster. You will need to query the clients individually and get their vCard by sending this IQ :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;iq from=&#039;stpeter@jabber.org/roundabout&#039;&lt;br /&gt;
    id=&#039;v1&#039;&lt;br /&gt;
    type=&#039;get&#039;&amp;gt;&lt;br /&gt;
  &amp;lt;vCard xmlns=&#039;vcard-temp&#039;/&amp;gt;&lt;br /&gt;
&amp;lt;/iq&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
My solution:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def vcard(disp, jid):&lt;br /&gt;
    msg = xmpp.protocol.Iq()&lt;br /&gt;
    msg.setType(&#039;get&#039;)&lt;br /&gt;
    msg.setTo(jid)&lt;br /&gt;
    qc = msg.addChild(&#039;vCard&#039;)&lt;br /&gt;
    qc.setAttr(&#039;xmlns&#039;, &#039;vcard-temp&#039;)&lt;br /&gt;
    rep = disp.SendAndWaitForResponse(msg)&lt;br /&gt;
    # to see what other fields are available in the XML output:&lt;br /&gt;
    # print rep&lt;br /&gt;
    userid=fname=lname=title=department=region=None&lt;br /&gt;
    for i in rep.getChildren():&lt;br /&gt;
        for j in i.getChildren():&lt;br /&gt;
            if j.getName() == &amp;quot;TITLE&amp;quot;:&lt;br /&gt;
                title = j.getData().encode(&#039;utf-8&#039;)&lt;br /&gt;
            for k in j.getChildren():&lt;br /&gt;
                if k.getName() == &amp;quot;GIVEN&amp;quot;:&lt;br /&gt;
                    fname = k.getData().encode(&#039;utf-8&#039;)&lt;br /&gt;
                if k.getName() == &amp;quot;FAMILY&amp;quot;:&lt;br /&gt;
                    lname = k.getData().encode(&#039;utf-8&#039;)&lt;br /&gt;
                if k.getName() == &amp;quot;ORGUNIT&amp;quot;:&lt;br /&gt;
                    department = k.getData().encode(&#039;utf-8&#039;)&lt;br /&gt;
                if k.getName() == &amp;quot;REGION&amp;quot;:&lt;br /&gt;
                    region = k.getData().encode(&#039;utf-8&#039;)&lt;br /&gt;
    return fname, lname, title, department, region&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* xmpppy - Retrieve gtalk nickname in python xmpp - Stack Overflow - http://stackoverflow.com/questions/4539477/retrieve-gtalk-nickname-in-python-xmpp&lt;br /&gt;
* XEP-0054: vcard-temp - http://xmpp.org/extensions/xep-0054.html&lt;br /&gt;
&lt;br /&gt;
=== google-api-python-client ===&lt;br /&gt;
&lt;br /&gt;
Google APIs Client Library for Python, which includes:&lt;br /&gt;
* google-api-python-client: The core Python library for accessing Google APIs.&lt;br /&gt;
* oauth2client: A Python client library for OAuth 2.0.&lt;br /&gt;
* Sample applications using google-api-python-client and oauth2client &lt;br /&gt;
&lt;br /&gt;
-&lt;br /&gt;
&lt;br /&gt;
https://developers.google.com/api-client-library/python/start/installation&lt;br /&gt;
* Calendar API - Python/Command Line&lt;br /&gt;
&lt;br /&gt;
-&lt;br /&gt;
Download:&lt;br /&gt;
 wget https://code.google.com/p/google-api-python-client/downloads/detail?name=google-api-python-client-1.2.zip&lt;br /&gt;
 wget https://code.google.com/p/google-api-python-client/downloads/detail?name=oauth2client-1.2.zip&lt;br /&gt;
&lt;br /&gt;
Git:&lt;br /&gt;
 git clone https://github.com/google/google-api-python-client&lt;br /&gt;
 git clone https://github.com/google/oauth2client&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* google-api-python-client - Google APIs Client Library for Python - Google Project Hosting - https://code.google.com/p/google-api-python-client/&lt;br /&gt;
&lt;br /&gt;
== Documentation Tools ==&lt;br /&gt;
&lt;br /&gt;
=== pydoc ===&lt;br /&gt;
&lt;br /&gt;
pydoc - http://docs.python.org/library/pydoc.html&lt;br /&gt;
: Documentation generator and online help system&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Doxygen and Doxypy ===&lt;br /&gt;
&lt;br /&gt;
See [[Python/Doxygen]]&lt;br /&gt;
&lt;br /&gt;
=== Sphinx ===&lt;br /&gt;
&lt;br /&gt;
Sphinx - http://sphinx.pocoo.org/&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Sphinx is a tool that makes it easy to create intelligent and beautiful documentation, written by Georg Brandl and licensed under the BSD license.&lt;br /&gt;
&lt;br /&gt;
It was originally created for the new Python documentation, and it has excellent facilities for the documentation of Python projects, but C/C++ is already supported as well, and it is planned to add special support for other languages as well. Of course, this site is also created from reStructuredText sources using Sphinx!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== epydoc ===&lt;br /&gt;
&lt;br /&gt;
epydoc - http://epydoc.sourceforge.net/&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Epydoc is a tool for generating API documentation for Python modules, based on their docstrings. For an example of epydoc&#039;s output, see the API documentation for epydoc itself (html, pdf). A lightweight markup language called epytext can be used to format docstrings, and to add information about specific fields, such as parameters and instance variables. Epydoc also understands docstrings written in reStructuredText, Javadoc, and plaintext. For a more extensive example of epydoc&#039;s output, see the API documentation for Python 2.5. &amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Python 3 ==&lt;br /&gt;
&lt;br /&gt;
=== Python 3 Wall of Superpowers ===&lt;br /&gt;
&lt;br /&gt;
Python 3 Wall of Superpowers - https://python3wos.appspot.com/&lt;br /&gt;
&lt;br /&gt;
&amp;quot;As listed on PyPI - packages in red don&#039;t support python 3, packages in green do. Hopefully one day everything will be greener. &amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== New in Python 3 ===&lt;br /&gt;
&lt;br /&gt;
==== qualnames ====&lt;br /&gt;
&lt;br /&gt;
New in 3.3&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; def f():&lt;br /&gt;
...   def g():&lt;br /&gt;
...     class H: pass&lt;br /&gt;
...     return H&lt;br /&gt;
...   return g&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; H=f()()&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; # 3.3:&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; H&lt;br /&gt;
&amp;lt;class &#039;__main__.f.&amp;lt;locals&amp;gt;.g.&amp;lt;locals&amp;gt;.H&#039;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; H.__qualname__&lt;br /&gt;
&#039;f.&amp;lt;locals&amp;gt;.g.&amp;lt;locals&amp;gt;.H&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; # 2.6:&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; H&lt;br /&gt;
&amp;lt;class __main__.H at 0x2b885044b890&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; H.__qualname__&lt;br /&gt;
AttributeError: class H has no attribute &#039;__qualname__&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Python 2 or Python 3 ==&lt;br /&gt;
&lt;br /&gt;
Python2orPython3 - PythonInfo Wiki - http://wiki.python.org/moin/Python2orPython3&lt;br /&gt;
:Short version: Python 2.x is the status quo, Python 3.x is the shiny new thing.&lt;br /&gt;
:At the time of writing (July 4, 2010), the final 2.7 release is out, with a statement of extended support for this end-of-life release. The 2.x branch will see no new major releases after that. 3.x is under active and continued development, with 3.1 already available and 3.2 due for release around the turn of the year.&lt;br /&gt;
&lt;br /&gt;
Python 2.7.1 Release - http://www.python.org/download/releases/2.7.1/&lt;br /&gt;
&lt;br /&gt;
What’s New In Python 3.0 — Python v3.0.1 documentation - http://docs.python.org/release/3.0.1/whatsnew/3.0.html&lt;br /&gt;
* print() requires parenthesis&lt;br /&gt;
* raw_input() is now input()&lt;br /&gt;
&lt;br /&gt;
== Python for Windows ==&lt;br /&gt;
&lt;br /&gt;
Python for Windows - http://www.python.org/download/windows/&lt;br /&gt;
&lt;br /&gt;
=== Windows IDEs ===&lt;br /&gt;
&lt;br /&gt;
==== PyCharm ====&lt;br /&gt;
&lt;br /&gt;
 http://www.pycharm.com/&lt;br /&gt;
&lt;br /&gt;
=== Hide Console ===&lt;br /&gt;
&lt;br /&gt;
fork() does not work on windows.  So what else can we do?&lt;br /&gt;
&lt;br /&gt;
How to hide console window in python? - http://stackoverflow.com/questions/764631/how-to-hide-console-window-in-python&lt;br /&gt;
* &amp;quot;Simply save it with a .pyw extension. This will prevent the console window from opening. Explanation at the bottom of section [http://docs.python.org/2/tutorial/interpreter.html#executable-python-scripts]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== 32bit vs 64bit ===&lt;br /&gt;
&lt;br /&gt;
IDLE:&lt;br /&gt;
&lt;br /&gt;
32bit:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
C:\Python27&amp;gt;python&lt;br /&gt;
Python 2.7.6 (default, Nov 10 2013, 19:24:18) [MSC v.1500 32 bit (Intel)] on win32&lt;br /&gt;
Type &amp;quot;help&amp;quot;, &amp;quot;copyright&amp;quot;, &amp;quot;credits&amp;quot; or &amp;quot;license&amp;quot; for more information.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
64bit: (note: default path is C:\Python27)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
C:\Python27-64bit&amp;gt;python.exe&lt;br /&gt;
Python 2.7.6 (default, Nov 10 2013, 19:24:24) [MSC v.1500 64 bit (AMD64)] on win32&lt;br /&gt;
Type &amp;quot;help&amp;quot;, &amp;quot;copyright&amp;quot;, &amp;quot;credits&amp;quot; or &amp;quot;license&amp;quot; for more information.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Task Manager:&lt;br /&gt;
 python.exe *32&lt;br /&gt;
&lt;br /&gt;
 python.exe&lt;br /&gt;
&lt;br /&gt;
Platform:&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; import platform&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; platform.python_compiler()&lt;br /&gt;
 &#039;MSC v.1500 32 bit (Intel)&#039;&lt;br /&gt;
&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; import platform&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; platform.python_compiler()&lt;br /&gt;
 &#039;MSC v.1500 64 bit (AMD64)&#039;&lt;br /&gt;
&lt;br /&gt;
Code: [http://stackoverflow.com/questions/2208828/detect-64bit-os-windows-in-python]&lt;br /&gt;
 import struct&lt;br /&gt;
 def is_python_64bit():&lt;br /&gt;
     return (struct.calcsize(&amp;quot;P&amp;quot;) == 8)&lt;br /&gt;
&lt;br /&gt;
=== Stand-Alone Executable ===&lt;br /&gt;
&lt;br /&gt;
==== Python ZIP Application ====&lt;br /&gt;
&lt;br /&gt;
Python can be run from a single bundled zip file - similar to a Java WAR!  Python has been able to (Allow interpreter to execute a zip file http://bugs.python.org/issue1739468)&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Python quietly added a new feature in 2.6 that makes it possible to bundle up a directory full of Python code into a single executable file.&amp;quot; [http://blog.ablepear.com/2012/10/bundling-python-files-into-stand-alone.html]&lt;br /&gt;
&lt;br /&gt;
When a python zip application is executed, it will execute &#039;__main__.py&#039; [http://docs.python.org/using/cmdline.html#interface-options]&lt;br /&gt;
&lt;br /&gt;
 mkdir app&lt;br /&gt;
 touch app/__main__.py&lt;br /&gt;
 cd app&lt;br /&gt;
 zip -r ../app.zip *&lt;br /&gt;
 cd ..&lt;br /&gt;
 python app.zip&lt;br /&gt;
&lt;br /&gt;
Load a resource - The easiest way to find and load a program bundle like this is to use the pkg_resources module. - http://packages.python.org/distribute/pkg_resources.html&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# file: app/__main__.py&lt;br /&gt;
&lt;br /&gt;
import pkg_resources&lt;br /&gt;
&lt;br /&gt;
def main():&lt;br /&gt;
  print(&#039;The rain in Spain falls mainly in the plain.&#039;)&lt;br /&gt;
  print(pkg_resources.resource_string(&#039;resources&#039;, &#039;inFrance.txt&#039;))&lt;br /&gt;
&lt;br /&gt;
if __name__ == &#039;__main__&#039;:&lt;br /&gt;
  main()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now use a bit of UNIX magic to turn app2.zip into an executable:&lt;br /&gt;
 echo &#039;#!/usr/bin/env python&#039; | cat - app2.zip &amp;gt; app2&lt;br /&gt;
 chmod +x app2&lt;br /&gt;
&lt;br /&gt;
&amp;quot;The zip file format is designed to allow a small executable program to be inserted at the front (that&#039;s how self-extracting zip files are created), so this is kosher and doesn&#039;t corrupt the zip file.&amp;quot; [http://blog.ablepear.com/2012/10/bundling-python-files-into-stand-alone.html]&lt;br /&gt;
&lt;br /&gt;
Now you can simply run app2 like any executable.&lt;br /&gt;
 $ ./app2&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* Able Pear Software: Bundling Python files into a stand-alone executable - http://blog.ablepear.com/2012/10/bundling-python-files-into-stand-alone.html&lt;br /&gt;
* PEP 441 -- Improving Python ZIP Application Support - http://www.python.org/dev/peps/pep-0441/&lt;br /&gt;
* Issue 1739468: Allow interpreter to execute a zip file - Python tracker - http://bugs.python.org/issue1739468&lt;br /&gt;
* Package Discovery and Resource Access using pkg_resources — Distribute documentation - http://packages.python.org/distribute/pkg_resources.html&lt;br /&gt;
&lt;br /&gt;
==== Shell Python Loader ====&lt;br /&gt;
&lt;br /&gt;
Came before the Python ZIP Application support.&lt;br /&gt;
&lt;br /&gt;
Python zip exe - Noah.org - http://www.noah.org/wiki/Python_zip_exe&lt;br /&gt;
&lt;br /&gt;
&amp;quot;This takes your Python application and packages it into a single executable shell script. You application can be made of up multiple python scripts. The executable shell script is also compressed, so the resulting script is smaller than the original. This should work on any system that has Python and a Bourne shell (works on Cygwin too). Note that this does not package the Python interpreter into the executable. This packages only you python code into a zip file, but this still allows you to distribute your application as a single shell script that will run on any system with Python installed.  In theory, you could zip the .pyc files, but the byte code is guaranteed to run only on exactly the same version Python interpreter (including minor version). It is safer to just package the .py files.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
First you need to zip all your python files:&lt;br /&gt;
 zip main.zip main.py spam.py eggs.py&lt;br /&gt;
&lt;br /&gt;
zipheader.sh:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/sh&lt;br /&gt;
# This is a self-extracting executable.&lt;br /&gt;
# Execute this like any normal executable.&lt;br /&gt;
# You may need to &amp;quot;chmod a+x&amp;quot; this file.&lt;br /&gt;
# This is a binary ZIP file with a Python loader header.&lt;br /&gt;
#&lt;br /&gt;
# Bourne shell loader:&lt;br /&gt;
PYTHON=$(which python 2&amp;gt;/dev/null)&lt;br /&gt;
if [ ! -x &amp;quot;$PYTHON&amp;quot; ] ; then&lt;br /&gt;
    echo &amp;quot;Python not found!&amp;quot;&lt;br /&gt;
    exit 1&lt;br /&gt;
fi&lt;br /&gt;
exec $PYTHON -c &amp;quot;&lt;br /&gt;
# Python loader:&lt;br /&gt;
import sys, os&lt;br /&gt;
if int(sys.version[0])&amp;lt;2:&lt;br /&gt;
    print &#039;Python version 2.3 final or greater is required.&#039;&lt;br /&gt;
    print &#039;Your version is&#039;, sys.version&lt;br /&gt;
    os._exit(1)&lt;br /&gt;
major = sys.version_info[0]&lt;br /&gt;
minor = sys.version_info[1]&lt;br /&gt;
releaselevel = sys.version_info[3]&lt;br /&gt;
if (major==2 and minor&amp;lt;3) or (major==2 and minor==3 and releaselevel!=&#039;final&#039;):&lt;br /&gt;
    print &#039;Python version 2.3 final or greater is required.&#039;&lt;br /&gt;
    print &#039;Your version is&#039;, sys.version&lt;br /&gt;
    os._exit(1)&lt;br /&gt;
sys.path.insert(0, sys.argv[1])&lt;br /&gt;
del sys.argv[0:1]&lt;br /&gt;
import main&lt;br /&gt;
main.main()&lt;br /&gt;
&amp;quot; $0 $@&lt;br /&gt;
# Zip file:&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Concatinate zipheader.sh with the zip file.&lt;br /&gt;
 cat zipheader.sh main.zip &amp;gt; main&lt;br /&gt;
&lt;br /&gt;
Set main as executable.&lt;br /&gt;
 chmod +x main&lt;br /&gt;
&lt;br /&gt;
&amp;quot;This is an improvement on Joerg Raedler&#039;s Python recipe, [http://code.activestate.com/recipes/215301-binding-main-skript-and-modules-to-one-executable-/ 215301]. The original closes stdin. The herefile in the shell script redirects stdin before python gets a chance to start. This disables raw_input() and anything else that reads sys.stdin. Unfortunately, Raedler&#039;s boot script closes stdin, which is a fairly big limitation. The herefile in the shell script (END_OF_PYTHON_CODE) redirects stdin before python starts; stdin is closed at the end of the herefile. This disables raw_input() and anything else that reads sys.stdin. &amp;quot;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* Python zip exe - Noah.org - http://www.noah.org/wiki/Python_zip_exe&lt;br /&gt;
* Build a compressed self-extracting executable script on UNIX « Python recipes « ActiveState Code - http://code.activestate.com/recipes/497000-build-a-compressed-self-extracting-executable-scri/&lt;br /&gt;
* binding main skript and modules to one executable with python-2.3 under UNIX « Python recipes « ActiveState Code - http://code.activestate.com/recipes/215301-binding-main-skript-and-modules-to-one-executable-/&lt;br /&gt;
&lt;br /&gt;
==== py2exe ====&lt;br /&gt;
&lt;br /&gt;
py2exe - http://www.py2exe.org/&lt;br /&gt;
: &amp;quot;py2exe is a Python Distutils extension which converts Python scripts into executable Windows programs, able to run without requiring a Python installation. &amp;quot;&lt;br /&gt;
&lt;br /&gt;
Tutorial - http://www.py2exe.org/index.cgi/Tutorial&lt;br /&gt;
&lt;br /&gt;
Note: Install the version that matches your version of python&lt;br /&gt;
&lt;br /&gt;
Note: run installer &amp;quot;as administrator&amp;quot;&lt;br /&gt;
&lt;br /&gt;
setup.py&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from distutils.core import setup&lt;br /&gt;
import py2exe&lt;br /&gt;
&lt;br /&gt;
setup(console=[&#039;hello.py&#039;])&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
No console window version: [http://ubuntuforums.org/showthread.php?t=728170] [http://stackoverflow.com/questions/3275293/hiding-console-window-of-python-gui-app-with-py2exe]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from distutils.core import setup&lt;br /&gt;
import py2exe&lt;br /&gt;
&lt;br /&gt;
setup(windows=[&#039;hello.py&#039;])&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Build:&lt;br /&gt;
 python setup.py py2exe&lt;br /&gt;
&lt;br /&gt;
pygame is more complex: http://www.pygame.org/wiki/Pygame2exe&lt;br /&gt;
&lt;br /&gt;
==== py2app ====&lt;br /&gt;
&lt;br /&gt;
==== pyinstaller ====&lt;br /&gt;
&lt;br /&gt;
==== cx_Freeze ====&lt;br /&gt;
&lt;br /&gt;
=== Windows Libraries ===&lt;br /&gt;
&lt;br /&gt;
==== Python for Windows Extensions - PyWin32 ====&lt;br /&gt;
&lt;br /&gt;
Python for Windows Extensions - http://starship.python.net/~skippy/win32/&lt;br /&gt;
* There is a build for each python version and architecture (32bit vs 64bit)&lt;br /&gt;
&lt;br /&gt;
Follow event viewer&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import win32evtlog  # install Python for Windows Extensions - http://starship.python.net/~skippy/win32/&lt;br /&gt;
&lt;br /&gt;
# open event viewer&lt;br /&gt;
server = &amp;quot;localhost&amp;quot;&lt;br /&gt;
source = &amp;quot;System&amp;quot;&lt;br /&gt;
handle = win32evtlog.OpenEventLog(server, source)&lt;br /&gt;
&lt;br /&gt;
# seek to end of log&lt;br /&gt;
flags = win32evtlog.EVENTLOG_BACKWARDS_READ | win32evtlog.EVENTLOG_SEQUENTIAL_READ&lt;br /&gt;
events = win32evtlog.ReadEventLog(handle, flags, 0)&lt;br /&gt;
&lt;br /&gt;
# return to normal reading direction&lt;br /&gt;
flags = win32evtlog.EVENTLOG_FORWARDS_READ | win32evtlog.EVENTLOG_SEQUENTIAL_READ&lt;br /&gt;
win32evtlog.ReadEventLog(handle, flags, 0)  # ignore initial logs&lt;br /&gt;
&lt;br /&gt;
# loop through events&lt;br /&gt;
while True:&lt;br /&gt;
    events = win32evtlog.ReadEventLog(handle, flags, 0)&lt;br /&gt;
    if events:&lt;br /&gt;
        for event in events:&lt;br /&gt;
            data = event.StringInserts&lt;br /&gt;
            if data:&lt;br /&gt;
                # Example: 07/03/14 12:34:35 - MYEVENTSOURCE - 0 - 1 - 4  &amp;quot;HELLO&amp;quot;&lt;br /&gt;
                print event.TimeGenerated, &#039;-&#039;, event.SourceName, &#039;-&#039;, event.EventCategory, &#039;-&#039;, event.EventID, &#039;-&#039;, event.EventType, &#039;-&#039;, &#039;&amp;quot;%s&amp;quot;&#039; % &amp;quot; &amp;quot;.join(data)&lt;br /&gt;
    time.sleep(.5)  # yield cpu&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* PyWin32: Getting Windows Event Logs « The Mouse Vs. The Python - http://www.blog.pythonlibrary.org/2010/07/27/pywin32-getting-windows-event-logs/&lt;br /&gt;
&lt;br /&gt;
==== PyCrypto for Windows ====&lt;br /&gt;
&lt;br /&gt;
Download Install: http://www.voidspace.org.uk/python/modules.shtml#pycrypto&lt;br /&gt;
&lt;br /&gt;
Installation: [http://stackoverflow.com/questions/11405549/how-do-i-install-pycrypto-on-windows]&lt;br /&gt;
 easy_install http://www.voidspace.org.uk/downloads/pycrypto26/pycrypto-2.6.win32-py2.7.exe&lt;br /&gt;
 easy_install http://www.voidspace.org.uk/downloads/pycrypto26/pycrypto-2.6.win-amd64-py2.7.exe&lt;br /&gt;
&lt;br /&gt;
==== Paramiko for Windows ====&lt;br /&gt;
&lt;br /&gt;
# Install PyCrypto (above)&lt;br /&gt;
# pip install paramiko&lt;br /&gt;
&lt;br /&gt;
==== PyGame for Windows ====&lt;br /&gt;
&lt;br /&gt;
Download - http://www.pygame.org/download.shtml&lt;br /&gt;
* http://pygame.org/ftp/pygame-1.9.1.win32-py2.7.msi&lt;br /&gt;
&lt;br /&gt;
== Indentation ==&lt;br /&gt;
&lt;br /&gt;
Python: Myths about Indentation - http://www.secnetix.de/olli/Python/block_indentation.hawk&lt;br /&gt;
:There are quite some prejudices and myths about Python&#039;s indentation rules among people who don&#039;t really know Python. I&#039;ll try to address a few of these concerns on this page. &lt;br /&gt;
*&amp;quot;Whitespace is significant in Python source code.&amp;quot;&lt;br /&gt;
*&amp;quot;Python forces me to use a certain indentation style.&amp;quot;&lt;br /&gt;
*&amp;quot;You cannot safely mix tabs and spaces in Python.&amp;quot;&lt;br /&gt;
*&amp;quot;I just don&#039;t like it.&amp;quot;&lt;br /&gt;
*&amp;quot;How does the compiler parse the indentation?&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== PEP - Python Enhancement Proposals ==&lt;br /&gt;
&lt;br /&gt;
Python Enhancement Proposals (PEPs)&lt;br /&gt;
&lt;br /&gt;
* Index of Python Enhancement Proposals (PEPs) - http://www.python.org/dev/peps/&lt;br /&gt;
&lt;br /&gt;
== Convert Tabs to Spaces ==&lt;br /&gt;
&lt;br /&gt;
Convert tabs to 4 spaces:&lt;br /&gt;
 sed -i &#039;s/\t/    /g&#039;  script.py&lt;br /&gt;
&lt;br /&gt;
== Linting ==&lt;br /&gt;
&lt;br /&gt;
* pep8 - python style guide checker&lt;br /&gt;
* pychecker - more verbose, imports code, slower&lt;br /&gt;
* pylint - most verbose, configurable, &amp;quot;rates&amp;quot; code&lt;br /&gt;
* pyflakes - least verbose (dead/redundant code)&lt;br /&gt;
&lt;br /&gt;
rpmforge:&lt;br /&gt;
 yum install pyflakes pychecker&lt;br /&gt;
 # pylint - not sure which pacakge includes&lt;br /&gt;
&lt;br /&gt;
=== pep8 ===&lt;br /&gt;
&lt;br /&gt;
See [[Python/pep8]]&lt;br /&gt;
&lt;br /&gt;
=== pychecker ===&lt;br /&gt;
&lt;br /&gt;
See [[Python/pychecker]]&lt;br /&gt;
&lt;br /&gt;
=== pylint ===&lt;br /&gt;
&lt;br /&gt;
See [[Python/pylint]]&lt;br /&gt;
&lt;br /&gt;
== PEP8 Style Guidlines ==&lt;br /&gt;
&lt;br /&gt;
PEP 8 -- Style Guide for Python Code - http://www.python.org/dev/peps/pep-0008/&lt;br /&gt;
&lt;br /&gt;
* Use spaces - Use 4 spaces per indentation level.&lt;br /&gt;
* Never mix tabs and spaces.&lt;br /&gt;
* Limit all lines to a maximum of 79 characters.&lt;br /&gt;
* Line wrapping - The preferred way of wrapping long lines is by using Python&#039;s implied line continuation inside parentheses, brackets and braces.  Long lines can be broken over multiple lines by wrapping expressions in parentheses.&lt;br /&gt;
* Encoding - For Python 3.0 and beyond, UTF-8 is preferred over Latin-1, see PEP 3120.&lt;br /&gt;
* Imports should usually be on separate lines&lt;br /&gt;
* Avoid extraneous whitespace in most situations&lt;br /&gt;
* Always use &#039;self&#039; for the first argument to instance methods.&lt;br /&gt;
&lt;br /&gt;
=== PEP8 Style Checker ===&lt;br /&gt;
&lt;br /&gt;
See [[#pep8]]&lt;br /&gt;
&lt;br /&gt;
== Benefits of Python ==&lt;br /&gt;
&lt;br /&gt;
What is the return on investment for this group by learning Python? The list of benefits below sums up what the language has to offer:&lt;br /&gt;
* Python is designed from the ground up to encourage maintainable, readable and reusable code. It has great support for particular paradigms such as object-oriented programming.&lt;br /&gt;
* Python code is usually around a quarter of the length of code generated by C++ or Java - less typing, less debugging and less maintenance.&lt;br /&gt;
* Python does not need to be compiled or linked, which allows for a more iterative programming style and a quicker development cycle.&lt;br /&gt;
* Python is extremely portable. Code can be easily exchanged between Windows, Mac OS and Linux with little to no modification.&lt;br /&gt;
* Python comes with a staggering array of standard libraries and mature third-party projects. Web development, scientific computing, operator system access and network scripting are all supported.&lt;br /&gt;
* Python can talk with many other languages easily. It has support for invoking C and C++ code and can itself be called from libraries written in these languages. &lt;br /&gt;
&lt;br /&gt;
Source: http://quantstart.com/articles/Quant-Reading-List-Python-Programming/ - Quant Reading List Python Programming&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Benefits of Python:&lt;br /&gt;
* Python is available for most operating systems, including Windows, UNIX, Linux, and Mac OS.&lt;br /&gt;
* Python&#039;s clean object-oriented design and extensive support libraries offer two to ten fold the programmer productivity seen with languages like C, C++, C#, Java, VB, and Perl.&lt;br /&gt;
&lt;br /&gt;
Source: Python Development - Benefits of Python - Digital Mesh - http://www.digitalmesh.com/offshore-development-center/python-development/benefits-of-python.html&lt;br /&gt;
&lt;br /&gt;
== Python Package Management ==&lt;br /&gt;
&lt;br /&gt;
=== Install Module ===&lt;br /&gt;
&lt;br /&gt;
Installing Python Modules — Python v2.7.1 documentation - http://docs.python.org/install/index.html&lt;br /&gt;
&lt;br /&gt;
The new standard: Distutils&lt;br /&gt;
 python setup.py install&lt;br /&gt;
&lt;br /&gt;
Download and extract target package, then:&lt;br /&gt;
 sudo python setup.py install&lt;br /&gt;
&lt;br /&gt;
Note: Running setup.py install builds and installs all modules in one run&lt;br /&gt;
&lt;br /&gt;
Help:&lt;br /&gt;
 python setup.py --help&lt;br /&gt;
&lt;br /&gt;
Incremental method:&lt;br /&gt;
 python setup.py build&lt;br /&gt;
 python setup.py install&lt;br /&gt;
 python setup.py build --help   # help&lt;br /&gt;
&lt;br /&gt;
Force rebuild and install:&lt;br /&gt;
 python setup.py build --force    # if have to repeat&lt;br /&gt;
 python setup.py install --force  # if have to repeat&lt;br /&gt;
&lt;br /&gt;
Default installation paths:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Platform	Standard installation location		Default value&lt;br /&gt;
Unix (pure)	prefix/lib/pythonX.Y/site-packages	/usr/local/lib/pythonX.Y/site-packages&lt;br /&gt;
Unix (non-pure)	exec-prefix/lib/pythonX.Y/site-packages	/usr/local/lib/pythonX.Y/site-packages&lt;br /&gt;
Windows		prefix					C:\Python&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alternate install path:&lt;br /&gt;
 python setup.py install --home=&amp;lt;dir&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alternate base folders:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Type of file			Installation Directory	Override option&lt;br /&gt;
pure module distribution	home/lib/python		--install-purelib&lt;br /&gt;
non-pure module distribution	home/lib/python		--install-platlib&lt;br /&gt;
scripts				home/bin		--install-scripts&lt;br /&gt;
data				home/share		--install-data&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Modifying Python’s Search Path:&lt;br /&gt;
 import sys&lt;br /&gt;
 sys.path.append(&#039;/www/python/&#039;)&lt;br /&gt;
&lt;br /&gt;
=== Python Package Index ===&lt;br /&gt;
&lt;br /&gt;
user-submitted Python packages:&lt;br /&gt;
 http://pypi.python.org/pypi&lt;br /&gt;
&lt;br /&gt;
 sudo python setup.py install&lt;br /&gt;
&lt;br /&gt;
Package Site:&lt;br /&gt;
 http://pypi.python.org/pypi/[PACKAGE]&lt;br /&gt;
 http://pypi.python.org/pypi/test&lt;br /&gt;
&lt;br /&gt;
If they are on http://pypi.python.org/:&lt;br /&gt;
 pip install foo&lt;br /&gt;
&lt;br /&gt;
[http://stackoverflow.com/questions/410163/for-python-programmers-is-there-anything-equivalent-to-perls-cpan For Python programmers, is there anything equivalent to Perl&#039;s CPAN? - Stack Overflow]&lt;br /&gt;
&lt;br /&gt;
=== Easy Installation ===&lt;br /&gt;
&lt;br /&gt;
EasyInstall - The PEAK Developers&#039; Center - http://peak.telecommunity.com/DevCenter/EasyInstall&lt;br /&gt;
: Easy Install is a python module (easy_install) bundled with setuptools that lets you automatically download, build, install, and manage Python packages.&lt;br /&gt;
&lt;br /&gt;
CheeseShopTutorial - PythonInfo Wiki - http://wiki.python.org/moin/CheeseShopTutorial&lt;br /&gt;
: EasyInstall (easy_install) gives you a quick and painless way to install packages remotely by connecting to the Package Index or even other websites via HTTP. It is somewhat analogous to the CPAN and PEAR tools for Perl and PHP, respectively.&lt;br /&gt;
&lt;br /&gt;
=== pip ===&lt;br /&gt;
&lt;br /&gt;
See [[Python/pip]]&lt;br /&gt;
&lt;br /&gt;
==== Create PIP Package ====&lt;br /&gt;
&lt;br /&gt;
See [[Python/pip#Create PIP Package]]&lt;br /&gt;
&lt;br /&gt;
=== Distribute ===&lt;br /&gt;
&lt;br /&gt;
distribute - Easily download, build, install, upgrade, and uninstall Python packages&lt;br /&gt;
&lt;br /&gt;
distribute 0.6.24 : Python Package Index - http://pypi.python.org/pypi/distribute&lt;br /&gt;
&lt;br /&gt;
Installation:&lt;br /&gt;
 mkdir -p ~/.src ; cd ~/.src&lt;br /&gt;
 wget http://pypi.python.org/packages/source/d/distribute/distribute-0.6.24.tar.gz#md5=17722b22141aba8235787f79800cc452&lt;br /&gt;
 tar -zvxf distribute-0.6.24.tar.gz&lt;br /&gt;
 cd distribute-0.6.24&lt;br /&gt;
 sudo python setup.py install&lt;br /&gt;
&lt;br /&gt;
Test:&lt;br /&gt;
 echo &amp;quot;import distribute&amp;quot; | grep python&lt;br /&gt;
&lt;br /&gt;
== Named Parameters ==&lt;br /&gt;
&lt;br /&gt;
http://diveintopython.org/power_of_introspection/optional_arguments.html&lt;br /&gt;
&lt;br /&gt;
Python allows function arguments to have default values; if the function is called without the argument, the argument gets its default value. Futhermore, arguments can be specified in any order by using named arguments. Stored procedures in SQL Server Transact/SQL can do this, so if you&#039;re a SQL Server scripting guru, you can skim this part.&lt;br /&gt;
&lt;br /&gt;
Here is an example of info, a function with two optional arguments:&lt;br /&gt;
&lt;br /&gt;
 def info(object, spacing=10, collapse=1):&lt;br /&gt;
&lt;br /&gt;
spacing and collapse are optional, because they have default values defined. object is required, because it has no default value. If info is called with only one argument, spacing defaults to 10 and collapse defaults to 1. If info is called with two arguments, collapse still defaults to 1.&lt;br /&gt;
&lt;br /&gt;
Say you want to specify a value for collapse but want to accept the default value for spacing. In most languages, you would be out of luck, because you would need to call the function with three arguments. But in Python, arguments can be specified by name, in any order. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
http://www.wellho.net/mouth/1871_Optional-and-named-parameters-in-Python.html&lt;br /&gt;
&lt;br /&gt;
If you add a parameter with two asterixes (**) on the end of a function definition, that parameter is taken as being the name of a dictionary into which all otherwise unidentified parameters are stored. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def getnet(gross, taxrate=17.5, **others):&lt;br /&gt;
  net = gross / (1.0 + taxrate*0.01)&lt;br /&gt;
  for more in others.keys():&lt;br /&gt;
    print &amp;quot;GETNET:&amp;quot;,more,&amp;quot; - &amp;quot;,others[more]&lt;br /&gt;
  return neto&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Python vs other languages ==&lt;br /&gt;
&lt;br /&gt;
[http://www.strombergers.com/python/ Python is Cool (and Perl is not), Especially for C/C++ Programmers]&lt;br /&gt;
&lt;br /&gt;
==Experimenting with Memory Remanence==&lt;br /&gt;
[http://citp.princeton.edu/memory/exp/ Experimenting with Memory Remanence]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    #!/usr/bin/env python&lt;br /&gt;
&lt;br /&gt;
    # a pirate&#039;s favorite chemical element&lt;br /&gt;
    a = &amp;quot;&amp;quot;&lt;br /&gt;
    while 1: a += &amp;quot;ARGON&amp;quot; &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 sudo strings /dev/mem | less&lt;br /&gt;
&lt;br /&gt;
==UTOSC 2008 - 90 percent of the Python you need to know (in 90 minutes)==&lt;br /&gt;
See [[UTOSC 2008 - 90 percent of the Python you need to know (in 90 minutes)]]&lt;br /&gt;
&lt;br /&gt;
== Program Layout Best Practices Presentation ==&lt;br /&gt;
&lt;br /&gt;
Program layout best practices - Seth House &amp;lt;seth@eseth.com&amp;gt; - Utah Django User Group - 2011-06-23&lt;br /&gt;
* Slides - https://github.com/whiteinge/presentations/tree/master/upyug_2011-06-09_program-layout&lt;br /&gt;
* Video - http://blip.tv/utah-open-source/python-layout-best-practices-for-modules-django-cli-utah-django-user-group-5315808&lt;br /&gt;
&lt;br /&gt;
Module skeleton:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
# coding: utf-8&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;Module docstring&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
__author__ = ’Mr. Me &amp;lt;me@example.net&amp;gt;’&lt;br /&gt;
__version__ = ’1.2.3’&lt;br /&gt;
&lt;br /&gt;
if __name__==’__main__’:&lt;br /&gt;
 main()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Executing modules as scripts&lt;br /&gt;
 # PEP 338:&lt;br /&gt;
 python -m SimpleHTTPServer&lt;br /&gt;
&lt;br /&gt;
== CLI package ==&lt;br /&gt;
&lt;br /&gt;
cli — command line tools — pyCLI v1.1.1 documentation - http://packages.python.org/pyCLI/&lt;br /&gt;
&lt;br /&gt;
== Python IDE ==&lt;br /&gt;
&lt;br /&gt;
IntegratedDevelopmentEnvironments - PythonInfo Wiki - http://wiki.python.org/moin/IntegratedDevelopmentEnvironments&lt;br /&gt;
* IDEs with introspection-based code completion and integrated debugger&lt;br /&gt;
* IDEs with introspection-based code completion /or/ integrated debugger&lt;br /&gt;
* IDEs with integrated gui builder&lt;br /&gt;
* Editors&lt;br /&gt;
* Reviews&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Is there a good, free Python IDE for Windows? - Stack Overflow - http://stackoverflow.com/questions/126753/is-there-a-good-free-python-ide-for-windows&lt;br /&gt;
* Eclipse with PyDev&lt;br /&gt;
* Aptana Studio 3&lt;br /&gt;
* Active State also offers Komodo Edit&lt;br /&gt;
* WingWare - http://www.wingware.com/&lt;br /&gt;
* Eric IDE - http://www.die-offenbachs.de/eric/index.html&lt;br /&gt;
* MMM-Experts - Products - http://mmm-experts.com/Products.aspx?ProductId=4&lt;br /&gt;
** PyScripter is a Python IDE built in Python for Delphi(P4D) components and created with the ambition to become competitive in functionality with commercial Windows-based IDEs available for other languages. Being built in a compiled language is rather snappier than some of the other Python IDEs and provides an extensive blend of features that make it a productive Python development environment. &lt;br /&gt;
* ActiveState Python comes with PythonWin which is reasonably good&lt;br /&gt;
* PyCharm from JetBrains is not free in general, but has free early access program.&lt;br /&gt;
* SPE - Stani&#039;s Python Editor, is pretty awesome. See http://pythonide.blogspot.com/.&lt;br /&gt;
* You may want to take a look at the pdb module - http://docs.python.org/lib/module-pdb.html&lt;br /&gt;
* Geany (http://www.geany.org/) is a fairly light text editor that does a lot of IDE-like stuff.&lt;br /&gt;
* SciTE: http://www.scintilla.org/SciTE.html&lt;br /&gt;
* Editra: http://editra.org/ &lt;br /&gt;
* Netbeans has support for python development in their Python Early Access version. - http://www.netbeans.org/features/python/&lt;br /&gt;
* I use Notepad++ with the appropriate settings.&lt;br /&gt;
* The Eric Python IDE - http://www.die-offenbachs.de/eric/index.html&lt;br /&gt;
* BOa Constructor www.boa-constructor.sourceforge.net really nice! drag and drop stuff!&lt;br /&gt;
* DrPtyhon is also very nice, and has many plug-ins. http://drpython.sourceforge.net/&lt;br /&gt;
* Vim&lt;br /&gt;
* I will make a plug for my preference of Python development environments: SPE. SPE is an integrated development environment that provides code completion, integrated Python shell, calltips, and various helper tools like notes and todo lists. It also includes wxGlade so you can make wxPython applications easily. Plus, it includes the python debugger WinPdb.&lt;br /&gt;
* http://groups.google.com.tr/group/python_opengl this software is my sample visual python ide.its demo version.&lt;br /&gt;
* I use PyScripter, and find it pretty awesome.&lt;br /&gt;
* There is one Python IDE written in Java: jHepWork: http://jwork.org/jhepwork/ it can detect Python&#039;s indentation rules rather nicely (+ detects structure of a code and syntax)&lt;br /&gt;
* gvim built with your python version support and with this plugins:&lt;br /&gt;
** NERDTree (don&#039;t read he&#039;s blog ;)&lt;br /&gt;
** matchit (it&#039;s builtin in new versions just put a symlink or junction)&lt;br /&gt;
** pyflakes&lt;br /&gt;
** pysmell&lt;br /&gt;
* Try Python Tools for Visual Studio. Supports CPython and IronPython. - http://pytools.codeplex.com/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
PythonEditors - PythonInfo Wiki - http://wiki.python.org/moin/PythonEditors&lt;br /&gt;
* List of editors&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Python Ide - http://c2.com/cgi/wiki?PythonIde&lt;br /&gt;
: There are a lot of Ides for PythonLanguage springing up. Many of them written in Python &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Is there a better Python IDE? « Lennart Regebro: Python, Plone, Web - http://regebro.wordpress.com/2010/10/09/is-there-a-better-python-ide/&lt;br /&gt;
: I’m currently a user of WingIDE, but sometimes I feel the need for something better, mainly something that is a bit more stable. WingIDE often hangs when switching projects, sometimes the file listing decides that you must double-click on the expand arrow instead of just click on it, etc. It still doesn’t have macros despite this being a much requested feature (how hard can it be to add, really?) and I never really get the hang of the SVN integration, so I just ignore it. And they keep recommending me to use WingIDE’s separate instance of GTK instead of the System GTK, which is daft. Their designs are ugly, and it should work with the system GTK so it looks the same. Anything else is just silly.&lt;br /&gt;
&lt;br /&gt;
=== Open Komodo ===&lt;br /&gt;
&lt;br /&gt;
Open Komodo - http://www.openkomodo.com/&lt;br /&gt;
: Open Komodo is the source code repository for Komodo Edit - a free multi-language editor for dynamic languages, based on the award-winning Komodo IDE. ActiveState created the Open Komodo code repository in August 2007 and it has been used since then for building all Komodo Edit releases.&lt;br /&gt;
&lt;br /&gt;
=== Eclipse ===&lt;br /&gt;
&lt;br /&gt;
Build an Eclipse development environment for Perl, Python, and PHP - http://www.eclipse.org/resources/resource.php?id=485&lt;br /&gt;
: This tutorial shows how Eclipse&#039;s DLTK makes it possible to build development tools for scripting languages. In particular, it explains how to implement syntax coloring, user preferences, and interpreter integration in a plug-in-based project.&lt;br /&gt;
&lt;br /&gt;
See [[#PyDev]]&lt;br /&gt;
&lt;br /&gt;
=== EasyEclipse ===&lt;br /&gt;
&lt;br /&gt;
EasyEclipse - http://www.easyeclipse.org/&lt;br /&gt;
:EasyEclipse packages together Eclipse, the open-source software&lt;br /&gt;
development platform, and selected open source plugins.&lt;br /&gt;
:We select, assemble, test, patch, build installers and document&lt;br /&gt;
a full IDE, offered as reliable distributions and plugins.&lt;br /&gt;
:EasyEclipse is:&lt;br /&gt;
* Free and open-source,&lt;br /&gt;
* Easy to download and install, and&lt;br /&gt;
* Simple to maintain, without version and dependency issues.&lt;br /&gt;
&lt;br /&gt;
EasyEclipse for Python - http://www.easyeclipse.org/site/distributions/python.html&lt;br /&gt;
&lt;br /&gt;
EclipsePythonIntegration - PythonInfo Wiki - http://wiki.python.org/moin/EclipsePythonIntegration&lt;br /&gt;
: Using Eclipse as a Python editor&lt;br /&gt;
&lt;br /&gt;
=== PyDev ===&lt;br /&gt;
&lt;br /&gt;
PyDev - http://pydev.org/&lt;br /&gt;
: PyDev is a Python IDE for Eclipse, which may be used in Python, Jython and IronPython development.&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
Pydev - http://pydev.sourceforge.net/ (old link)&lt;br /&gt;
&lt;br /&gt;
How to Configure Eclipse for Python - http://www.rose-hulman.edu/class/csse/resources/Eclipse/eclipse-python-configuration.htm&lt;br /&gt;
&lt;br /&gt;
Python Development with PyDev and Eclipse - Tutorial - http://www.vogella.de/articles/Python/article.html&lt;br /&gt;
: This article describes how to write and debug Python programs with Eclipse&lt;br /&gt;
&lt;br /&gt;
PyDev Getting Started - http://pydev.org/manual_101_root.html&lt;br /&gt;
&lt;br /&gt;
Running a program - http://pydev.org/manual_101_run.html&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
Supported Task Tags:&lt;br /&gt;
* TODO:&lt;br /&gt;
* TASK:&lt;br /&gt;
* FIXME:&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
Installation:&lt;br /&gt;
# Platform Runtime Binary (download around 45-50 MB) - http://download.eclipse.org/eclipse/downloads/ or http://www.eclipse.org/downloads/&lt;br /&gt;
#* Example: Eclipse Classic 4.2.2&lt;br /&gt;
# Eclipse Software Add - PyDev: http://pydev.org/updates&lt;br /&gt;
# Eclipse Software Add - MercurialEclipse: http://cbes.javaforge.com/update  [http://javaforge.com/project/HGE] [http://mercurial.selenic.com/wiki/MercurialEclipse]&lt;br /&gt;
# Switch perspectives to PyDev&lt;br /&gt;
&lt;br /&gt;
=== The Eric Python IDE ===&lt;br /&gt;
&lt;br /&gt;
The Eric Python IDE - http://eric-ide.python-projects.org/&lt;br /&gt;
:Eric is a full featured Python and Ruby editor and IDE, written in python. It is based on the cross platform Qt gui toolkit, integrating the highly flexible Scintilla editor control. It is designed to be usable as everdays&#039; quick and dirty editor as well as being usable as a professional project management tool integrating many advanced features Python offers the professional coder. eric4 includes a plugin system, which allows easy extension of the IDE functionality with plugins downloadable from the net.&lt;br /&gt;
&lt;br /&gt;
Eric Python IDE - Wikipedia - http://en.wikipedia.org/wiki/Eric_Python_IDE&lt;br /&gt;
&lt;br /&gt;
=== Wingware Python IDE ===&lt;br /&gt;
&lt;br /&gt;
The Intelligent Development Environment for Python Programmers - Wingware Python IDE - http://www.wingware.com/&lt;br /&gt;
:Wingware&#039;s Python IDE is an Integrated Development Environment designed specifically for the Python programming language. Since 1999, Wingware has focused on Python.&lt;br /&gt;
&lt;br /&gt;
=== VIM ===&lt;br /&gt;
&lt;br /&gt;
Python .vimrc:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;quot; Kenneth&#039;s Preferences&lt;br /&gt;
&lt;br /&gt;
set nobackup            &amp;quot; don&#039;t create backup files&lt;br /&gt;
&amp;quot;set nohlsearch          &amp;quot; don&#039;t highlight search results&lt;br /&gt;
set hlsearch            &amp;quot; do highlight search results&lt;br /&gt;
set incsearch           &amp;quot; incremental search&lt;br /&gt;
set ignorecase          &amp;quot; ignore case during search&lt;br /&gt;
set smartcase           &amp;quot; do case sensitive search when upper case is typed&lt;br /&gt;
set shiftwidth=4        &amp;quot; shift blocks in 4 space increments&lt;br /&gt;
set tabstop=4           &amp;quot; the (typewriter) tab stops are every 4 spaces&lt;br /&gt;
set smarttab            &amp;quot; tab at beginning of line inserts 4 spaces (shiftwidth)&lt;br /&gt;
set showmatch           &amp;quot; briefly highlight matching bracket&lt;br /&gt;
set matchtime=1         &amp;quot; highlight match for 0.1 seconds&lt;br /&gt;
set background=dark     &amp;quot; black background&lt;br /&gt;
set shiftwidth=4        &amp;quot; shift blocks by 4 spaces&lt;br /&gt;
set shortmess=at        &amp;quot; use short messages so we don&#039;t have to hit enter&lt;br /&gt;
set expandtab           &amp;quot; expand tabs into spaces&lt;br /&gt;
set scrolloff=5         &amp;quot; always show 5 lines before &amp;amp; after cursor&lt;br /&gt;
set shell=bash          &amp;quot; use bash for the command shell&lt;br /&gt;
set shellcmdflag=-lc    &amp;quot; make bash startup as a login shell for ~/.bashrc&lt;br /&gt;
&amp;quot;set nowrap              &amp;quot; do not wrap long lines&lt;br /&gt;
set visualbell          &amp;quot; flash the screen rather than beep&lt;br /&gt;
set noerrorbells        &amp;quot; don&#039;t beep on errors&lt;br /&gt;
set wildmenu            &amp;quot; enable filename tab completion&lt;br /&gt;
set ruler               &amp;quot; display the ruler: shows cursor position&lt;br /&gt;
set cpoptions+=$        &amp;quot; display &#039;$&#039; at end of cw sequence&lt;br /&gt;
set title               &amp;quot; display filename and vim info in window title bar&lt;br /&gt;
set modelines=5         &amp;quot; search the first and last 5 lines for &amp;quot;vim:&amp;quot; modeline&lt;br /&gt;
set backspace=2         &amp;quot; backspace deletes&lt;br /&gt;
&lt;br /&gt;
set wildignore=*.o,*.class,*.pyc,*.pyo,*.a,*.so,*.dll,*.exe,core,*.jar,*.zip&lt;br /&gt;
&lt;br /&gt;
&amp;quot;let loaded_matchparen = 1 &amp;quot; don&#039;t highlight parenthesis match&lt;br /&gt;
&lt;br /&gt;
filetype indent on&lt;br /&gt;
&lt;br /&gt;
&amp;quot;if v:version &amp;gt; 700&lt;br /&gt;
&amp;quot;    set cursorline          &amp;quot; underline the current line&lt;br /&gt;
&amp;quot;endif&lt;br /&gt;
&lt;br /&gt;
if &amp;amp;t_Co &amp;gt; 2 || has( &amp;quot;gui_running&amp;quot; )&lt;br /&gt;
    syntax on&lt;br /&gt;
endif&lt;br /&gt;
&lt;br /&gt;
if has( &#039;mouse&#039; )&lt;br /&gt;
    set mouse=a &amp;quot; enable mouse&lt;br /&gt;
endif&lt;br /&gt;
&lt;br /&gt;
if has( &amp;quot;autocmd&amp;quot; )&lt;br /&gt;
    &amp;quot; open the file in the last place we were editing&lt;br /&gt;
    autocmd BufReadPost *&lt;br /&gt;
        \ if line(&amp;quot;&#039;\&amp;quot;&amp;quot;) &amp;gt; 1 &amp;amp;&amp;amp; line(&amp;quot;&#039;\&amp;quot;&amp;quot;) &amp;lt;= line(&amp;quot;$&amp;quot;) |&lt;br /&gt;
        \     exe &amp;quot;normal! g&#039;\&amp;quot;&amp;quot; |&lt;br /&gt;
        \ endif&lt;br /&gt;
endif&lt;br /&gt;
&lt;br /&gt;
&amp;quot;folding settings&lt;br /&gt;
set foldmethod=indent   &amp;quot;fold based on indent&lt;br /&gt;
set foldnestmax=10      &amp;quot;deepest fold is 10 levels&lt;br /&gt;
set nofoldenable        &amp;quot;dont fold by default&lt;br /&gt;
set foldlevel=10        &amp;quot;this is just what i use&lt;br /&gt;
&lt;br /&gt;
&amp;quot; Auto clear trailing white space in Python files&lt;br /&gt;
func! DeleteTrailingWS()&lt;br /&gt;
    exec &amp;quot;normal mz&amp;quot;&lt;br /&gt;
    %s/\s\+$//ge&lt;br /&gt;
    exe &amp;quot;normal `z&amp;quot;&lt;br /&gt;
endfunc&lt;br /&gt;
autocmd BufWrite *.py :call DeleteTrailingWS()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Older versions:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;quot; KENNETH SETTINGS&lt;br /&gt;
set nocp                &amp;quot; turn off compatibility mode&lt;br /&gt;
set nomodeline          &amp;quot; do not allow files to dictate vim behavior&lt;br /&gt;
&lt;br /&gt;
set incsearch           &amp;quot; incremental search&lt;br /&gt;
set ignorecase          &amp;quot; ignore case during search&lt;br /&gt;
&lt;br /&gt;
set visualbell          &amp;quot; flash the screen rather than beep&lt;br /&gt;
set noerrorbells        &amp;quot; don&#039;t beep on errors&lt;br /&gt;
set background=dark     &amp;quot; black background&lt;br /&gt;
syntax on               &amp;quot; turn on syntax highlighting&lt;br /&gt;
set hlsearch            &amp;quot; highligh last search pattern&lt;br /&gt;
&lt;br /&gt;
set nowrap              &amp;quot; do not wrap long lines&lt;br /&gt;
set scrolloff=5         &amp;quot; always show 5 lines before &amp;amp; after cursor&lt;br /&gt;
set ruler               &amp;quot; show the cursor position all the time&lt;br /&gt;
set backspace=2         &amp;quot; allow backspace deletion&lt;br /&gt;
set bs=indent,eol,start &amp;quot; allow backspacing over everything in insert mode&lt;br /&gt;
&lt;br /&gt;
set shiftwidth=4        &amp;quot; shift blocks in 4 space increments&lt;br /&gt;
set tabstop=4           &amp;quot; the (typewriter) tab stops are every 4 spaces&lt;br /&gt;
set expandtab           &amp;quot; expand tab into spaces&lt;br /&gt;
set smarttab            &amp;quot; tab at beginning of line inserts 4 spaces (shiftwidth)&lt;br /&gt;
filetype indent on      &amp;quot; turn on auto indent for specific file types&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Other options:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
set number              &amp;quot; show line numbers&lt;br /&gt;
set numberwidth=1       &amp;quot; remove space before largest line numbers&lt;br /&gt;
&lt;br /&gt;
set smartindent         &amp;quot; ?? - maybe included in &#039;filetype indent on&#039;&lt;br /&gt;
&lt;br /&gt;
set ai                  &amp;quot; always auto indent&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
if has( &amp;quot;autocmd&amp;quot; )&lt;br /&gt;
    &amp;quot; open the file in the last place we were editing&lt;br /&gt;
    autocmd BufReadPost *&lt;br /&gt;
        \ if line(&amp;quot;&#039;\&amp;quot;&amp;quot;) &amp;gt; 1 &amp;amp;&amp;amp; line(&amp;quot;&#039;\&amp;quot;&amp;quot;) &amp;lt;= line(&amp;quot;$&amp;quot;) |&lt;br /&gt;
        \     exe &amp;quot;normal! g&#039;\&amp;quot;&amp;quot; |&lt;br /&gt;
        \ endif&lt;br /&gt;
endif&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Kenneth&#039;s fio .vimrc:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;quot;source $VIM/mswin.vim&lt;br /&gt;
&lt;br /&gt;
set nobackup            &amp;quot; don&#039;t create backup files&lt;br /&gt;
&amp;quot;set nohlsearch          &amp;quot; don&#039;t highlight search results&lt;br /&gt;
set incsearch           &amp;quot; incremental search&lt;br /&gt;
set ignorecase          &amp;quot; ignore case during search&lt;br /&gt;
set smartcase           &amp;quot; do case sensitive search when upper case is typed&lt;br /&gt;
set shiftwidth=4        &amp;quot; shift blocks in 4 space increments&lt;br /&gt;
set tabstop=4           &amp;quot; the (typewriter) tab stops are every 4 spaces&lt;br /&gt;
set smarttab            &amp;quot; tab at beginning of line inserts 4 spaces (shiftwidth)&lt;br /&gt;
set showmatch           &amp;quot; briefly highlight matching bracket&lt;br /&gt;
set matchtime=1         &amp;quot; highlight match for 0.1 seconds&lt;br /&gt;
set background=dark     &amp;quot; black background&lt;br /&gt;
set shiftwidth=4        &amp;quot; shift blocks by 4 spaces&lt;br /&gt;
set shortmess=at        &amp;quot; use short messages so we don&#039;t have to hit enter&lt;br /&gt;
set expandtab           &amp;quot; expand tabs into spaces&lt;br /&gt;
set scrolloff=5         &amp;quot; always show 5 lines before &amp;amp; after cursor&lt;br /&gt;
set shell=bash          &amp;quot; use bash for the command shell&lt;br /&gt;
set shellcmdflag=-lc    &amp;quot; make bash startup as a login shell for ~/.bashrc&lt;br /&gt;
&amp;quot;set nowrap              &amp;quot; do not wrap long lines&lt;br /&gt;
set visualbell          &amp;quot; flash the screen rather than beep&lt;br /&gt;
set noerrorbells        &amp;quot; don&#039;t beep on errors&lt;br /&gt;
set wildmenu            &amp;quot; enable filename tab completion&lt;br /&gt;
set ruler               &amp;quot; display the ruler: shows cursor position&lt;br /&gt;
set cpoptions+=$        &amp;quot; display &#039;$&#039; at end of cw sequence&lt;br /&gt;
set title               &amp;quot; display filename and vim info in window title bar&lt;br /&gt;
set modelines=5         &amp;quot; search the first and last 5 lines for &amp;quot;vim:&amp;quot; modeline&lt;br /&gt;
&lt;br /&gt;
set wildignore=*.o,*.class,*.pyc,*.pyo,*.a,*.so,*.dll,*.exe,core,*.jar,*.zip&lt;br /&gt;
&lt;br /&gt;
&amp;quot;let loaded_matchparen = 1 &amp;quot; don&#039;t highlight parenthesis match&lt;br /&gt;
&lt;br /&gt;
filetype indent on&lt;br /&gt;
&lt;br /&gt;
if v:version &amp;gt; 700&lt;br /&gt;
    set cursorline          &amp;quot; underline the current line&lt;br /&gt;
endif&lt;br /&gt;
&lt;br /&gt;
if &amp;amp;t_Co &amp;gt; 2 || has( &amp;quot;gui_running&amp;quot; )&lt;br /&gt;
    syntax on&lt;br /&gt;
endif&lt;br /&gt;
&lt;br /&gt;
if has( &#039;mouse&#039; )&lt;br /&gt;
    set mouse=a &amp;quot; enable mouse&lt;br /&gt;
endif&lt;br /&gt;
&lt;br /&gt;
if has( &amp;quot;autocmd&amp;quot; )&lt;br /&gt;
    &amp;quot; open the file in the last place we were editing&lt;br /&gt;
    autocmd BufReadPost *&lt;br /&gt;
        \ if line(&amp;quot;&#039;\&amp;quot;&amp;quot;) &amp;gt; 1 &amp;amp;&amp;amp; line(&amp;quot;&#039;\&amp;quot;&amp;quot;) &amp;lt;= line(&amp;quot;$&amp;quot;) |&lt;br /&gt;
        \     exe &amp;quot;normal! g&#039;\&amp;quot;&amp;quot; |&lt;br /&gt;
        \ endif&lt;br /&gt;
endif&lt;br /&gt;
&lt;br /&gt;
&amp;quot;folding settings&lt;br /&gt;
set foldmethod=indent   &amp;quot;fold based on indent&lt;br /&gt;
set foldnestmax=10      &amp;quot;deepest fold is 10 levels&lt;br /&gt;
set nofoldenable        &amp;quot;dont fold by default&lt;br /&gt;
set foldlevel=10        &amp;quot;this is just what i use&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Interpreter vs Script ==&lt;br /&gt;
&lt;br /&gt;
Interpreter:&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; import os&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; os.uname()&lt;br /&gt;
 (&#039;Linux&#039;, &#039;demo.oeey.com&#039;, &#039;2.6.18-194.8.1.el5&#039;, &#039;#1 SMP Thu Jul 1 19:07:06 EDT 2010&#039;, &#039;i686&#039;)&lt;br /&gt;
&lt;br /&gt;
Script:&lt;br /&gt;
 #!/usr/bin/env python&lt;br /&gt;
 import os&lt;br /&gt;
 print os.uname()&lt;br /&gt;
&lt;br /&gt;
== Web Development ==&lt;br /&gt;
&lt;br /&gt;
WebProgramming - PythonInfo Wiki - http://wiki.python.org/moin/WebProgramming&lt;br /&gt;
: This topic guide attempts to cover every aspect of programming Web applications (both clients and servers) using Python. &lt;br /&gt;
&lt;br /&gt;
HOWTO Use Python in the web — Python v2.7.2 documentation - http://docs.python.org/howto/webservers.html&lt;br /&gt;
: This document shows how Python fits into the web. It presents some ways to integrate Python with a web server, and general practices useful for developing web sites.&lt;br /&gt;
&lt;br /&gt;
=== Plug Simple Python Web App ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
-------- Original Message --------&lt;br /&gt;
Subject: 	Re: Writing a simple python web app&lt;br /&gt;
Date: 	Mon, 25 Oct 2010 19:03:31 -0400&lt;br /&gt;
From: 	Roberto Mello &amp;lt;roberto.mello@gmail.com&amp;gt;&lt;br /&gt;
To: 	Provo Linux Users Group &amp;lt;plug@plug.org&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
On Sat, Sep 11, 2010 at 5:40 PM, Dave Smith &amp;lt;dave@thesmithfam.org&amp;gt; wrote:&lt;br /&gt;
&amp;gt; I&#039;m creating a very simple web application, and I want to use python. My first guess was that mod_python&lt;br /&gt;
would provide the easiest entry point. Boy, was I wrong. All the mod_python tutorials spend 80% of their&lt;br /&gt;
time extolling the virtues of mod_python over CGI, but they are quite lean on specific examples. It&#039;s quite&lt;br /&gt;
disappointing. A natural progression then leads me to mod_wsgi, and since that has equally poor&lt;br /&gt;
documentation, to Django. However, Django is overkill for my app (I don&#039;t even have a database).&lt;br /&gt;
&lt;br /&gt;
For something as simple as you have described, and to run on an&lt;br /&gt;
embedded platform, I would probably stay away from frameworks designed&lt;br /&gt;
to run on full hardware, and go with something more minimalistic.&lt;br /&gt;
&lt;br /&gt;
Take a look at CherryPy [1] or web.py [2].&lt;br /&gt;
&lt;br /&gt;
[1] http://www.cherrypy.org/&lt;br /&gt;
[2] http://webpy.org/&lt;br /&gt;
&lt;br /&gt;
Roberto Mello&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
See also [[web.py]]&lt;br /&gt;
&lt;br /&gt;
See also [[CherryPy]]&lt;br /&gt;
&lt;br /&gt;
See also [[Django]]&lt;br /&gt;
&lt;br /&gt;
=== Apache CGI ===&lt;br /&gt;
&lt;br /&gt;
See [[CGI]]&lt;br /&gt;
&lt;br /&gt;
Great tutorial: https://www.tutorialspoint.com/python/python_cgi_programming.htm&lt;br /&gt;
&lt;br /&gt;
My favorite option, make all .cgi files executable: (or .py)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 DirectoryIndex index.html index.php index.py&lt;br /&gt;
 &amp;lt;Location /&amp;gt;&lt;br /&gt;
   # AddHandler cgi-script .cgi&lt;br /&gt;
   AddHandler cgi-script .py&lt;br /&gt;
   Options +ExecCGI &lt;br /&gt;
 &amp;lt;/Location&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you want to allow .htaccess:&lt;br /&gt;
* see [[Apache#.htaccess]]&lt;br /&gt;
&lt;br /&gt;
To enable on Ubuntu:&lt;br /&gt;
 sudo a2enmod cgi&lt;br /&gt;
 service apache2 restart&lt;br /&gt;
&lt;br /&gt;
Directory index:&lt;br /&gt;
 DirectoryIndex index.py&lt;br /&gt;
&lt;br /&gt;
Or if you really want to go crazy, this will try to run *every* file: [http://blog.kapsobor.de/archives/2006/09/05/apache_addhandler_multiple_extensions/]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    # this has problems with / directory being run as a script, instead of index too!&lt;br /&gt;
    #&amp;lt;Location /&amp;gt;&lt;br /&gt;
    #    SetHandler cgi-script&lt;br /&gt;
    #    Options +ExecCGI&lt;br /&gt;
    #&amp;lt;/Location&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;Files ~ &amp;quot;.&amp;quot;&amp;gt;&lt;br /&gt;
        SetHandler cgi-script&lt;br /&gt;
        Options +ExecCGI&lt;br /&gt;
    &amp;lt;/Files&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    &amp;lt;Files ~ &amp;quot;^.[a-zA-Z]*$&amp;quot;&amp;gt;&lt;br /&gt;
        SetHandler cgi-script&lt;br /&gt;
        Options +ExecCGI&lt;br /&gt;
    &amp;lt;/Files&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Or just have index file:&lt;br /&gt;
    &amp;lt;Files &amp;quot;index&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: Place within a &amp;lt;VirtualHost&amp;gt; section if needed.&lt;br /&gt;
&lt;br /&gt;
Note: Make sure to &#039;chmod +x&#039; the files.&lt;br /&gt;
&lt;br /&gt;
Start all HTML output with:&lt;br /&gt;
 print &amp;quot;Content-Type: text/html\n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If you want just text output:&lt;br /&gt;
 print &amp;quot;Content-Type: text/plain\n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
GET (from Environment):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
print &amp;quot;&amp;amp;lt;pre&amp;gt;&amp;quot;&lt;br /&gt;
for env in os.environ:&lt;br /&gt;
    print &amp;quot;%s = %s&amp;quot; % (env, os.environ[env])&lt;br /&gt;
print &amp;quot;&amp;amp;lt;/pre&amp;gt;&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# sample for: http://oeey.com/py/test.py/test?var1=ken&amp;amp;var2=barbie&lt;br /&gt;
&lt;br /&gt;
REQUEST_URI = /py/index.py/test?var1=ken&amp;amp;var2=barbie&lt;br /&gt;
QUERY_STRING = var1=ken&amp;amp;var2=barbie&lt;br /&gt;
PATH_INFO = /test&lt;br /&gt;
REQUEST_METHOD = GET&lt;br /&gt;
&lt;br /&gt;
SCRIPT_NAME = /py/test.py&lt;br /&gt;
SERVER_NAME = oeey.com&lt;br /&gt;
REMOTE_ADDR = 216.51.42.66&lt;br /&gt;
SERVER_ADDR = 192.168.108.4&lt;br /&gt;
DOCUMENT_ROOT = /www/py&lt;br /&gt;
SCRIPT_FILENAME = /www/py/test.py&lt;br /&gt;
HTTP_HOST = cgi.oeey.com&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
POST (from stdin):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
post = sys.stdin.readline()&lt;br /&gt;
if post:&lt;br /&gt;
    print post&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CONTENT_TYPE = application/x-www-form-urlencoded&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
yin=one+two+three&amp;amp;yang=four+five+six&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
cgi helper class:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import cgi&lt;br /&gt;
&lt;br /&gt;
print &amp;quot;Content-Type: text/html\n\n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
form = cgi.FieldStorage()&lt;br /&gt;
&lt;br /&gt;
# field keys&lt;br /&gt;
print &amp;quot;fields keys: &amp;quot;, form.keys()  # list of field keys&lt;br /&gt;
&lt;br /&gt;
# fild values&lt;br /&gt;
if &amp;quot;name&amp;quot; in form:  # if form.has_key(&#039;name&#039;):&lt;br /&gt;
    print &amp;quot;field &#039;name&#039; is: &amp;quot;, form[&amp;quot;name&amp;quot;].value&lt;br /&gt;
    print &amp;quot;field &#039;name&#039; is: &amp;quot;, form.getvalue(&#039;name&#039;)&lt;br /&gt;
&lt;br /&gt;
# headers&lt;br /&gt;
print &amp;quot;dictionary of headers: &amp;quot;, form.headers&lt;br /&gt;
print form.type&lt;br /&gt;
print form.headers[&#039;content-type&#039;]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To prevent XSS escape the characters:&lt;br /&gt;
  print cgi.escape(form.getvalue(&#039;name&#039;))&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import cgi&lt;br /&gt;
&lt;br /&gt;
print &amp;quot;Content-Type: text/html\n\n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
form = cgi.FieldStorage()&lt;br /&gt;
if (form.has_key(&amp;quot;action&amp;quot;) and form.has_key(&amp;quot;name&amp;quot;) \&lt;br /&gt;
        and form.has_key(&amp;quot;age&amp;quot;)):&lt;br /&gt;
    if (form[&amp;quot;action&amp;quot;].value == &amp;quot;display&amp;quot;):&lt;br /&gt;
        print &amp;quot;%s = %s&amp;quot; % (form[&amp;quot;name&amp;quot;].value form[&amp;quot;age&amp;quot;].value)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: cgi helper class also does sessions and cookies.&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* CGI Tutorial | Web Python - http://webpython.codepoint.net/cgi_tutorial&lt;br /&gt;
* Python CGI: An Interactive Instruction - http://www.cs.virginia.edu/~lab2q/&lt;br /&gt;
&lt;br /&gt;
See also:&lt;br /&gt;
* Web Python - http://webpython.codepoint.net/&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
REST Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import os, re&lt;br /&gt;
def get_rest():&lt;br /&gt;
    if not &amp;quot;PATH_INFO&amp;quot; in os.environ:&lt;br /&gt;
        return ()&lt;br /&gt;
    # filter for garbage&lt;br /&gt;
    #print os.environ[&amp;quot;PATH_INFO&amp;quot;]&lt;br /&gt;
    path_info = re.findall(&#039;[/A-Za-z0-9_-]*&#039;, os.environ[&amp;quot;PATH_INFO&amp;quot;])&lt;br /&gt;
    if not path_info:&lt;br /&gt;
        return ()&lt;br /&gt;
    path_info = &#039;&#039;.join(path_info)&lt;br /&gt;
    # collapse empty paths&lt;br /&gt;
    paths = path_info.split(&#039;/&#039;)&lt;br /&gt;
    final_paths = []&lt;br /&gt;
    for path in paths:&lt;br /&gt;
        if path:&lt;br /&gt;
            final_paths.append(path)&lt;br /&gt;
    return tuple(final_paths)&lt;br /&gt;
rest = get_rest();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== mod_python ===&lt;br /&gt;
&lt;br /&gt;
AVOID! AVOID! AVOID! - if you want this simple, just use CGI!&lt;br /&gt;
&lt;br /&gt;
See [[Apache mod_python]]&lt;br /&gt;
&lt;br /&gt;
mod_python - http://docs.python.org/howto/webservers.html#mod-python&lt;br /&gt;
&lt;br /&gt;
Install:&lt;br /&gt;
 yum install mod_python&lt;br /&gt;
&lt;br /&gt;
Config:&lt;br /&gt;
 /etc/httpd/conf.d/python.conf&lt;br /&gt;
&lt;br /&gt;
Simple:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;quot;People coming from PHP often find it hard to grasp how to use Python in the web. Their first thought is mostly mod_python, because they think that this is the equivalent to mod_php. Actually, there are many differences. What mod_python does is embed the interpreter into the Apache process, thus speeding up requests by not having to start a Python interpreter for each request. On the other hand, it is not “Python intermixed with HTML” in the way that PHP is often intermixed with HTML. The Python equivalent of that is a template engine. mod_python itself is much more powerful and provides more access to Apache internals. It can emulate CGI, work in a “Python Server Pages” mode (similar to JSP) which is “HTML intermingled with Python”, and it has a “Publisher” which designates one file to accept all requests and decide what to do with them.&lt;br /&gt;
&lt;br /&gt;
:mod_python does have some problems. Unlike the PHP interpreter, the Python interpreter uses caching when executing files, so changes to a file will require the web server to be restarted. Another problem is the basic concept – Apache starts child processes to handle the requests, and unfortunately every child process needs to load the whole Python interpreter even if it does not use it. This makes the whole web server slower. Another problem is that, because mod_python is linked against a specific version of libpython, it is not possible to switch from an older version to a newer (e.g. 2.4 to 2.5) without recompiling mod_python. mod_python is also bound to the Apache web server, so programs written for mod_python cannot easily run on other web servers.&lt;br /&gt;
&lt;br /&gt;
:These are the reasons why mod_python should be avoided when writing new programs. In some circumstances it still might be a good idea to use mod_python for deployment, but WSGI makes it possible to run WSGI programs under mod_python as well.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== WSGI ===&lt;br /&gt;
&lt;br /&gt;
WSGI - http://docs.python.org/howto/webservers.html#mod-wsgi&lt;br /&gt;
&lt;br /&gt;
: &amp;quot;The Web Server Gateway Interface, or WSGI for short, is defined in PEP 333 and is currently the best way to do Python web programming. While it is great for programmers writing frameworks, a normal web developer does not need to get in direct contact with it. When choosing a framework for web development it is a good idea to choose one which supports WSGI.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
See [[mod_wsgi]]&lt;br /&gt;
&lt;br /&gt;
=== Django ===&lt;br /&gt;
&lt;br /&gt;
See [[Django]]&lt;br /&gt;
&lt;br /&gt;
=== CherryPy ===&lt;br /&gt;
&lt;br /&gt;
See [[CherryPy]]&lt;br /&gt;
&lt;br /&gt;
=== web.py ===&lt;br /&gt;
&lt;br /&gt;
web.py: makes web apps&lt;br /&gt;
&lt;br /&gt;
Think about the ideal way to write a web app. Write the code to make it happen.&lt;br /&gt;
&lt;br /&gt;
web.py : Python Package Index - http://pypi.python.org/pypi/web.py&lt;br /&gt;
&lt;br /&gt;
Home Page: http://webpy.org/&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Django lets you write web apps in Django. TurboGears lets you write web apps in TurboGears. Web.py lets you write web apps in Python.&amp;quot;&lt;br /&gt;
:—  Adam Atlas&lt;br /&gt;
&lt;br /&gt;
NOTE: Can modify source code without having to restart app!  :-)&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
PIP Install:&lt;br /&gt;
 pip install web.py&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
Hello World: [http://webpy.org/]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import web&lt;br /&gt;
        &lt;br /&gt;
urls = (&lt;br /&gt;
    &#039;/(.*)&#039;, &#039;hello&#039;&lt;br /&gt;
)&lt;br /&gt;
app = web.application(urls, globals())&lt;br /&gt;
&lt;br /&gt;
class hello:        &lt;br /&gt;
    def GET(self, name):&lt;br /&gt;
        if not name: &lt;br /&gt;
            name = &#039;World&#039;&lt;br /&gt;
        return &#039;Hello, &#039; + name + &#039;!&#039;&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
    app.run()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: app.py can be renamed.&lt;br /&gt;
&lt;br /&gt;
Running:&lt;br /&gt;
 python app.py&lt;br /&gt;
&lt;br /&gt;
Note: You can add an IP address/port after the &amp;quot;app.py&amp;quot; bit to control where web.py launches the server. You can also tell it to run a fastcgi or scgi server.&lt;br /&gt;
 python app.py 1234&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
Templates&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# templates/hello.html&lt;br /&gt;
$def with (name)&lt;br /&gt;
&lt;br /&gt;
$if name:&lt;br /&gt;
    I just wanted to say &amp;lt;em&amp;gt;hello&amp;lt;/em&amp;gt; to $name.&lt;br /&gt;
$else:&lt;br /&gt;
    &amp;lt;em&amp;gt;Hello&amp;lt;/em&amp;gt;, world!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 app = ...&lt;br /&gt;
 render = web.template.render(&#039;templates/&#039;)&lt;br /&gt;
&lt;br /&gt;
index.GET:&lt;br /&gt;
 name = &#039;Bob&#039;    &lt;br /&gt;
 return render.hello(name)  # render.[TEMPLATE_NAME](vars)&lt;br /&gt;
&lt;br /&gt;
get variable: (/?name=Joe)&lt;br /&gt;
 i = web.input(name=None)&lt;br /&gt;
 return render.hello(i.name)&lt;br /&gt;
&lt;br /&gt;
variable in url:&lt;br /&gt;
 urls = (&#039;/(.*)&#039;, &#039;hello&#039;)&lt;br /&gt;
&lt;br /&gt;
 class index:&lt;br /&gt;
     def GET(self, name):&lt;br /&gt;
        return render.hello(name)&lt;br /&gt;
&lt;br /&gt;
 # visit: /Joe&lt;br /&gt;
&lt;br /&gt;
multiple variables in url:&lt;br /&gt;
 urls = (&#039;/(.*)/(.*)&#039;, &#039;hello&#039;)&lt;br /&gt;
&lt;br /&gt;
  class hello:&lt;br /&gt;
    def GET(self, fname, lname):&lt;br /&gt;
        return render.hello(fname, lname)&lt;br /&gt;
&lt;br /&gt;
 # visit: /Joe/Smith&lt;br /&gt;
&lt;br /&gt;
=== lpthw.web ===&lt;br /&gt;
&lt;br /&gt;
lpthw.web: a fork of web.py for Learn Python The Hard Way&lt;br /&gt;
&lt;br /&gt;
Locks web.py at a specific version and removes some magic. Thanks to Aaron Swartz for making it originally.&lt;br /&gt;
&lt;br /&gt;
lpthw.web: a fork of web.py for Learn Python The Hard Way - http://pypi.python.org/pypi/lpthw.web&lt;br /&gt;
&lt;br /&gt;
Home Page: http://learnpythonthehardway.org/&lt;br /&gt;
&lt;br /&gt;
This conflicts with web.py, so only install one.&lt;br /&gt;
&lt;br /&gt;
=== web ===&lt;br /&gt;
&lt;br /&gt;
web - Web modules for CGI and WSGI web programming&lt;br /&gt;
&lt;br /&gt;
web : Python Package Index - http://pypi.python.org/pypi/web&lt;br /&gt;
&lt;br /&gt;
Warning: This is an alpha release for those who are interested in&lt;br /&gt;
    checking progress. No documentation and not for production use.&lt;br /&gt;
&lt;br /&gt;
Auth, session, mail, form and templating tools for writing CGI scripts or WSGI web applications.&lt;br /&gt;
&lt;br /&gt;
This version incompatible with previous versions becuase large portions of the code have been refactored into separate components.&lt;br /&gt;
&lt;br /&gt;
== Issues ==&lt;br /&gt;
&lt;br /&gt;
=== Hide DeprecationWarning ===&lt;br /&gt;
&lt;br /&gt;
==== Import DeprecationWarning ====&lt;br /&gt;
&lt;br /&gt;
Error:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/opt/xmpppy-0.4.1/xmpp/auth.py:24: DeprecationWarning: the sha module is deprecated; use the hashlib module instead&lt;br /&gt;
  import sha,base64,random,dispatcher,re&lt;br /&gt;
/opt/xmpppy-0.4.1/xmpp/auth.py:26: DeprecationWarning: the md5 module is deprecated; use hashlib instead&lt;br /&gt;
  import md5&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hide deprecation warnings with code: [http://stackoverflow.com/questions/879173/how-to-ignore-deprecation-warnings-in-python]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import warnings&lt;br /&gt;
&lt;br /&gt;
with warnings.catch_warnings():&lt;br /&gt;
    warnings.filterwarnings(&amp;quot;ignore&amp;quot;,category=DeprecationWarning)&lt;br /&gt;
    import md5, sha&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hide with header:&lt;br /&gt;
 #!/usr/bin/env python -W ignore::DeprecationWarning&lt;br /&gt;
&lt;br /&gt;
Hide from command line:&lt;br /&gt;
 python -W ignore::DeprecationWarning script.py&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* How to ignore deprecation warnings in Python - Stack Overflow - http://stackoverflow.com/questions/879173/how-to-ignore-deprecation-warnings-in-python&lt;br /&gt;
&lt;br /&gt;
==== Funciton DeprecationWarning ====&lt;br /&gt;
&lt;br /&gt;
Error:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/opt/xmpppy-0.4.1/xmpp/transports.py:307: DeprecationWarning: socket.ssl() is deprecated.  Use ssl.wrap_socket() instead.&lt;br /&gt;
  tcpsock._sslObj    = socket.ssl(tcpsock._sock, None, None)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hide with header:&lt;br /&gt;
 #!/usr/bin/env python -W ignore::DeprecationWarning&lt;br /&gt;
&lt;br /&gt;
Hide from command line:&lt;br /&gt;
 python -W ignore::DeprecationWarning script.py&lt;br /&gt;
&lt;br /&gt;
==== Ubuntu 24 pip packages ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
error: externally-managed-environment&lt;br /&gt;
&lt;br /&gt;
× This environment is externally managed&lt;br /&gt;
╰─&amp;gt; To install Python packages system-wide, try apt install&lt;br /&gt;
    python3-xyz, where xyz is the package you are trying to&lt;br /&gt;
    install.&lt;br /&gt;
&lt;br /&gt;
    If you wish to install a non-Debian-packaged Python package,&lt;br /&gt;
    create a virtual environment using python3 -m venv path/to/venv.&lt;br /&gt;
    Then use path/to/venv/bin/python and path/to/venv/bin/pip. Make&lt;br /&gt;
    sure you have python3-full installed.&lt;br /&gt;
&lt;br /&gt;
    If you wish to install a non-Debian packaged Python application,&lt;br /&gt;
    it may be easiest to use pipx install xyz, which will manage a&lt;br /&gt;
    virtual environment for you. Make sure you have pipx installed.&lt;br /&gt;
&lt;br /&gt;
    See /usr/share/doc/python3.12/README.venv for more information.&lt;br /&gt;
&lt;br /&gt;
note: If you believe this is a mistake, please contact your Python installation or OS distribution provider. You can override this, at the risk of breaking your Python installation or OS, by passing --break-system-packages.&lt;br /&gt;
hint: See PEP 668 for the detailed specification.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== keywords ==&lt;br /&gt;
&lt;br /&gt;
[[Category:Programming]]&lt;br /&gt;
[[Category:Python]]&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=Ubuntu/Python/3.14&amp;diff=9869</id>
		<title>Ubuntu/Python/3.14</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=Ubuntu/Python/3.14&amp;diff=9869"/>
		<updated>2026-04-27T20:06:11Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: /* pip3.14 script */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Install with DeadSnakes PPA ==&lt;br /&gt;
&lt;br /&gt;
Dependency:&lt;br /&gt;
 sudo apt install software-properties-common&lt;br /&gt;
&lt;br /&gt;
Add Deadsnakes and install python 3.14&lt;br /&gt;
 sudo add-apt-repository ppa:deadsnakes/ppa&lt;br /&gt;
   # respond to prompts&lt;br /&gt;
 sudo apt update&lt;br /&gt;
 sudo apt install python3.14&lt;br /&gt;
 # should also install:&lt;br /&gt;
 sudo apt install python3.14-dev python3.14-venv&lt;br /&gt;
&lt;br /&gt;
 python3.14 --version&lt;br /&gt;
&lt;br /&gt;
For development, virtuan env&lt;br /&gt;
 sudo apt install python3.14-dev python3.14-venv&lt;br /&gt;
&lt;br /&gt;
For a more complete installation including the Tkinter IDE and other utilities, you can use:&lt;br /&gt;
 sudo apt install python3.14-full&lt;br /&gt;
&lt;br /&gt;
Pip:&lt;br /&gt;
 curl -sS https://bootstrap.pypa.io/get-pip.py | python3.14&lt;br /&gt;
&lt;br /&gt;
 python3.14 -m pip install pip --upgrade&lt;br /&gt;
&lt;br /&gt;
 python3.14 -m pip --version&lt;br /&gt;
&lt;br /&gt;
 python3.14 -m pip list&lt;br /&gt;
&lt;br /&gt;
venv:  (requires pip)&lt;br /&gt;
 python3.14 -m venv -h&lt;br /&gt;
&lt;br /&gt;
 # check if pip is working&lt;br /&gt;
 python3.14 -m ensurepip&lt;br /&gt;
   #   /usr/bin/python3.14: No module named ensurepip&lt;br /&gt;
   # if this fails with the above, install pip and python3.14-venv ^&lt;br /&gt;
&lt;br /&gt;
 cd ~ ; rm -rf .test-venv ; mkdir .test-venv ; cd .test-venv ; python3.14 -m venv venv&lt;br /&gt;
&lt;br /&gt;
== pip3.14 script ==&lt;br /&gt;
&lt;br /&gt;
Dead-Snakes doesn&#039;t install the pip3.14 script for reasons (as you will see...)  You can manually install, by copying the python 3.12 version, and changing the shebang header from python3 to python3.14.  Only useful as a convenience for regular users, not for root.&lt;br /&gt;
&lt;br /&gt;
 cd /usr/bin&lt;br /&gt;
 cp pip3.12 pip3.14&lt;br /&gt;
 sed -i &amp;quot;s/python3/python3.14/&amp;quot; pip3.14&lt;br /&gt;
&lt;br /&gt;
Note, calling pip directly as root will error out, but at least as users you can call it to install local packages&lt;br /&gt;
 pip3.14 install pip --upgrade&lt;br /&gt;
  ERROR: Cannot uninstall pip 24.0, RECORD file not found. Hint: The package was installed by debian.&lt;br /&gt;
&lt;br /&gt;
/usr/bin/pip3.14&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/python3.14&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
import re&lt;br /&gt;
import sys&lt;br /&gt;
from pip._internal.cli.main import main&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
    sys.argv[0] = re.sub(r&amp;quot;(-script\.pyw|\.exe)?$&amp;quot;, &amp;quot;&amp;quot;, sys.argv[0])&lt;br /&gt;
    sys.exit(main())&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Alternatively, you could also just create an alias:&lt;br /&gt;
&lt;br /&gt;
 alias pip3.14=&amp;quot;python3.14 -m pip&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== keywords ==&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=Ubuntu/Python/3.14&amp;diff=9868</id>
		<title>Ubuntu/Python/3.14</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=Ubuntu/Python/3.14&amp;diff=9868"/>
		<updated>2026-04-27T20:04:56Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: /* pip3.14 script */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Install with DeadSnakes PPA ==&lt;br /&gt;
&lt;br /&gt;
Dependency:&lt;br /&gt;
 sudo apt install software-properties-common&lt;br /&gt;
&lt;br /&gt;
Add Deadsnakes and install python 3.14&lt;br /&gt;
 sudo add-apt-repository ppa:deadsnakes/ppa&lt;br /&gt;
   # respond to prompts&lt;br /&gt;
 sudo apt update&lt;br /&gt;
 sudo apt install python3.14&lt;br /&gt;
 # should also install:&lt;br /&gt;
 sudo apt install python3.14-dev python3.14-venv&lt;br /&gt;
&lt;br /&gt;
 python3.14 --version&lt;br /&gt;
&lt;br /&gt;
For development, virtuan env&lt;br /&gt;
 sudo apt install python3.14-dev python3.14-venv&lt;br /&gt;
&lt;br /&gt;
For a more complete installation including the Tkinter IDE and other utilities, you can use:&lt;br /&gt;
 sudo apt install python3.14-full&lt;br /&gt;
&lt;br /&gt;
Pip:&lt;br /&gt;
 curl -sS https://bootstrap.pypa.io/get-pip.py | python3.14&lt;br /&gt;
&lt;br /&gt;
 python3.14 -m pip install pip --upgrade&lt;br /&gt;
&lt;br /&gt;
 python3.14 -m pip --version&lt;br /&gt;
&lt;br /&gt;
 python3.14 -m pip list&lt;br /&gt;
&lt;br /&gt;
venv:  (requires pip)&lt;br /&gt;
 python3.14 -m venv -h&lt;br /&gt;
&lt;br /&gt;
 # check if pip is working&lt;br /&gt;
 python3.14 -m ensurepip&lt;br /&gt;
   #   /usr/bin/python3.14: No module named ensurepip&lt;br /&gt;
   # if this fails with the above, install pip and python3.14-venv ^&lt;br /&gt;
&lt;br /&gt;
 cd ~ ; rm -rf .test-venv ; mkdir .test-venv ; cd .test-venv ; python3.14 -m venv venv&lt;br /&gt;
&lt;br /&gt;
== pip3.14 script ==&lt;br /&gt;
&lt;br /&gt;
Dead-Snakes doesn&#039;t install the pip3.14 script for reasons...  Can manually install, by copying the python 3.12 version, and changing the shebang header from python3 to python3.14&lt;br /&gt;
&lt;br /&gt;
 cd /usr/bin&lt;br /&gt;
 cp pip3.12 pip3.14&lt;br /&gt;
 sed -i &amp;quot;s/python3/python3.14/&amp;quot; pip3.14&lt;br /&gt;
&lt;br /&gt;
Note, calling pip directly as root will error out, but at least as users you can call it to install local packages&lt;br /&gt;
 pip3.14 install pip --upgrade&lt;br /&gt;
  ERROR: Cannot uninstall pip 24.0, RECORD file not found. Hint: The package was installed by debian.&lt;br /&gt;
&lt;br /&gt;
/usr/bin/pip3.14&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/python3.14&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
import re&lt;br /&gt;
import sys&lt;br /&gt;
from pip._internal.cli.main import main&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
    sys.argv[0] = re.sub(r&amp;quot;(-script\.pyw|\.exe)?$&amp;quot;, &amp;quot;&amp;quot;, sys.argv[0])&lt;br /&gt;
    sys.exit(main())&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Alternatively, you could also just create an alias:&lt;br /&gt;
&lt;br /&gt;
 alias pip3.14=&amp;quot;python3.14 -m pip&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== keywords ==&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=Ubuntu/Python/3.14&amp;diff=9867</id>
		<title>Ubuntu/Python/3.14</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=Ubuntu/Python/3.14&amp;diff=9867"/>
		<updated>2026-04-27T20:04:17Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: /* pip3.14 script */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Install with DeadSnakes PPA ==&lt;br /&gt;
&lt;br /&gt;
Dependency:&lt;br /&gt;
 sudo apt install software-properties-common&lt;br /&gt;
&lt;br /&gt;
Add Deadsnakes and install python 3.14&lt;br /&gt;
 sudo add-apt-repository ppa:deadsnakes/ppa&lt;br /&gt;
   # respond to prompts&lt;br /&gt;
 sudo apt update&lt;br /&gt;
 sudo apt install python3.14&lt;br /&gt;
 # should also install:&lt;br /&gt;
 sudo apt install python3.14-dev python3.14-venv&lt;br /&gt;
&lt;br /&gt;
 python3.14 --version&lt;br /&gt;
&lt;br /&gt;
For development, virtuan env&lt;br /&gt;
 sudo apt install python3.14-dev python3.14-venv&lt;br /&gt;
&lt;br /&gt;
For a more complete installation including the Tkinter IDE and other utilities, you can use:&lt;br /&gt;
 sudo apt install python3.14-full&lt;br /&gt;
&lt;br /&gt;
Pip:&lt;br /&gt;
 curl -sS https://bootstrap.pypa.io/get-pip.py | python3.14&lt;br /&gt;
&lt;br /&gt;
 python3.14 -m pip install pip --upgrade&lt;br /&gt;
&lt;br /&gt;
 python3.14 -m pip --version&lt;br /&gt;
&lt;br /&gt;
 python3.14 -m pip list&lt;br /&gt;
&lt;br /&gt;
venv:  (requires pip)&lt;br /&gt;
 python3.14 -m venv -h&lt;br /&gt;
&lt;br /&gt;
 # check if pip is working&lt;br /&gt;
 python3.14 -m ensurepip&lt;br /&gt;
   #   /usr/bin/python3.14: No module named ensurepip&lt;br /&gt;
   # if this fails with the above, install pip and python3.14-venv ^&lt;br /&gt;
&lt;br /&gt;
 cd ~ ; rm -rf .test-venv ; mkdir .test-venv ; cd .test-venv ; python3.14 -m venv venv&lt;br /&gt;
&lt;br /&gt;
== pip3.14 script ==&lt;br /&gt;
&lt;br /&gt;
Dead-Snakes doesn&#039;t install the pip3.14 script for reasons...  Can manually install, by copying the python 3.12 version, and changing the shebang header from python3 to python3.14&lt;br /&gt;
&lt;br /&gt;
 cd /usr/bin&lt;br /&gt;
 cp pip3.12 pip3.14&lt;br /&gt;
 sed -i &amp;quot;s/python3/python3.14/&amp;quot; pip3.14&lt;br /&gt;
&lt;br /&gt;
 pip3.14 install pip --upgrade&lt;br /&gt;
  ERROR: Cannot uninstall pip 24.0, RECORD file not found. Hint: The package was installed by debian.&lt;br /&gt;
&lt;br /&gt;
/usr/bin/pip3.14&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/python3.14&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
import re&lt;br /&gt;
import sys&lt;br /&gt;
from pip._internal.cli.main import main&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
    sys.argv[0] = re.sub(r&amp;quot;(-script\.pyw|\.exe)?$&amp;quot;, &amp;quot;&amp;quot;, sys.argv[0])&lt;br /&gt;
    sys.exit(main())&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Alternatively, you could also just create an alias:&lt;br /&gt;
&lt;br /&gt;
 alias pip3.14=&amp;quot;python3.14 -m pip&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== keywords ==&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=Ubuntu/Python/3.14&amp;diff=9866</id>
		<title>Ubuntu/Python/3.14</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=Ubuntu/Python/3.14&amp;diff=9866"/>
		<updated>2026-04-27T20:01:53Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: /* pip3.14 script */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Install with DeadSnakes PPA ==&lt;br /&gt;
&lt;br /&gt;
Dependency:&lt;br /&gt;
 sudo apt install software-properties-common&lt;br /&gt;
&lt;br /&gt;
Add Deadsnakes and install python 3.14&lt;br /&gt;
 sudo add-apt-repository ppa:deadsnakes/ppa&lt;br /&gt;
   # respond to prompts&lt;br /&gt;
 sudo apt update&lt;br /&gt;
 sudo apt install python3.14&lt;br /&gt;
 # should also install:&lt;br /&gt;
 sudo apt install python3.14-dev python3.14-venv&lt;br /&gt;
&lt;br /&gt;
 python3.14 --version&lt;br /&gt;
&lt;br /&gt;
For development, virtuan env&lt;br /&gt;
 sudo apt install python3.14-dev python3.14-venv&lt;br /&gt;
&lt;br /&gt;
For a more complete installation including the Tkinter IDE and other utilities, you can use:&lt;br /&gt;
 sudo apt install python3.14-full&lt;br /&gt;
&lt;br /&gt;
Pip:&lt;br /&gt;
 curl -sS https://bootstrap.pypa.io/get-pip.py | python3.14&lt;br /&gt;
&lt;br /&gt;
 python3.14 -m pip install pip --upgrade&lt;br /&gt;
&lt;br /&gt;
 python3.14 -m pip --version&lt;br /&gt;
&lt;br /&gt;
 python3.14 -m pip list&lt;br /&gt;
&lt;br /&gt;
venv:  (requires pip)&lt;br /&gt;
 python3.14 -m venv -h&lt;br /&gt;
&lt;br /&gt;
 # check if pip is working&lt;br /&gt;
 python3.14 -m ensurepip&lt;br /&gt;
   #   /usr/bin/python3.14: No module named ensurepip&lt;br /&gt;
   # if this fails with the above, install pip and python3.14-venv ^&lt;br /&gt;
&lt;br /&gt;
 cd ~ ; rm -rf .test-venv ; mkdir .test-venv ; cd .test-venv ; python3.14 -m venv venv&lt;br /&gt;
&lt;br /&gt;
== pip3.14 script ==&lt;br /&gt;
&lt;br /&gt;
Dead-Snakes doesn&#039;t install the pip3.14 script for reasons...  Can manually install, by copying the python 3.12 version, and changing the shebang header from python3 to python3.14&lt;br /&gt;
&lt;br /&gt;
 cd /usr/bin&lt;br /&gt;
 cp pip3.12 pip3.14&lt;br /&gt;
 sed -i &amp;quot;s/python3/python3.14/&amp;quot; pip3.14&lt;br /&gt;
&lt;br /&gt;
/usr/bin/pip3.14&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/python3.14&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
import re&lt;br /&gt;
import sys&lt;br /&gt;
from pip._internal.cli.main import main&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
    sys.argv[0] = re.sub(r&amp;quot;(-script\.pyw|\.exe)?$&amp;quot;, &amp;quot;&amp;quot;, sys.argv[0])&lt;br /&gt;
    sys.exit(main())&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Alternatively, you could also just create an alias:&lt;br /&gt;
&lt;br /&gt;
 alias pip3.14=&amp;quot;python3.14 -m pip&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== keywords ==&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=Apache&amp;diff=9865</id>
		<title>Apache</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=Apache&amp;diff=9865"/>
		<updated>2026-04-27T19:22:58Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: /* .htaccess */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{subpages}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Apache]]&lt;br /&gt;
&lt;br /&gt;
== Install Apache ==&lt;br /&gt;
&lt;br /&gt;
 # Debian / Ubuntu&lt;br /&gt;
 sudo apt install apache2&lt;br /&gt;
&lt;br /&gt;
 # Redhat&lt;br /&gt;
 yum install httpd&lt;br /&gt;
&lt;br /&gt;
== Virtual Hosting ==&lt;br /&gt;
 touch /etc/httpd/conf.d/virtual.conf&lt;br /&gt;
&lt;br /&gt;
Virtual Host Configuration File:&lt;br /&gt;
 /etc/httpd/conf.d/virtual.conf:&lt;br /&gt;
&lt;br /&gt;
HTTP Virtual Host&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
NameVirtualHost *:80&lt;br /&gt;
&lt;br /&gt;
&amp;lt;VirtualHost *:80&amp;gt;&lt;br /&gt;
    ServerName t0e.org&lt;br /&gt;
    ServerAlias www.t0e.org&lt;br /&gt;
&lt;br /&gt;
    DocumentRoot /www&lt;br /&gt;
&lt;br /&gt;
    ServerAdmin admin@t0e.org&lt;br /&gt;
    ErrorLog logs/t0e.org-error_log&lt;br /&gt;
    CustomLog logs/t0e.org-access_log common&lt;br /&gt;
&amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;VirtualHost *:80&amp;gt;&lt;br /&gt;
    ServerName www2.t0e.org&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
HTTPS Virtual Host:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
NameVirtualHost *:443&lt;br /&gt;
&lt;br /&gt;
&amp;lt;VirtualHost *:443&amp;gt;&lt;br /&gt;
    ServerName t0e.org&lt;br /&gt;
    ServerAlias www.t0e.org&lt;br /&gt;
&lt;br /&gt;
    # SSL Enabled:&lt;br /&gt;
    SSLEngine on&lt;br /&gt;
    SSLCertificateFile /etc/t0e.org.pem&lt;br /&gt;
&lt;br /&gt;
    # If using a godaddy certificate chain:&lt;br /&gt;
    #SSLCertificateFile /etc/contractpal.net.pem&lt;br /&gt;
    #SSLCertificateKeyFile /etc/contractpal.net.pem&lt;br /&gt;
    #SSLCertificateChainFile /etc/contractpal.net.pem&lt;br /&gt;
&lt;br /&gt;
    #Forwarding Traffic&lt;br /&gt;
    # RewriteEngine on&lt;br /&gt;
    # RewriteRule ^(/.*)  http://localhost:8080/$1   [P]&lt;br /&gt;
&lt;br /&gt;
    DocumentRoot /www&lt;br /&gt;
&lt;br /&gt;
    ServerAdmin admin@t0e.org&lt;br /&gt;
    ErrorLog logs/t0e.org-error_log&lt;br /&gt;
    CustomLog logs/t0e.org-access_log common&lt;br /&gt;
&amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
*[http://www.onlamp.com/pub/a/apache/2005/02/17/apacheckbk.html A Day in the Life of #Apache: Running Name-Based SSL Virtual Hosts in Apache]&lt;br /&gt;
*[http://httpd.apache.org/docs/1.3/vhosts/name-based.html Apache: Name-based Virtual Host Support]&lt;br /&gt;
*[http://www.networkworld.com/columnists/2006/011606internet.html Getting SSL to work across virtual hosts in Apache]&lt;br /&gt;
&lt;br /&gt;
== CentOS common configuration changes ==&lt;br /&gt;
&lt;br /&gt;
Keep alives:&lt;br /&gt;
 # KeepAlive Off&lt;br /&gt;
 KeepAlive On&lt;br /&gt;
&lt;br /&gt;
Hide Apache version (in likely in /etc/apache2/conf-enabled/security.conf):&lt;br /&gt;
 # ServerTokens Full&lt;br /&gt;
 ServerTokens Prod&lt;br /&gt;
&lt;br /&gt;
 # ServerSignature On&lt;br /&gt;
 ServerSignature Off&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
PHP config in /etc/php.ini (now likely in /etc/php/8.3/apache2/php.ini):&lt;br /&gt;
 expose_php = Off&lt;br /&gt;
&lt;br /&gt;
==Forwarding / Rewriting / Proxying Traffic==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
NameVirtualHost *:80&lt;br /&gt;
&amp;lt;VirtualHost *:80&amp;gt;&lt;br /&gt;
    ServerName t0e.org&lt;br /&gt;
    ServerAlias www.t0e.org&lt;br /&gt;
&lt;br /&gt;
    #Forwarding Traffic&lt;br /&gt;
    RewriteEngine on&lt;br /&gt;
    RewriteRule ^(/.*)  http://localhost:8080/$1   [P]&lt;br /&gt;
&lt;br /&gt;
    ServerAdmin admin@t0e.org&lt;br /&gt;
    ErrorLog logs/t0e.org-error_log&lt;br /&gt;
    CustomLog logs/t0e.org-access_log common&lt;br /&gt;
&amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Apache module mod_rewrite - RewriteRule - http://httpd.apache.org/docs/1.3/mod/mod_rewrite.html#RewriteRule&lt;br /&gt;
 a2enmod rewrite&lt;br /&gt;
&lt;br /&gt;
 a2enmod proxy_http&lt;br /&gt;
&lt;br /&gt;
[http://httpd.apache.org/docs/1.3/mod/mod_rewrite.html Module mod_rewrite - URL Rewriting Engine]:&lt;br /&gt;
*RewriteEngine&lt;br /&gt;
*RewriteCond&lt;br /&gt;
*RewriteRule&lt;br /&gt;
&lt;br /&gt;
[http://httpd.apache.org/docs/1.3/misc/rewriteguide.html Apache 1.3 - URL Rewriting Guide]&lt;br /&gt;
&lt;br /&gt;
[http://httpd.apache.org/docs/1.3/mod/mod_proxy.html Apache module mod_proxy]:&lt;br /&gt;
*ProxyPass&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;VirtualHost *:80&amp;gt;&lt;br /&gt;
    ServerName home.burgenerfamily.com&lt;br /&gt;
    DocumentRoot /www/home&lt;br /&gt;
    &amp;lt;Directory /www/home&amp;gt;&lt;br /&gt;
        Options FollowSymLinks&lt;br /&gt;
        RewriteEngine On&lt;br /&gt;
        # allow existing files and directories to pass through&lt;br /&gt;
        RewriteCond %{REQUEST_FILENAME} !-f&lt;br /&gt;
        RewriteCond %{REQUEST_FILENAME} !-d&lt;br /&gt;
        #RewriteRule ^static - [L,NC] &lt;br /&gt;
        #RewriteCond %{REQUEST_FILENAME} !^favicon.ico$&lt;br /&gt;
        #RewriteCond %{REQUEST_FILENAME} !^static/&lt;br /&gt;
        #RewriteRule ^(.+)$ /index.php?title=$1 [PT,L,QSA]&lt;br /&gt;
        RewriteRule ^(.*)$ /index.php/$1 [L,QSA]&lt;br /&gt;
    &amp;lt;/Directory&amp;gt;&lt;br /&gt;
    ErrorLog logs/home.burgenerfamily.com-error_log&lt;br /&gt;
    CustomLog logs/home.burgenerfamily.com-access_log common&lt;br /&gt;
&amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Proxy Pass ==&lt;br /&gt;
&lt;br /&gt;
Enable Proxy: [https://www.digitalocean.com/community/tutorials/how-to-use-apache-as-a-reverse-proxy-with-mod_proxy-on-ubuntu-16-04]&lt;br /&gt;
 sudo a2enmod proxy&lt;br /&gt;
 sudo a2enmod proxy_http&lt;br /&gt;
 systemctl restart apache2&lt;br /&gt;
&lt;br /&gt;
Similar to forwarding, but takes care of redirects:&lt;br /&gt;
&lt;br /&gt;
   ProxyPass         /mirror/foo/ http://foo.com/&lt;br /&gt;
   ProxyPassReverse  /mirror/foo/ http://foo.com/&lt;br /&gt;
&lt;br /&gt;
Suppose the local server has address http://wibble.org/; then&lt;br /&gt;
&lt;br /&gt;
   ProxyPass         /mirror/foo/ http://foo.com/&lt;br /&gt;
   ProxyPassReverse  /mirror/foo/ http://foo.com/&lt;br /&gt;
&lt;br /&gt;
will not only cause a local request for the &amp;lt;http://wibble.org/mirror/foo/bar&amp;gt; to be internally converted into a proxy request to &amp;lt;http://foo.com/bar&amp;gt; (the functionality ProxyPass provides here). It also takes care of redirects the server foo.com sends: when http://foo.com/bar is redirected by him to http://foo.com/quux Apache adjusts this to http://wibble.org/mirror/foo/quux before forwarding the HTTP redirect response to the client. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;VirtualHost *:80&amp;gt;&lt;br /&gt;
    ServerName wiki.oeey.com&lt;br /&gt;
&lt;br /&gt;
    # Reverse Proxy&lt;br /&gt;
    ProxyPass         / http://localhost:8080/&lt;br /&gt;
    ProxyPassReverse  / http://localhost:8080/&lt;br /&gt;
&lt;br /&gt;
    ServerAdmin website@oeey.com&lt;br /&gt;
    ErrorLog logs/wiki-error_log&lt;br /&gt;
    CustomLog logs/wiki-access_log common&lt;br /&gt;
&amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Proxy Pass to Jenkins: [https://wiki.jenkins-ci.org/display/JENKINS/Running+Jenkins+behind+Apache]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
NameVirtualHost *:80&lt;br /&gt;
&amp;lt;VirtualHost *:80&amp;gt;&lt;br /&gt;
    ServerName jenkins.oeey.com&lt;br /&gt;
&lt;br /&gt;
    #Forwarding Traffic&lt;br /&gt;
    #RewriteEngine on&lt;br /&gt;
    #RewriteRule ^(/.*)  http://localhost:8080/$1   [P]&lt;br /&gt;
&lt;br /&gt;
    ProxyPass         /  http://localhost:8080/ nocanon&lt;br /&gt;
    ProxyPassReverse  /  http://localhost:8080/&lt;br /&gt;
    ProxyRequests     Off&lt;br /&gt;
    ProxyPreserveHost On&lt;br /&gt;
    AllowEncodedSlashes NoDecode&lt;br /&gt;
&lt;br /&gt;
    # Local reverse proxy authorization override&lt;br /&gt;
    # Most unix distribution deny proxy by default (ie /etc/apache2/mods-enabled/proxy.conf in Ubuntu)&lt;br /&gt;
    &amp;lt;Proxy http://localhost:8080/*&amp;gt;&lt;br /&gt;
        Order deny,allow&lt;br /&gt;
        Allow from all&lt;br /&gt;
    &amp;lt;/Proxy&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    ServerAdmin admin@oeey.com&lt;br /&gt;
    ErrorLog logs/jenkins.oeey.com-error_log&lt;br /&gt;
    CustomLog logs/jenkins.oeey.com-access_log common&lt;br /&gt;
&amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Proxy Pass HTTPS ===&lt;br /&gt;
&lt;br /&gt;
Proxy Pass to Jenkins:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
NameVirtualHost *:443&lt;br /&gt;
&amp;lt;VirtualHost *:443&amp;gt;&lt;br /&gt;
    ServerName jenkins.oeey.com&lt;br /&gt;
&lt;br /&gt;
    # Enable SSL Support&lt;br /&gt;
    SSLEngine on&lt;br /&gt;
    SSLCertificateFile /etc/pki/tls/certs/localhost.crt&lt;br /&gt;
    SSLCertificateKeyFile /etc/pki/tls/private/localhost.key&lt;br /&gt;
&lt;br /&gt;
    #Forwarding Traffic&lt;br /&gt;
    #RewriteEngine on&lt;br /&gt;
    #RewriteRule ^(/.*)  http://localhost:8080/$1   [P]&lt;br /&gt;
&lt;br /&gt;
    ProxyPass         /  http://localhost:8080/ nocanon&lt;br /&gt;
    ProxyPassReverse  /  http://localhost:8080/&lt;br /&gt;
    ProxyPassReverse  /  http://jenkins.oeey.com/&lt;br /&gt;
    ProxyRequests     Off&lt;br /&gt;
    ProxyPreserveHost On&lt;br /&gt;
    AllowEncodedSlashes NoDecode&lt;br /&gt;
    RequestHeader set X-Forwarded-Proto &amp;quot;http&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # Local reverse proxy authorization override&lt;br /&gt;
    # Most unix distribution deny proxy by default (ie /etc/apache2/mods-enabled/proxy.conf in Ubuntu)&lt;br /&gt;
    &amp;lt;Proxy http://localhost:8080/jenkins*&amp;gt;&lt;br /&gt;
        Order deny,allow&lt;br /&gt;
        Allow from all&lt;br /&gt;
    &amp;lt;/Proxy&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    ServerAdmin admin@oeey.com&lt;br /&gt;
    ErrorLog logs/jenkins.oeey.com-error_log&lt;br /&gt;
    CustomLog logs/jenkins.oeey.com-access_log common&lt;br /&gt;
&amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Redirect ==&lt;br /&gt;
&lt;br /&gt;
Redirect with URI intact:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
NameVirtualHost *:80&lt;br /&gt;
&amp;lt;VirtualHost *:80&amp;gt;&lt;br /&gt;
    ServerName test.oeey.com&lt;br /&gt;
    Redirect permanent / http://www.oeey.com/&lt;br /&gt;
&amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Redirect users to HTTPS with URI intact:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
NameVirtualHost *:80&lt;br /&gt;
&amp;lt;VirtualHost *:80&amp;gt;&lt;br /&gt;
    ServerName test.oeey.com&lt;br /&gt;
    Redirect permanent / https://test.oeey.com/&lt;br /&gt;
&amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Can be wrapped in Location (if you want)&lt;br /&gt;
 &amp;lt;Location /&amp;gt;&lt;br /&gt;
   Redirect permanent / https://test.oeey.com/&lt;br /&gt;
 &amp;lt;/Location&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Redirect with RewriteEngine with URI intact:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
NameVirtualHost *:80&lt;br /&gt;
&amp;lt;VirtualHost *:80&amp;gt;&lt;br /&gt;
    ServerName test.oeey.com&lt;br /&gt;
&lt;br /&gt;
    # Redirect HTTP to HTTPS&lt;br /&gt;
    RewriteEngine On&lt;br /&gt;
    RewriteCond %{HTTPS} off&lt;br /&gt;
    RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}&lt;br /&gt;
&amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Redirect removing URI:&lt;br /&gt;
 NameVirtualHost *:80&lt;br /&gt;
 &amp;lt;VirtualHost *:80&amp;gt;&lt;br /&gt;
     ServerName test.oeey.com&lt;br /&gt;
     RedirectMatch &amp;quot;(.*)&amp;quot; &amp;quot;http://www.oeey.com/&amp;quot;&lt;br /&gt;
 &amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[http://httpd.apache.org/docs/2.0/mod/mod_alias.html Apache Module mod_alias]:&lt;br /&gt;
*Alias&lt;br /&gt;
*Redirect&lt;br /&gt;
*RedirectPermanent&lt;br /&gt;
&lt;br /&gt;
== Default Directory Index ==&lt;br /&gt;
&lt;br /&gt;
to set the default pages to try and load (e.g. index.html, index.php):&lt;br /&gt;
 DirectoryIndex index.html index.php&lt;br /&gt;
&lt;br /&gt;
== Directory Index ==&lt;br /&gt;
&lt;br /&gt;
To show full file names:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  &amp;lt;Directory /&amp;gt;&lt;br /&gt;
    Options Indexes&lt;br /&gt;
    IndexOptions NameWidth=*&lt;br /&gt;
  &amp;lt;/Directory&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sample:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;Directory &amp;quot;/www&amp;quot;&amp;gt;&lt;br /&gt;
    Options Indexes FollowSymLinks&lt;br /&gt;
    IndexOptions FancyIndexing NameWidth=*&lt;br /&gt;
    AllowOverride None&lt;br /&gt;
    Require all granted&lt;br /&gt;
&amp;lt;/Directory&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Hide Apache and PHP Banner ==&lt;br /&gt;
&lt;br /&gt;
Hide PHP version (X-Powered-By) - Edit php.ini: [http://www.ducea.com/2006/06/16/apache-tips-tricks-hide-php-version-x-powered-by/]&lt;br /&gt;
 expose_php = Off&lt;br /&gt;
&lt;br /&gt;
Hide Apache version: [http://www.itsolutionskb.com/2008/10/hide-apache-information/]&lt;br /&gt;
 # ServerSignature On&lt;br /&gt;
 ServerSignature Off&lt;br /&gt;
 &lt;br /&gt;
 # ServerTokens Full&lt;br /&gt;
 ServerTokens Prod&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* Hide Apache ServerSignature/ServerTokens/PHP X-Powered-By - http://www.if-not-true-then-false.com/2009/howto-hide-and-modify-apache-server-information-serversignature-and-servertokens-and-hide-php-version-x-powered-by/&lt;br /&gt;
&lt;br /&gt;
== .htaccess ==&lt;br /&gt;
&lt;br /&gt;
Override configuration settings on a per directory (and sub directories) level with:&lt;br /&gt;
 .htaccess&lt;br /&gt;
&lt;br /&gt;
Allow override of all configuration options:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;Directory /var/www/html&amp;gt;&lt;br /&gt;
  AllowOverride All&lt;br /&gt;
&amp;lt;/Directory&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example directory browsing in .htaccess:&lt;br /&gt;
 Options +indexes&lt;br /&gt;
&lt;br /&gt;
Redirect to index.php:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RewriteEngine on&lt;br /&gt;
RewriteCond %{REQUEST_FILENAME} !-f&lt;br /&gt;
RewriteCond %{REQUEST_FILENAME} !-d&lt;br /&gt;
RewriteRule ^(.*)$ /index.php?path=$1 [NC,L,QSA]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 a2enmod rewrite&lt;br /&gt;
 #a2enmod proxy_http&lt;br /&gt;
&lt;br /&gt;
Seems to work for subdirectories:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RewriteEngine on&lt;br /&gt;
RewriteCond %{REQUEST_FILENAME} !-f&lt;br /&gt;
RewriteCond %{REQUEST_FILENAME} !-d&lt;br /&gt;
RewriteRule ^.*$ /subdir/index.php?path=$1 [L,QSA]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Allow from networks ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;Directory &amp;quot;...&amp;quot;&amp;gt;&lt;br /&gt;
    Order Deny,Allow&lt;br /&gt;
    Deny from all&lt;br /&gt;
    Allow from 127.0.0.0/255.255.255.0  10.10.0.0/16&lt;br /&gt;
&amp;lt;/Directory&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Log Files ==&lt;br /&gt;
&lt;br /&gt;
    ErrorLog logs/test.com-error_log&lt;br /&gt;
    CustomLog logs/test.com-access_log common&lt;br /&gt;
&lt;br /&gt;
Make sure the soft link exists:&lt;br /&gt;
 ln -s /var/log/httpd /etc/httpd/logs      # RHEL based&lt;br /&gt;
 ln -s /var/log/apache2 /etc/apache2/logs  # Debian Based&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*[http://httpd.apache.org/docs/2.0/logs.html Log Files v2.0]&lt;br /&gt;
*[http://httpd.apache.org/docs/1.3/logs.html#accesslog Log files v1.3]&lt;br /&gt;
&lt;br /&gt;
===Log HTTPS X-Forwarded-For===&lt;br /&gt;
[http://www.webmasterworld.com/forum92/6134.htm Log the X-Forwarded-For] header in apache...&lt;br /&gt;
 LogFormat &amp;quot;[X-Forwarded-For: %{X-Forwarded-For}i] %h %l %u %t \&amp;quot;%r\&amp;quot; %&amp;gt;s %b \&amp;quot;%{Referer}i\&amp;quot; \&amp;quot;%{User-Agent}i\&amp;quot;&amp;quot; combined&lt;br /&gt;
 LogFormat &amp;quot;[X-Forwarded-For: %{X-Forwarded-For}i] %h %l %u %t \&amp;quot;%r\&amp;quot; %&amp;gt;s %b&amp;quot; common&lt;br /&gt;
 LogFormat &amp;quot;%{Referer}i -&amp;gt; %U&amp;quot; referer&lt;br /&gt;
 LogFormat &amp;quot;%{User-agent}i&amp;quot; agent&lt;br /&gt;
&lt;br /&gt;
== PHP ==&lt;br /&gt;
&lt;br /&gt;
Install PHP with Apache: (Ubuntu)&lt;br /&gt;
 #apt-get install apache2 php5 libapache2-mod-php5&lt;br /&gt;
 apt-get install apache2 php libapache2-mod-php&lt;br /&gt;
&lt;br /&gt;
== Apache SSL ==&lt;br /&gt;
&lt;br /&gt;
Enable SSL with...&lt;br /&gt;
&lt;br /&gt;
Apache can do virtual SSL hosting!&lt;br /&gt;
&lt;br /&gt;
Install mod_ssl: [https://help.ubuntu.com/10.04/serverguide/httpd.html]&lt;br /&gt;
 # redhat / rhel&lt;br /&gt;
 sudo yum install mod_ssl&lt;br /&gt;
&lt;br /&gt;
 # debian / ubuntu&lt;br /&gt;
 sudo a2enmod ssl&lt;br /&gt;
 sudo a2ensite default-ssl&lt;br /&gt;
 systemctl reload apache2&lt;br /&gt;
&lt;br /&gt;
/etc/httpd/conf.d/ssl.conf:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LoadModule ssl_module modules/mod_ssl.so&lt;br /&gt;
Listen 443&lt;br /&gt;
AddType application/x-x509-ca-cert .crt&lt;br /&gt;
AddType application/x-pkcs7-crl    .crl&lt;br /&gt;
SSLPassPhraseDialog  builtin&lt;br /&gt;
SSLSessionCache         shmcb:/var/cache/mod_ssl/scache(512000)&lt;br /&gt;
SSLSessionCacheTimeout  300&lt;br /&gt;
SSLMutex default&lt;br /&gt;
SSLRandomSeed startup file:/dev/urandom  256&lt;br /&gt;
SSLRandomSeed connect builtin&lt;br /&gt;
SSLCryptoDevice builtin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: Delete the default VirtualHost section so we can add our own.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# SSL Configuration - from ssl.conf virtual host example&lt;br /&gt;
SSLEngine On&lt;br /&gt;
SSLProtocol all -SSLv2&lt;br /&gt;
SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM:+LOW&lt;br /&gt;
SSLCertificateFile /etc/pki/tls/certs/localhost.crt&lt;br /&gt;
SSLCertificateKeyFile /etc/pki/tls/private/localhost.key&lt;br /&gt;
&lt;br /&gt;
CustomLog logs/ssl_request_log \&lt;br /&gt;
          &amp;quot;%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \&amp;quot;%r\&amp;quot; %b&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# SSL configuration&lt;br /&gt;
SSLEngine On&lt;br /&gt;
SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL&lt;br /&gt;
SSLCertificateFile /etc/apache2/ssl/cert.crt&lt;br /&gt;
SSLCertificateKeyFile /etc/apache2/ssl/cert.key&lt;br /&gt;
SSLCertificateChainFile /etc/apache2/ssl/sf_bundle.crt&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
NameVirtualHost *:80&lt;br /&gt;
&amp;lt;VirtualHost *:80&amp;gt;&lt;br /&gt;
    ServerName default.t0e.org&lt;br /&gt;
&lt;br /&gt;
    # Redirect HTTP to HTTPS&lt;br /&gt;
    RewriteEngine On&lt;br /&gt;
    RewriteCond %{HTTPS} off&lt;br /&gt;
    RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}&lt;br /&gt;
&amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&lt;br /&gt;
NameVirtualHost *:443&lt;br /&gt;
&amp;lt;VirtualHost *:443&amp;gt;&lt;br /&gt;
    ServerName kb.t0e.org&lt;br /&gt;
&lt;br /&gt;
    # SSL Enabled: (only once in config file)&lt;br /&gt;
    SSLEngine on&lt;br /&gt;
    SSLCertificateFile /etc/t0e.org.pem&lt;br /&gt;
    SSLCertificateKeyFile /etc/t0e.org.pem&lt;br /&gt;
    SSLProtocol all -SSLv2&lt;br /&gt;
    SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM:+LOW&lt;br /&gt;
&lt;br /&gt;
    DocumentRoot /www&lt;br /&gt;
&lt;br /&gt;
    ServerAdmin admin@kb.t0e.org.com&lt;br /&gt;
    ErrorLog logs/kb.t0e.org-error_log&lt;br /&gt;
    CustomLog logs/kb.t0e.org-access_log common&lt;br /&gt;
&amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;VirtualHost *:443&amp;gt;&lt;br /&gt;
    ServerName wiki.t0e.org&lt;br /&gt;
&lt;br /&gt;
    DocumentRoot /www&lt;br /&gt;
&lt;br /&gt;
    ServerAdmin admin@wiki.t0e.org.com&lt;br /&gt;
    ErrorLog logs/wiki.t0e.org-error_log&lt;br /&gt;
    CustomLog logs/wiki.t0e.org-access_log common&lt;br /&gt;
&amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: With SSL, Apache will always use the first default virtual hosts&#039; certificate, so it only makes sense to define it there.&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
*[http://www.apache-ssl.org/ Apache SSL]&lt;br /&gt;
*[http://httpd.apache.org/docs/2.0/ssl/ Apache SSL/TLS Encryption Documentation]&lt;br /&gt;
*[http://httpd.apache.org/docs/2.0/mod/mod_ssl.html mod_ssl]&lt;br /&gt;
*[http://www.securityfocus.com/infocus/1818 Article: Apache 2 with SSL/TLS: Step-by-Step, Part 1]&lt;br /&gt;
*[http://www.vanemery.com/Linux/Apache/apache-SSL.html Van&#039;s Apache SSL/TLS mini-HOWTO]&lt;br /&gt;
*[http://tomcat.apache.org/tomcat-3.3-doc/tomcat-ssl-howto.html Tomcat SSL Configuration]&lt;br /&gt;
*[http://httpd.apache.org/docs/2.0/ssl/ssl_faq.html Apache: SSL/TLS Strong Encryption: FAQ]&lt;br /&gt;
*[http://www.networkworld.com/columnists/2006/011606internet.html Getting SSL to work across virtual hosts in Apache]&lt;br /&gt;
*[http://www.faqs.org/docs/Linux-HOWTO/SSL-RedHat-HOWTO.html Building a Secure RedHat Apache Server HOWTO]&lt;br /&gt;
* CommonMisconfigurations - Httpd Wiki - http://wiki.apache.org/httpd/CommonMisconfigurations&lt;br /&gt;
&lt;br /&gt;
--- chain ---&lt;br /&gt;
&lt;br /&gt;
If you have a chain, create the pem as &amp;quot;key, cert, chain&amp;quot; and set Apache config like so:&lt;br /&gt;
&lt;br /&gt;
    SSLCertificateFile /etc/ssl.pem&lt;br /&gt;
    SSLCertificateKeyFile /etc/ssl.pem&lt;br /&gt;
    SSLCertificateChainFile /etc/ssl.pem&lt;br /&gt;
&lt;br /&gt;
or just&lt;br /&gt;
&lt;br /&gt;
    SSLCertificateFile /etc/ssl.pem&lt;br /&gt;
    SSLCertificateChainFile /etc/ssl.pem&lt;br /&gt;
&lt;br /&gt;
=== Ubuntu SnakeOil Cert ===&lt;br /&gt;
&lt;br /&gt;
Install the snakoil fake cert &amp;lt;ref&amp;gt;https://superuser.com/questions/58149/host-based-snakeoil-certificates-in-ubuntu&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 sudo apt-get install ssl-cert&lt;br /&gt;
&lt;br /&gt;
 sudo make-ssl-cert generate-default-snakeoil --force-overwrite&lt;br /&gt;
&lt;br /&gt;
 /etc/ssl/certs/ssl-cert-snakeoil.pem&lt;br /&gt;
 /etc/ssl/private/ssl-cert-snakeoil.key&lt;br /&gt;
&lt;br /&gt;
== Linux System Password Protection ==&lt;br /&gt;
&lt;br /&gt;
Using system accounts for HTTP authentication - http://wiki.zs64.net/Using_system_accounts_for_HTTP_authentication&lt;br /&gt;
&lt;br /&gt;
  httpd.conf&lt;br /&gt;
&lt;br /&gt;
Edit httpd.conf to add these lines to the general configuration:&lt;br /&gt;
&lt;br /&gt;
LoadModule              auth_external_module    libexec/apache2/mod_auth_external.so&lt;br /&gt;
&lt;br /&gt;
(Should have been added by installing the port already.)&lt;br /&gt;
&lt;br /&gt;
Add these lines to each virtual host where you&#039;d like to use system accounts for authentication:&lt;br /&gt;
&lt;br /&gt;
AddExternalAuth         pwauth  /usr/local/bin/pwauth&lt;br /&gt;
SetExternalAuthMethod   pwauth  pipe&lt;br /&gt;
&lt;br /&gt;
Add these lines to each Directory or Location section that you want protected by authentication:&lt;br /&gt;
&lt;br /&gt;
AuthType        Basic&lt;br /&gt;
AuthExternal    pwauth&lt;br /&gt;
require         valid-user&lt;br /&gt;
&lt;br /&gt;
== Password Protection with .htaccess and htpasswd ==&lt;br /&gt;
&lt;br /&gt;
*[http://www.javascriptkit.com/howto/htaccess3.shtml Comprehensive guide to .htaccess: Password protection]&lt;br /&gt;
*[http://apache-server.com/tutorials/ATusing-htaccess.html Using .htaccess Files with Apache]&lt;br /&gt;
*[http://www.4webhelp.net/tutorials/misc/htaccess.php Password Protection by Rod]&lt;br /&gt;
*[http://www.spoono.com/php/tutorials/tutorial.php?id=30 .htaccess Password Protection in PHP]&lt;br /&gt;
&lt;br /&gt;
Sample .htaccess file:&lt;br /&gt;
&lt;br /&gt;
 AuthUserFile /var/www/htpasswd&lt;br /&gt;
 AuthGroupFile /dev/null&lt;br /&gt;
 AuthName &amp;quot;Secret Place&amp;quot;&lt;br /&gt;
 AuthType Basic&lt;br /&gt;
 Require valid-user&lt;br /&gt;
 &lt;br /&gt;
 #Require user &amp;lt;user&amp;gt;&lt;br /&gt;
 #Require group &amp;lt;group&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
To use with httpd.conf or virtual.conf, wrap in &amp;quot;&amp;lt;Directory&amp;gt;&amp;quot; tags:&lt;br /&gt;
 &amp;lt;Directory /&amp;gt;&lt;br /&gt;
   AuthUserFile ...&lt;br /&gt;
   ...&lt;br /&gt;
 &amp;lt;/Directory&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: if you want in your httpd.conf (or virtual.conf) surround with &amp;quot;&amp;lt;Location /&amp;gt;...&amp;lt;/Location&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
To add password file:&lt;br /&gt;
 htpasswd -c /var/www/htpasswd admin&lt;br /&gt;
 htpasswd /var/www/htpasswd user1&lt;br /&gt;
&lt;br /&gt;
 # if you want to create a blank username with password:&lt;br /&gt;
 htpasswd /path/htpasswd &#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To use .htaccess:&lt;br /&gt;
 &amp;lt;Directory /&amp;gt;&lt;br /&gt;
     Options FollowSymLinks&lt;br /&gt;
     AllowOverride &#039;&#039;&#039;AuthConfig&#039;&#039;&#039;&lt;br /&gt;
 &amp;lt;/Directory&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Or user the [http://www.webmaster-toolkit.com/htaccess-generator.shtml .htaccess generator]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[http://httpd.apache.org/docs/2.2/mod/core.html#require Apache HTTP Server - Require Directive]:&lt;br /&gt;
&lt;br /&gt;
Require user userid [userid] ...&lt;br /&gt;
:Only the named users can access the resource.&lt;br /&gt;
Require group group-name [group-name] ...&lt;br /&gt;
:Only users in the named groups can access the resource.&lt;br /&gt;
Require valid-user&lt;br /&gt;
:All valid users can access the resource. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
AuthType Basic&lt;br /&gt;
AuthName &amp;quot;Restricted Resource&amp;quot;&lt;br /&gt;
AuthUserFile /web/users&lt;br /&gt;
AuthGroupFile /web/groups&lt;br /&gt;
Require group admin &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== web based htpasswd manager ===&lt;br /&gt;
&lt;br /&gt;
see [[change_htpasswd.pl]]&lt;br /&gt;
&lt;br /&gt;
[http://home.xnet.com/~efflandt/pub/htpasswd.pl htpasswd.cgi by David Efflandt]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Perl CGI Script to Modify User Passwords:&lt;br /&gt;
&lt;br /&gt;
This allows users to manage / change their own passwords.&lt;br /&gt;
&lt;br /&gt;
Use the Perl CGI script [http://home.xnet.com/%7Eefflandt/pub/htpasswd.pl htpasswd.pl] [[http://www.yolinux.com/TUTORIALS/src/htpasswd_pl.txt cache]]&lt;br /&gt;
&lt;br /&gt;
* Edit location of Perl .i.e.: /usr/bin/perl&lt;br /&gt;
** Not /usr/local/bin/perl&lt;br /&gt;
* Edit the script to specify location of the password file i.e. /var/www/PasswordDir/.htpasswd&lt;br /&gt;
* SELinux users must add the correct attribute i.e. chcon -R -h -t httpd_sys_content_t /var/www/PasswordDir&lt;br /&gt;
* The password file must be located in a directory where CGI is allowed to modify files.&lt;br /&gt;
&lt;br /&gt;
File: httpd.conf (portion):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
..&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;Directory &amp;quot;/var/www/PasswordDir&amp;quot;&amp;gt;&lt;br /&gt;
    Options -Indexes&lt;br /&gt;
    AllowOverride None&lt;br /&gt;
    Options None&lt;br /&gt;
    Order allow,deny&lt;br /&gt;
    Allow from all&lt;br /&gt;
&amp;lt;/Directory&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
..&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Directory Browsing==&lt;br /&gt;
 DocumentRoot /www/files&lt;br /&gt;
 &amp;lt;Directory /&amp;gt;&lt;br /&gt;
     Options FollowSymLinks &#039;&#039;&#039;+Indexes&#039;&#039;&#039;&lt;br /&gt;
     AllowOverride None&lt;br /&gt;
 &amp;lt;/Directory&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: The &#039;+&#039; may not be needed.&lt;br /&gt;
&lt;br /&gt;
In a .htaccess:&lt;br /&gt;
 Options +indexes&lt;br /&gt;
&lt;br /&gt;
Long file names: [http://www.networkworld.com/article/2311687/software/showing-long-file-names-in-apache-directory-listings.html]&lt;br /&gt;
 IndexOptions NameWidth=*&lt;br /&gt;
&lt;br /&gt;
For root indexes, the welcome.conf may be overriding with the welcome screen.  Make the following change: [http://www.linuxquestions.org/questions/linux-general-1/apache-2-root-directory-listing-201356/]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;LocationMatch &amp;quot;^/$&amp;gt;&lt;br /&gt;
    #Options -Indexes&lt;br /&gt;
    Options Indexes&lt;br /&gt;
    ErrorDocument 403 /error/noindex.html&lt;br /&gt;
&amp;lt;/LocationMatch&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== cgi ==&lt;br /&gt;
&lt;br /&gt;
Script Alias folder:&lt;br /&gt;
 ScriptAlias /cgi-bin/ &amp;quot;C:/Program Files/Apache Group/Apache/cgi-bin/&amp;quot; &lt;br /&gt;
 ScriptAlias /cgi-bin/ &amp;quot;/var/www/cgi-bin/&amp;quot;&lt;br /&gt;
&lt;br /&gt;
My favorite option, make all .cgi files executable: (This will need to be surrounded with &#039;&amp;lt;Location /&amp;gt;&#039; or &#039;&amp;lt;Directory /&amp;gt;&#039; tags)&lt;br /&gt;
 AddHandler cgi-script .cgi &lt;br /&gt;
 Options +ExecCGI &lt;br /&gt;
&lt;br /&gt;
Note: Make sure to &#039;chmod +x&#039; the files.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;VirtualHost *:80&amp;gt;&lt;br /&gt;
    ServerName hg.t0e.org&lt;br /&gt;
&lt;br /&gt;
    DirectoryIndex hgweb.cgi&lt;br /&gt;
    DocumentRoot /www/hg&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;Location /&amp;gt;&lt;br /&gt;
        AddHandler cgi-script .cgi&lt;br /&gt;
        Options +ExecCGI&lt;br /&gt;
    &amp;lt;/Location&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    ServerAdmin admin@hg.t0e.org&lt;br /&gt;
    ErrorLog logs/hg.t0e.org-error_log&lt;br /&gt;
    CustomLog logs/hg.t0e.org-access_log common&lt;br /&gt;
&amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Source: [http://www.thesitewizard.com/archive/addcgitoapache.shtml How to Add CGI Script Support (Perl, Python, etc) to Your Apache Server on Windows (thesitewizard.com)]&lt;br /&gt;
&lt;br /&gt;
--&lt;br /&gt;
&lt;br /&gt;
Only files without an extension:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;VirtualHost *:80&amp;gt;&lt;br /&gt;
    ServerName pi.t0e.org&lt;br /&gt;
    DocumentRoot /www/pi&lt;br /&gt;
    &amp;lt;Directory /&amp;gt;&lt;br /&gt;
        AllowOverride All&lt;br /&gt;
    &amp;lt;/Directory&amp;gt;&lt;br /&gt;
    DirectoryIndex index index.php index.html index.htm&lt;br /&gt;
    &amp;lt;Files ~ &amp;quot;^[a-zA-Z]*$&amp;quot;&amp;gt;&lt;br /&gt;
        SetHandler cgi-script&lt;br /&gt;
        Options +ExecCGI&lt;br /&gt;
    &amp;lt;/Files&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
=== CentOS Default ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#&lt;br /&gt;
# ScriptAliases are essentially the same as Aliases, except that&lt;br /&gt;
# documents in the realname directory are treated as applications and&lt;br /&gt;
# run by the server when requested rather than as documents sent to the client.&lt;br /&gt;
# The same rules about trailing &amp;quot;/&amp;quot; apply to ScriptAlias directives as to&lt;br /&gt;
# Alias.&lt;br /&gt;
#&lt;br /&gt;
ScriptAlias /cgi-bin/ &amp;quot;/var/www/cgi-bin/&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
# &amp;quot;/var/www/cgi-bin&amp;quot; should be changed to whatever your ScriptAliased&lt;br /&gt;
# CGI directory exists, if you have that configured.&lt;br /&gt;
#&lt;br /&gt;
&amp;lt;Directory &amp;quot;/var/www/cgi-bin&amp;quot;&amp;gt;&lt;br /&gt;
    AllowOverride None&lt;br /&gt;
    Options None&lt;br /&gt;
    Order allow,deny&lt;br /&gt;
    Allow from all&lt;br /&gt;
&amp;lt;/Directory&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Python CGI ==&lt;br /&gt;
&lt;br /&gt;
See [[Python#Apache_CGI]]&lt;br /&gt;
&lt;br /&gt;
==mod_proxy==&lt;br /&gt;
*http://www.apachetutor.org/admin/reverseproxies&lt;br /&gt;
*http://www.linuxfocus.org/English/March2000/article147.html&lt;br /&gt;
*http://www.linuxhelp.net/guides/apacheproxy/&lt;br /&gt;
*http://webauth.stanford.edu/manual/mod/mod_proxy.html&lt;br /&gt;
*http://www.apachetutor.org/admin/reverseproxies&lt;br /&gt;
*http://confluence.atlassian.com/display/DOC/Using+Apache+with+mod_proxy&lt;br /&gt;
*http://www.serverwatch.com/tutorials/article.php/3290851&lt;br /&gt;
*http://apache.webthing.com/mod_proxy_html/&lt;br /&gt;
*http://www.ibm.com/developerworks/linux/library/wa-lampsec/index.html&lt;br /&gt;
&lt;br /&gt;
== prefork vs worker ==&lt;br /&gt;
&lt;br /&gt;
Prefork performs better.  Worker uses less memory.  Prefork is most commonly used, and is the better choice for a web server.&lt;br /&gt;
&lt;br /&gt;
To see which is compiled, and look for prefork.c or worker.c:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# httpd -l&lt;br /&gt;
 &lt;br /&gt;
Compiled in modules:&lt;br /&gt;
  core.c&lt;br /&gt;
  prefork.c&lt;br /&gt;
  http_core.c&lt;br /&gt;
  mod_so.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Statistics ==&lt;br /&gt;
&lt;br /&gt;
=== Connections ===&lt;br /&gt;
&lt;br /&gt;
Count active connections:&lt;br /&gt;
 netstat -ant | grep ESTABLISHED | grep :80 | wc -l&lt;br /&gt;
&lt;br /&gt;
From PHP:&lt;br /&gt;
 &amp;lt;?php&lt;br /&gt;
 $number_of_users = shell_exec(&#039;netstat -ant | grep ESTABLISHED | grep :80 | wc -l&#039;);&lt;br /&gt;
 echo $number_of_users;&lt;br /&gt;
 ?&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* [http://www.experts-exchange.com/OS/Linux/Q_22825240.html Find out how many connections are on an apache server : apache, connections, many, find, server]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== [http://httpd.apache.org/docs/2.0/mod/mod_status.html mod_status] ===&lt;br /&gt;
&lt;br /&gt;
[http://httpd.apache.org/docs/2.0/mod/mod_status.html mod_status - Apache HTTP Server]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Summary&lt;br /&gt;
&lt;br /&gt;
The Status module allows a server administrator to find out how well their server is performing. A HTML page is presented that gives the current server statistics in an easily readable form. If required this page can be made to automatically refresh (given a compatible browser). Another page gives a simple machine-readable list of the current server state.&lt;br /&gt;
&lt;br /&gt;
The details given are:&lt;br /&gt;
&lt;br /&gt;
* The number of worker serving requests&lt;br /&gt;
* The number of idle worker&lt;br /&gt;
* The status of each worker, the number of requests that worker has performed and the total number of bytes served by the worker (*)&lt;br /&gt;
* A total number of accesses and byte count served (*)&lt;br /&gt;
* The time the server was started/restarted and the time it has been running for&lt;br /&gt;
* Averages giving the number of requests per second, the number of bytes served per second and the average number of bytes per request (*)&lt;br /&gt;
* The current percentage CPU used by each worker and in total by Apache (*)&lt;br /&gt;
* The current hosts and requests being processed (*)&lt;br /&gt;
&lt;br /&gt;
The lines marked &amp;quot;(*)&amp;quot; are only available if ExtendedStatus is On.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LoadModule status_module modules/mod_status.so&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
# ExtendedStatus controls whether Apache will generate &amp;quot;full&amp;quot; status&lt;br /&gt;
# information (ExtendedStatus On) or just basic information (ExtendedStatus&lt;br /&gt;
# Off) when the &amp;quot;server-status&amp;quot; handler is called. The default is Off.&lt;br /&gt;
#&lt;br /&gt;
#ExtendedStatus On&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
# Allow server status reports generated by mod_status,&lt;br /&gt;
# with the URL of http://servername/server-status&lt;br /&gt;
# Change the &amp;quot;.example.com&amp;quot; to match your domain to enable.&lt;br /&gt;
#&lt;br /&gt;
#&amp;lt;Location /server-status&amp;gt;&lt;br /&gt;
#    SetHandler server-status&lt;br /&gt;
#    Order deny,allow&lt;br /&gt;
#    Deny from all&lt;br /&gt;
#    Allow from .example.com&lt;br /&gt;
#&amp;lt;/Location&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* [http://httpd.apache.org/docs/2.0/mod/mod_status.html mod_status - Apache HTTP Server]&lt;br /&gt;
* [http://www.experts-exchange.com/OS/Linux/Q_22825240.html Find out how many connections are on an apache server : apache, connections, many, find, server]&lt;br /&gt;
&lt;br /&gt;
== TRACE and TRACK ==&lt;br /&gt;
&lt;br /&gt;
ISO Audit may result in this &amp;quot;Medium&amp;quot; risk detected:&lt;br /&gt;
&lt;br /&gt;
:&amp;quot;HTTP Methods Allowed.  It is observed that HTTP methods GET HEAD TRACE OPTIONS are allowed on this host.  Disable all unnecessary methods.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
:&amp;quot;HTTP TRACE / TRACK Methods Allowed.  The remote webserver supports the TRACE and/or TRACK methods.  TRACE and TRACK are HTTP methods that are used to debug web server connections.  Disable these methods.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Disabling TRACE ===&lt;br /&gt;
&lt;br /&gt;
[http://rackerhacker.com/2007/08/28/apache-disable-trace-and-track-methods/ Apache: Disable TRACE and TRACK methods | Racker Hacker]:&lt;br /&gt;
&lt;br /&gt;
Lots of PCI Compliance and vulnerability scan vendors will complain about TRACE and TRACK methods being enabled on your server. Since most providers run Nessus, you&#039;ll see this fairly often. Here&#039;s the rewrite rules to add:&lt;br /&gt;
&lt;br /&gt;
 RewriteEngine on&lt;br /&gt;
 RewriteCond %{REQUEST_METHOD} ^(TRACE|TRACK)&lt;br /&gt;
 RewriteRule .* - [F]&lt;br /&gt;
&lt;br /&gt;
These directives will need to be added to each VirtualHost.&lt;br /&gt;
&lt;br /&gt;
For apache version 1.3.34 (or later 1.3.x versions), or apache 2.0.55 (or later), this has been made easy. Just add the line TraceEnable off&lt;br /&gt;
&lt;br /&gt;
 TraceEnable off&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[http://publib.boulder.ibm.com/httpserv/ihsdiag/http_trace.html Disabling the HTTP TRACE method]:&lt;br /&gt;
&lt;br /&gt;
The HTTP TRACE request method causes the data received by IBM HTTP Server from the client to be sent back to the client, as in the following example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ telnet 127.0.0.1 8080&lt;br /&gt;
Trying...&lt;br /&gt;
Connected to 127.0.0.1.&lt;br /&gt;
Escape character is &#039;^]&#039;.&lt;br /&gt;
TRACE / HTTP/1.0&lt;br /&gt;
Host: foo&lt;br /&gt;
A: b&lt;br /&gt;
C: d&lt;br /&gt;
&lt;br /&gt;
HTTP/1.1 200 OK&lt;br /&gt;
Date: Mon, 04 Oct 2004 14:07:59 GMT&lt;br /&gt;
Server: IBM_HTTP_SERVER&lt;br /&gt;
Connection: close&lt;br /&gt;
Content-Type: message/http&lt;br /&gt;
&lt;br /&gt;
TRACE / HTTP/1.0&lt;br /&gt;
A: b&lt;br /&gt;
C: d&lt;br /&gt;
Host: foo&lt;br /&gt;
&lt;br /&gt;
Connection closed.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The TRACE capability could be used by vulnerable or malicious applications to trick a web browser into issuing a TRACE request against an arbitrary site and then send the response to the TRACE to a third party using web browser features.&lt;br /&gt;
&lt;br /&gt;
Making the required configuration changes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;VirtualHost www.example.com&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
# disable TRACE in the www.example.com virtual host&lt;br /&gt;
RewriteEngine On &lt;br /&gt;
RewriteCond %{REQUEST_METHOD} ^TRACE &lt;br /&gt;
RewriteRule .* - [F] &lt;br /&gt;
&amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Using SSL:&lt;br /&gt;
 $ /usr/linux/bin/openssl s_client -connect 127.0.0.1:8444&lt;br /&gt;
&lt;br /&gt;
For more information...&lt;br /&gt;
&lt;br /&gt;
More background information on the concerns with TRACE is provided at http://www.apacheweek.com/issues/03-01-24#news.&lt;br /&gt;
&lt;br /&gt;
Other:&lt;br /&gt;
* Apache Tips: Disable the HTTP TRACE method | MDLog:/sysadmin - http://www.ducea.com/2007/10/22/apache-tips-disable-the-http-trace-method/&lt;br /&gt;
&lt;br /&gt;
=== TraceEnable ===&lt;br /&gt;
&lt;br /&gt;
Apache Core Features - http://httpd.apache.org/docs/1.3/mod/core.html#traceenable&lt;br /&gt;
&lt;br /&gt;
TraceEnable:&lt;br /&gt;
 Syntax: TraceEnable [on|off|extended]&lt;br /&gt;
 Default: TraceEnable on&lt;br /&gt;
 Context: server config&lt;br /&gt;
 Status: core (Windows, NetWare)&lt;br /&gt;
 Compatibility: Available only in Apache 1.3.34, 2.0.55 and later&lt;br /&gt;
&lt;br /&gt;
This directive overrides the behavior of TRACE for both the core server and mod_proxy. The default TraceEnable on permits TRACE requests per RFC 2616, which disallows any request body to accompany the request. TraceEnable off causes the core server and mod_proxy to return a 405 FORBIDDEN error to the client.&lt;br /&gt;
&lt;br /&gt;
Finally, for testing and diagnostic purposes only, request bodies may be allowed using the non-compliant TraceEnable extended directive. The core (as an origin server) will restrict the request body to 64k (plus 8k for chunk headers if Transfer-Encoding: chunked is used). The core will reflect the full headers and all chunk headers with the request body. As a proxy server, the request body is not restricted to 64k. At this time the Apache 1.3 mod_proxy does not permit chunked request bodies for any request, including the extended TRACE request.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Disabling TRACK ===&lt;br /&gt;
&lt;br /&gt;
The HTTP TRACK method&lt;br /&gt;
&lt;br /&gt;
The TRACK method is a type of request supported by Microsoft web servers. It is not RFC compliant and is not supported directly by IBM HTTP Server. The method may be utilized as part of a cross-site scripting attack. See Vulnerability Note VU#288308 for more information.&lt;br /&gt;
&lt;br /&gt;
Even though IBM HTTP Server does not support the TRACK method natively, it is possible for plug-in modules to provide support for it. To disable this capability for plug-in modules, in addition to disabling the TRACE method, add these two additional directives after the existing RewriteCond and RewriteRule directives which are used to disable TRACE:&lt;br /&gt;
&lt;br /&gt;
RewriteCond %{REQUEST_METHOD} ^TRACK&lt;br /&gt;
RewriteRule .* - [F]&lt;br /&gt;
&lt;br /&gt;
Here is a full example showing the directives to disable both TRACE and TRACK:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;VirtualHost www.example.com&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
# disable TRACE and TRACK in the www.example.com virtual host&lt;br /&gt;
RewriteEngine On &lt;br /&gt;
RewriteCond %{REQUEST_METHOD} ^TRACE &lt;br /&gt;
RewriteRule .* - [F] &lt;br /&gt;
RewriteCond %{REQUEST_METHOD} ^TRACK&lt;br /&gt;
RewriteRule .* - [F] &lt;br /&gt;
&amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Attack ===&lt;br /&gt;
&lt;br /&gt;
Cross-Site Tracing issues&lt;br /&gt;
&lt;br /&gt;
Earlier this week a paper was published, [http://www.cgisecurity.com/whitehat-mirror/WH-WhitePaper_XST_ebook.pdf &amp;quot;Cross-Site Tracing&amp;quot;] which gave details of how the TRACE HTTP request could be used in Cross-Site Scripting attacks. Unfortunately this issue has not been very well understood by the media and has received a unwarranted amount of attention.&lt;br /&gt;
&lt;br /&gt;
When an HTTP TRACE request is sent to a web server that supports it, that server will respond echoing the data that is passed to it, including any HTTP headers. The paper explains that some browsers can be scripted to perform a TRACE request. A browser with this functionality could be made to issue a TRACE request against an arbitrary site and pass the results on elsewhere. Since browsers will only send authentication details and cookies to the sites that issue them this means a user having a browser with this functionality could be tricked into sending their cookies or authentication details for arbitrary sites to an attacker.&lt;br /&gt;
&lt;br /&gt;
For example, if you visited a page that an attacker has carefully crafted, the page could cause your browser to bounce a TRACE request against some site for which you have authentication cookies. The result of the TRACE will be a copy of what was sent to the site, which will therefore include those cookies or authentication data. The carefully crafted page can then pass that information on to the attacker.&lt;br /&gt;
&lt;br /&gt;
TRACE requests can be disabled by making a change to the Apache server configuration. Unfortunately it is not possible to do this using the Limit directive since the processing for the TRACE request skips this authorisation checking. Instead the following lines can be added which make use of the mod_rewrite module.&lt;br /&gt;
&lt;br /&gt;
    RewriteEngine On &lt;br /&gt;
    RewriteCond %{REQUEST_METHOD} ^TRACE &lt;br /&gt;
    RewriteRule .* - [F] &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Although the particular attack highlighted made use of the TRACE functionality to grab authentication details, this isn&#039;t a vulnerability in TRACE, or in the Apache web server.&#039;&#039;&#039; The same browser functionality that permits the published attack can be used for different attacks even if TRACE is disabled on the remote web server. For example an attacker could create a carefully crafted page that when visited submits a hidden request to some arbitrary site through your browser, grabs the result and passes it to the attacker.&lt;br /&gt;
&lt;br /&gt;
== Performance Tuning ==&lt;br /&gt;
&lt;br /&gt;
See [[Linux Performance Tuning]]&lt;br /&gt;
&lt;br /&gt;
[http://www.linuxjournal.com/article/6041 Apache and Firewall Performance Tips from the Xenu.net Masters]&lt;br /&gt;
&lt;br /&gt;
=== CentOS January 2009 Thread ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
-------- Original Message --------&lt;br /&gt;
Subject: 	[CentOS] Apache Server Tuning for Performance&lt;br /&gt;
Date: 	Wed, 21 Jan 2009 00:09:38 +0530&lt;br /&gt;
From: 	linux-crazy &amp;lt;hicheerup@gmail.com&amp;gt;&lt;br /&gt;
Reply-To: 	CentOS mailing list &amp;lt;centos@centos.org&amp;gt;&lt;br /&gt;
To: 	CentOS mailing list &amp;lt;centos@centos.org&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Hi all,&lt;br /&gt;
&lt;br /&gt;
I am facing  facing performance issues with our web servers which is&lt;br /&gt;
working for concurrent  250 requests properly and then stops&lt;br /&gt;
responding when the requests are more than 250 .&lt;br /&gt;
&lt;br /&gt;
The current configuration parameters are as follows :&lt;br /&gt;
&lt;br /&gt;
apachectl -version&lt;br /&gt;
Server version: Apache/2.0.52&lt;br /&gt;
Server built:   Jan 30 2007 09:56:16&lt;br /&gt;
&lt;br /&gt;
Kernel : 2.6.9-55.ELsmp #1 SMP Fri Apr 20 16:36:54 EDT 2007 x86_64&lt;br /&gt;
x86_64 x86_64 GNU/Linux&lt;br /&gt;
&lt;br /&gt;
Server Hardware :&lt;br /&gt;
MAIN MEMORY&lt;br /&gt;
(i) Memory Size 4 GB  Dual-Core Intel 5160 processors.&lt;br /&gt;
&lt;br /&gt;
httpd.conf&lt;br /&gt;
&lt;br /&gt;
Timeout 300&lt;br /&gt;
KeepAlive On&lt;br /&gt;
MaxKeepAliveRequests 1000&lt;br /&gt;
KeepAliveTimeout 150&lt;br /&gt;
&lt;br /&gt;
## Server-Pool Size Regulation (MPM specific)&lt;br /&gt;
# prefork MPM&lt;br /&gt;
&lt;br /&gt;
# StartServers: number of server processes to start&lt;br /&gt;
# MinSpareServers: minimum number of server processes which are kept spare&lt;br /&gt;
# MaxSpareServers: maximum number of server processes which are kept spare&lt;br /&gt;
# ServerLimit: maximum value for MaxClients for the lifetime of the server&lt;br /&gt;
# MaxClients: maximum number of server processes allowed to start&lt;br /&gt;
# MaxRequestsPerChild: maximum number of requests a server process serves&lt;br /&gt;
&lt;br /&gt;
&amp;lt;IfModule prefork.c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
StartServers       8&lt;br /&gt;
MinSpareServers    5&lt;br /&gt;
MaxSpareServers   20&lt;br /&gt;
ServerLimit      251&lt;br /&gt;
MaxClients       251&lt;br /&gt;
MaxRequestsPerChild  4000&lt;br /&gt;
&amp;lt;/IfModule&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# worker MPM&lt;br /&gt;
# StartServers: initial number of server processes to start&lt;br /&gt;
# MaxClients: maximum number of simultaneous client connections&lt;br /&gt;
# MinSpareThreads: minimum number of worker threads which are kept spare&lt;br /&gt;
# MaxSpareThreads: maximum number of worker threads which are kept spare&lt;br /&gt;
# ThreadsPerChild: constant number of worker threads in each server process&lt;br /&gt;
# MaxRequestsPerChild: maximum number of requests a server process serves&lt;br /&gt;
&amp;lt;IfModule worker.c&amp;gt;&lt;br /&gt;
StartServers         2&lt;br /&gt;
MaxClients        150&lt;br /&gt;
MinSpareThreads     25&lt;br /&gt;
MaxSpareThreads     75&lt;br /&gt;
ThreadsPerChild     25&lt;br /&gt;
MaxRequestsPerChild  0&lt;br /&gt;
&amp;lt;/IfModule&amp;gt;&lt;br /&gt;
&lt;br /&gt;
     I want to  know about  the difference  between worker MPM and&lt;br /&gt;
Prefork MPM , how to find out which one will be used by my apache&lt;br /&gt;
server and  the recommended one   for highly loaded server.If some one&lt;br /&gt;
provide me the link that best explains above two comparison also  be&lt;br /&gt;
very use full.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 Can any one guide me tuning to be  done for the maximum utilization&lt;br /&gt;
of the Resources  and better performance of the Servers.&lt;br /&gt;
&lt;br /&gt;
 Regards,&lt;br /&gt;
lingu&lt;br /&gt;
_______________________________________________&lt;br /&gt;
CentOS mailing list&lt;br /&gt;
CentOS@centos.org&lt;br /&gt;
http://lists.centos.org/mailman/listinfo/centos&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Only use prefork MPM (worker is for Win32, AFAIK).&lt;br /&gt;
&lt;br /&gt;
If you set ServerLimit to 251, that&#039;s the limit.&lt;br /&gt;
Set ServerLimit and MaxClients to the same value.&lt;br /&gt;
(Larger than 250)&lt;br /&gt;
OK?&lt;br /&gt;
And take a couple of minutes to study the apache documentation. It&#039;s  &lt;br /&gt;
actually quite good and tranlated into many languages...&lt;br /&gt;
&lt;br /&gt;
BUT: what your server is being able to handle also depends on what you  &lt;br /&gt;
actually serve (PHP/JSP/Servelets/Perl/whatever!&lt;br /&gt;
&lt;br /&gt;
This is usually not a problem that is easily described and solved in  &lt;br /&gt;
two sentences.&lt;br /&gt;
&lt;br /&gt;
Rainer&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Increase your MaxClients configuration, also enable if you&lt;br /&gt;
haven&#039;t already the server-status module and monitor the&lt;br /&gt;
server via http://&amp;lt;your server name&amp;gt;/server-status it will&lt;br /&gt;
show how many workers are busy and what they are doing.&lt;br /&gt;
&lt;br /&gt;
As for which to use, prefork is the old forked method of&lt;br /&gt;
doing things, the other uses threads. Depending on what kind&lt;br /&gt;
of application your running on top of apache, if it is not&lt;br /&gt;
thread safe(at some point many PHP modules were not thread&lt;br /&gt;
safe), you may want to use prefork. Otherwise you can use&lt;br /&gt;
the threading model.&lt;br /&gt;
&lt;br /&gt;
If your not sure I&#039;d say stick to prefork to be safe until&lt;br /&gt;
you can determine for sure that threading is safe.&lt;br /&gt;
&lt;br /&gt;
nate&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Most list members would likely advise sticking with the prefork &lt;br /&gt;
configuration.  Without knowing what kind of applications you are &lt;br /&gt;
running on your webserver, I wouldn&#039;t suggest changing it.&lt;br /&gt;
&lt;br /&gt;
Merely increasing the number of workers might make performance worse.&lt;br /&gt;
&lt;br /&gt;
Use ps or top to figure out how much each apache worker is using. Then &lt;br /&gt;
decide how much ram you want to dedicate on your server to Apache, &lt;br /&gt;
without going into swap. (Over-allocating and then paging out memory &lt;br /&gt;
will only make performance much worse.) For example, if I have 2G or &lt;br /&gt;
ram, and I want 1.5 for apache workers, my average apache worker size &lt;br /&gt;
(resident memory) is 65MB, then I have room for 23 workers. (1024 * 1.5 &lt;br /&gt;
) / 65. (There are more accurate ways to calculate this usage, like &lt;br /&gt;
taking shared memory into account.)&lt;br /&gt;
&lt;br /&gt;
Upgrading the ram in your web server is a pretty fast interim solution.&lt;br /&gt;
&lt;br /&gt;
Consider your application performance, too. The longer a request in your &lt;br /&gt;
application takes, the more workers are in use on your web server, &lt;br /&gt;
taking up more memory. If you have long-running queries in your &lt;br /&gt;
database, take care of those first.&lt;br /&gt;
&lt;br /&gt;
Good luck&lt;br /&gt;
&lt;br /&gt;
Jed&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Jed Reynolds wrote:&lt;br /&gt;
&amp;gt; &lt;br /&gt;
&amp;gt; Merely increasing the number of workers might make performance worse.&lt;br /&gt;
&amp;gt; &lt;br /&gt;
&amp;gt; Use ps or top to figure out how much each apache worker is using. Then &lt;br /&gt;
&amp;gt; decide how much ram you want to dedicate on your server to Apache, &lt;br /&gt;
&amp;gt; without going into swap. (Over-allocating and then paging out memory &lt;br /&gt;
&amp;gt; will only make performance much worse.)  For example, if I have 2G or&lt;br /&gt;
&amp;gt; ram, and I want 1.5 for apache workers, my average apache worker size &lt;br /&gt;
&amp;gt; (resident memory) is 65MB, then I have room for 23 workers. (1024 * 1.5 &lt;br /&gt;
&amp;gt; ) / 65. (There are more accurate ways to calculate this usage, like &lt;br /&gt;
&amp;gt; taking shared memory into account.)&lt;br /&gt;
&lt;br /&gt;
Pay attention to shared memory when doing this.  A freshly-forked &lt;br /&gt;
process shares virtually all RAM with its parent.  How much and how &lt;br /&gt;
quickly this changes varies wildly with the application type and &lt;br /&gt;
activity that causes the child&#039;s data to become unique.  With some types &lt;br /&gt;
of applications (especially mod_perl) you may want to tune down the &lt;br /&gt;
number of hits each child services to increase memory sharing.  Also, if &lt;br /&gt;
you are running external cgi programs you must take them into account.&lt;br /&gt;
&lt;br /&gt;
&amp;gt; Upgrading the ram in your web server is a pretty fast interim solution.&lt;br /&gt;
&amp;gt; &lt;br /&gt;
&amp;gt; Consider your application performance, too. The longer a request in your &lt;br /&gt;
&amp;gt; application takes, the more workers are in use on your web server, &lt;br /&gt;
&amp;gt; taking up more memory. If you have long-running queries in your &lt;br /&gt;
&amp;gt; database, take care of those first.&lt;br /&gt;
&lt;br /&gt;
You may also have to turn off or tune down the HTTP 1.1 connection &lt;br /&gt;
keepalives, trading the time it takes to establish a new connection for &lt;br /&gt;
the RAM it takes to keep the associated process waiting for another &lt;br /&gt;
request from the same client.&lt;br /&gt;
&lt;br /&gt;
-- &lt;br /&gt;
   Les Mikesell&lt;br /&gt;
    lesmikesell@gmail.com&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Also take a look at apache alternatives like lighttpd and nginx. In certain&lt;br /&gt;
cases they do miracles.&lt;br /&gt;
&lt;br /&gt;
Jure Pečar&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
I don&#039;t know about lighttpd (our results were mixed) - but NGINX is  &lt;br /&gt;
really _very_ fast.&lt;br /&gt;
Last time I checked, it seems to be the fastest way to accelerate  &lt;br /&gt;
webpage-delivery on generic hardware and with OSS-software.&lt;br /&gt;
&lt;br /&gt;
But it&#039;s not a feature-monster like apache, so you still need that.&lt;br /&gt;
&lt;br /&gt;
Rainer&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Linux-crazy wrote on Wed, 21 Jan 2009 00:09:38 +0530:&lt;br /&gt;
&lt;br /&gt;
&amp;gt; KeepAliveTimeout 150&lt;br /&gt;
&lt;br /&gt;
My god, reduce this to 10 or 5.&lt;br /&gt;
&lt;br /&gt;
&amp;gt; ServerLimit      251&lt;br /&gt;
&amp;gt; MaxClients       251&lt;br /&gt;
&lt;br /&gt;
There&#039;s your limit. However, you should check with your hardware if upping &lt;br /&gt;
it is really desirable. With 4 GB I think you won&#039;t be able to handle much &lt;br /&gt;
more anyway.&lt;br /&gt;
&lt;br /&gt;
Kai&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Kai Schaetzl wrote:&lt;br /&gt;
&amp;gt; There&#039;s your limit. However, you should check with your hardware if upping &lt;br /&gt;
&amp;gt; it is really desirable. With 4 GB I think you won&#039;t be able to handle much &lt;br /&gt;
&amp;gt; more anyway.&lt;br /&gt;
&lt;br /&gt;
That really depends. If you only shove out static pages and have one or&lt;br /&gt;
two or three odd cgis on the machine, you can flatten down the httpd&lt;br /&gt;
binary quite a bit by throwing out unneeded modules.&lt;br /&gt;
&lt;br /&gt;
500 to 750 clients shouldn&#039;t be that much of a problem then ...&lt;br /&gt;
&lt;br /&gt;
Cheers,&lt;br /&gt;
&lt;br /&gt;
Ralph&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Ralph Angenendt wrote on Wed, 21 Jan 2009 10:52:59 +0100:&lt;br /&gt;
&lt;br /&gt;
&amp;gt; That really depends. If you only shove out static pages and have one or&lt;br /&gt;
&amp;gt; two or three odd cgis on the machine, you can flatten down the httpd&lt;br /&gt;
&amp;gt; binary quite a bit by throwing out unneeded modules.&lt;br /&gt;
&amp;gt; &lt;br /&gt;
&amp;gt; 500 to 750 clients shouldn&#039;t be that much of a problem then ...&lt;br /&gt;
&lt;br /&gt;
Sure it depends ;-) I do serve dynamic pages but by removing the really &lt;br /&gt;
unnecessary modules I made my httpds much faster (especially on pipelined &lt;br /&gt;
image downloads) and they only have some 10 MB (RES) per worker.&lt;br /&gt;
&lt;br /&gt;
But I would expect that they are running the default set of modules.&lt;br /&gt;
&lt;br /&gt;
Kai&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Kai Schaetzl schrieb:&lt;br /&gt;
&amp;gt; Ralph Angenendt wrote on Wed, 21 Jan 2009 10:52:59 +0100:&lt;br /&gt;
&amp;gt;&lt;br /&gt;
&amp;gt;   &lt;br /&gt;
&amp;gt;&amp;gt; That really depends. If you only shove out static pages and have one or&lt;br /&gt;
&amp;gt;&amp;gt; two or three odd cgis on the machine, you can flatten down the httpd&lt;br /&gt;
&amp;gt;&amp;gt; binary quite a bit by throwing out unneeded modules.&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt; 500 to 750 clients shouldn&#039;t be that much of a problem then ...&lt;br /&gt;
&amp;gt;&amp;gt;     &lt;br /&gt;
&amp;gt;&lt;br /&gt;
&amp;gt; Sure it depends ;-) I do serve dynamic pages but by removing the really &lt;br /&gt;
&amp;gt; unnecessary modules I made my httpds much faster (especially on pipelined &lt;br /&gt;
&amp;gt; image downloads) and they only have some 10 MB (RES) per worker.&lt;br /&gt;
&amp;gt;&lt;br /&gt;
&amp;gt; But I would expect that they are running the default set of modules.&lt;br /&gt;
&amp;gt;&lt;br /&gt;
&amp;gt; Kai&lt;br /&gt;
&amp;gt;&lt;br /&gt;
&amp;gt;   &lt;br /&gt;
&lt;br /&gt;
If you can separate-out the images to a specific URL (img.domain.com)&lt;br /&gt;
and put them all in the same directory, you can use NGINX to serve them.&lt;br /&gt;
Of course, the actual transfer-speed will not increase much - but&lt;br /&gt;
latency will go down to the absolute minimum.&lt;br /&gt;
And latency is what makes a page appear &amp;quot;fast&amp;quot; or &amp;quot;slow&amp;quot; to customers.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Ralph Angenendt wrote:&lt;br /&gt;
&amp;gt; Kai Schaetzl wrote:&lt;br /&gt;
&amp;gt;&amp;gt; There&#039;s your limit. However, you should check with your hardware if upping&lt;br /&gt;
&amp;gt;&amp;gt; it is really desirable. With 4 GB I think you won&#039;t be able to handle much&lt;br /&gt;
&amp;gt;&amp;gt; more anyway.&lt;br /&gt;
&amp;gt;&lt;br /&gt;
&amp;gt; That really depends. If you only shove out static pages and have one or&lt;br /&gt;
&amp;gt; two or three odd cgis on the machine, you can flatten down the httpd&lt;br /&gt;
&amp;gt; binary quite a bit by throwing out unneeded modules.&lt;br /&gt;
&amp;gt;&lt;br /&gt;
&amp;gt; 500 to 750 clients shouldn&#039;t be that much of a problem then ...&lt;br /&gt;
&lt;br /&gt;
Yeah gotta monitor it.. just checked in on some servers I ran at&lt;br /&gt;
my last company and the front end proxies (99% mod_proxy) seem to&lt;br /&gt;
peak out traffic wise at about 230 workers. For no other reason other&lt;br /&gt;
than because I could each proxy has 8 apache instances running(4 for&lt;br /&gt;
HTTP 4 for HTTPS). CPU usage peaks at around 3%(dual proc single core),&lt;br /&gt;
memory usage around 800MB. About 100 idle workers. Keepalive was set&lt;br /&gt;
to 300 seconds due to poor application design.&lt;br /&gt;
&lt;br /&gt;
One set of back end apache servers peaks traffic wise at around 100&lt;br /&gt;
active workers, though memory usage was higher, around 2GB because&lt;br /&gt;
of mod_fcgid running ruby on rails. CPU usage seems to be at around&lt;br /&gt;
25%(dual proc quad core) for that one application.&lt;br /&gt;
&lt;br /&gt;
Each back end application had it&#039;s own dedicated apache instance(11&lt;br /&gt;
apps) for maximum stability/best performance monitoring. The bulk&lt;br /&gt;
of them ran on the same physical hardware though.&lt;br /&gt;
&lt;br /&gt;
Traffic routing was handled by a combination of F5 load balancers&lt;br /&gt;
and the apache servers previously mentioned(F5 iRules were too slow&lt;br /&gt;
and F5&#039;s TMM was not scalable at the time).&lt;br /&gt;
&lt;br /&gt;
nate&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt; &lt;br /&gt;
&amp;gt; &amp;gt; KeepAliveTimeout 150&lt;br /&gt;
&amp;gt; &lt;br /&gt;
&amp;gt;reduce this to 10 or 5.&lt;br /&gt;
&amp;gt; &lt;br /&gt;
&amp;gt; &lt;br /&gt;
&amp;gt; Kai&lt;br /&gt;
&amp;gt; &lt;br /&gt;
&amp;gt; --&lt;br /&gt;
&amp;gt; Kai Schätzl, Berlin, Germany&lt;br /&gt;
&lt;br /&gt;
Kai,&lt;br /&gt;
&lt;br /&gt;
what do you think about the &amp;quot;general Timeout&lt;br /&gt;
&lt;br /&gt;
it is set to 300&lt;br /&gt;
&lt;br /&gt;
ive never much thought about it, yet should we be consider and possible&lt;br /&gt;
reduce that one too?&lt;br /&gt;
&lt;br /&gt;
 - rh&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RobertH wrote on Wed, 21 Jan 2009 11:26:41 -0800:&lt;br /&gt;
&lt;br /&gt;
&amp;gt; what do you think about the &amp;quot;general Timeout&lt;br /&gt;
&amp;gt; &lt;br /&gt;
&amp;gt; it is set to 300&lt;br /&gt;
&amp;gt; &lt;br /&gt;
&amp;gt; ive never much thought about it, yet should we be consider and possible&lt;br /&gt;
&amp;gt; reduce that one too?&lt;br /&gt;
&lt;br /&gt;
I&#039;m using 120, but I don&#039;t think reducing this value has much impact.&lt;br /&gt;
&lt;br /&gt;
Kai&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Load Balancer ==&lt;br /&gt;
&lt;br /&gt;
Apache Load Balancer&lt;br /&gt;
&lt;br /&gt;
mod_proxy_balancer - Apache HTTP Server - mod_proxy_balancer - http://httpd.apache.org/docs/2.2/mod/mod_proxy_balancer.html&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;Proxy balancer://mycluster&amp;gt;&lt;br /&gt;
BalancerMember http://192.168.1.50:80&lt;br /&gt;
BalancerMember http://192.168.1.51:80&lt;br /&gt;
&amp;lt;/Proxy&amp;gt;&lt;br /&gt;
ProxyPass /test balancer://mycluster &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== User Directories ==&lt;br /&gt;
&lt;br /&gt;
Default:&lt;br /&gt;
 UserDir public_html &lt;br /&gt;
&lt;br /&gt;
Results in:&lt;br /&gt;
 ~/public_html/&lt;br /&gt;
&lt;br /&gt;
To disable user directories:&lt;br /&gt;
 UserDir disabled&lt;br /&gt;
&lt;br /&gt;
Ubuntu user dir config:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        UserDir public_html&lt;br /&gt;
        UserDir disabled root&lt;br /&gt;
&lt;br /&gt;
        &amp;lt;Directory /home/*/public_html&amp;gt;&lt;br /&gt;
                AllowOverride FileInfo AuthConfig Limit Indexes&lt;br /&gt;
                Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec&lt;br /&gt;
                &amp;lt;Limit GET POST OPTIONS&amp;gt;&lt;br /&gt;
                        Order allow,deny&lt;br /&gt;
                        Allow from all&lt;br /&gt;
                &amp;lt;/Limit&amp;gt;&lt;br /&gt;
                &amp;lt;LimitExcept GET POST OPTIONS&amp;gt;&lt;br /&gt;
                        Order deny,allow&lt;br /&gt;
                        Deny from all&lt;br /&gt;
                &amp;lt;/LimitExcept&amp;gt;&lt;br /&gt;
        &amp;lt;/Directory&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* Per-user web directories - Apache HTTP Server - http://httpd.apache.org/docs/2.2/howto/public_html.html&lt;br /&gt;
* mod_userdir - Apache HTTP Server - http://httpd.apache.org/docs/2.2/mod/mod_userdir.html#userdir&lt;br /&gt;
&lt;br /&gt;
== Minimal Memory Instance ==&lt;br /&gt;
&lt;br /&gt;
Assuming running prefork module (check with &#039;apache -l&#039;):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
KeepAlive off&lt;br /&gt;
&lt;br /&gt;
&amp;lt;IfModule mpm_prefork_module&amp;gt;&lt;br /&gt;
StartServers          2&lt;br /&gt;
MinSpareServers       2&lt;br /&gt;
MaxSpareServers      5&lt;br /&gt;
ServerLimit          20&lt;br /&gt;
MaxClients           20&lt;br /&gt;
MaxRequestsPerChild  10000&lt;br /&gt;
&amp;lt;/IfModule&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* Running Apache On A Memory-Constrained VPS | Kalzumeus Software - http://www.kalzumeus.com/2010/06/19/running-apache-on-a-memory-constrained-vps/&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
TODO See:&lt;br /&gt;
*  http://wiki.vpslink.com/Low_memory_MySQL_/_Apache_configurations&lt;br /&gt;
* http://www.narga.net/optimizing-apachephpmysql-low-memory-server/&lt;br /&gt;
&lt;br /&gt;
== LDAP Authentication ==&lt;br /&gt;
&lt;br /&gt;
 # Red Hat / RHEL&lt;br /&gt;
 sudo yum install mod_ldap&lt;br /&gt;
 # allow ldap to connect through selinux:&lt;br /&gt;
 sudo setsebool -P httpd_can_network_connect on&lt;br /&gt;
&lt;br /&gt;
 mod_ldap - Apache HTTP Server Version 2.4&lt;br /&gt;
 https://httpd.apache.org/docs/2.4/mod/mod_ldap.html&lt;br /&gt;
&lt;br /&gt;
== Issues ==&lt;br /&gt;
&lt;br /&gt;
=== Could not reliably determine domain name ===&lt;br /&gt;
&lt;br /&gt;
Warning:&lt;br /&gt;
 Could not reliably determine the server&#039;s fully qualified domain name&lt;br /&gt;
&lt;br /&gt;
Solution:&lt;br /&gt;
* Force ServerName in apache configs [http://askubuntu.com/questions/256013/could-not-reliably-determine-the-servers-fully-qualified-domain-name]&lt;br /&gt;
 ServerName localhost&lt;br /&gt;
&lt;br /&gt;
=== client denied by server configuration ===&lt;br /&gt;
&lt;br /&gt;
browser:&lt;br /&gt;
 403 Forbidden - You don&#039;t have permission to access / on this server.&lt;br /&gt;
&lt;br /&gt;
Error:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
==&amp;gt; httpd/default-error_log &amp;lt;==&lt;br /&gt;
[Mon Sep 01 21:42:02.273169 2014] [authz_core:error] [pid 11221] [client 174.52.47.54:50675] AH01630: client denied by server configuration: /www/&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add Directory allow permissions: [http://stackoverflow.com/questions/19445686/ubuntu-server-apache-2-4-6-client-denied-by-server-configuration-php-fpm]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
DocumentRoot /www&lt;br /&gt;
&amp;lt;Directory /www&amp;gt;&lt;br /&gt;
  Order allow,deny&lt;br /&gt;
  Allow from all&lt;br /&gt;
&amp;lt;/Directory&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or this worked better for me: [http://stackoverflow.com/questions/19445686/ubuntu-server-apache-2-4-6-client-denied-by-server-configuration-php-fpm] [https://mikegriffin.ie/blog/20140130-authz-core-error-client-denied-by-server-configuration/]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
DocumentRoot /www&lt;br /&gt;
&amp;lt;Directory /www&amp;gt;&lt;br /&gt;
  Require all granted&lt;br /&gt;
&amp;lt;/Directory&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Actually this just worked on the latest Ubuntu system:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;Directory /www/&amp;gt;&lt;br /&gt;
        Options Indexes FollowSymLinks&lt;br /&gt;
        AllowOverride None&lt;br /&gt;
        Require all granted&lt;br /&gt;
&amp;lt;/Directory&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* ClientDeniedByServerConfiguration - Httpd Wiki - https://wiki.apache.org/httpd/ClientDeniedByServerConfiguration&lt;br /&gt;
&lt;br /&gt;
=== permissions missing component path ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
==&amp;gt; httpd/default-error_log &amp;lt;==&lt;br /&gt;
[Mon Sep 01 21:50:09.256120 2014] [core:error] [pid 11511] (13)Permission denied: [client 174.52.47.54:50744] AH00035: access to \&lt;br /&gt;
/index.html denied (filesystem path &#039;/www/index.html&#039;) because search permissions are missing on a component of the path&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== keywords ==&lt;br /&gt;
&lt;br /&gt;
[[Category:Linux]]&lt;br /&gt;
[[Category:Web Development ‎]]&lt;br /&gt;
[[Category:Web]]&lt;br /&gt;
[[Category:HTML]]&lt;br /&gt;
[[Category:Internet]]&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=Apache&amp;diff=9864</id>
		<title>Apache</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=Apache&amp;diff=9864"/>
		<updated>2026-04-27T19:21:55Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: /* .htaccess */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{subpages}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Apache]]&lt;br /&gt;
&lt;br /&gt;
== Install Apache ==&lt;br /&gt;
&lt;br /&gt;
 # Debian / Ubuntu&lt;br /&gt;
 sudo apt install apache2&lt;br /&gt;
&lt;br /&gt;
 # Redhat&lt;br /&gt;
 yum install httpd&lt;br /&gt;
&lt;br /&gt;
== Virtual Hosting ==&lt;br /&gt;
 touch /etc/httpd/conf.d/virtual.conf&lt;br /&gt;
&lt;br /&gt;
Virtual Host Configuration File:&lt;br /&gt;
 /etc/httpd/conf.d/virtual.conf:&lt;br /&gt;
&lt;br /&gt;
HTTP Virtual Host&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
NameVirtualHost *:80&lt;br /&gt;
&lt;br /&gt;
&amp;lt;VirtualHost *:80&amp;gt;&lt;br /&gt;
    ServerName t0e.org&lt;br /&gt;
    ServerAlias www.t0e.org&lt;br /&gt;
&lt;br /&gt;
    DocumentRoot /www&lt;br /&gt;
&lt;br /&gt;
    ServerAdmin admin@t0e.org&lt;br /&gt;
    ErrorLog logs/t0e.org-error_log&lt;br /&gt;
    CustomLog logs/t0e.org-access_log common&lt;br /&gt;
&amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;VirtualHost *:80&amp;gt;&lt;br /&gt;
    ServerName www2.t0e.org&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
HTTPS Virtual Host:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
NameVirtualHost *:443&lt;br /&gt;
&lt;br /&gt;
&amp;lt;VirtualHost *:443&amp;gt;&lt;br /&gt;
    ServerName t0e.org&lt;br /&gt;
    ServerAlias www.t0e.org&lt;br /&gt;
&lt;br /&gt;
    # SSL Enabled:&lt;br /&gt;
    SSLEngine on&lt;br /&gt;
    SSLCertificateFile /etc/t0e.org.pem&lt;br /&gt;
&lt;br /&gt;
    # If using a godaddy certificate chain:&lt;br /&gt;
    #SSLCertificateFile /etc/contractpal.net.pem&lt;br /&gt;
    #SSLCertificateKeyFile /etc/contractpal.net.pem&lt;br /&gt;
    #SSLCertificateChainFile /etc/contractpal.net.pem&lt;br /&gt;
&lt;br /&gt;
    #Forwarding Traffic&lt;br /&gt;
    # RewriteEngine on&lt;br /&gt;
    # RewriteRule ^(/.*)  http://localhost:8080/$1   [P]&lt;br /&gt;
&lt;br /&gt;
    DocumentRoot /www&lt;br /&gt;
&lt;br /&gt;
    ServerAdmin admin@t0e.org&lt;br /&gt;
    ErrorLog logs/t0e.org-error_log&lt;br /&gt;
    CustomLog logs/t0e.org-access_log common&lt;br /&gt;
&amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
*[http://www.onlamp.com/pub/a/apache/2005/02/17/apacheckbk.html A Day in the Life of #Apache: Running Name-Based SSL Virtual Hosts in Apache]&lt;br /&gt;
*[http://httpd.apache.org/docs/1.3/vhosts/name-based.html Apache: Name-based Virtual Host Support]&lt;br /&gt;
*[http://www.networkworld.com/columnists/2006/011606internet.html Getting SSL to work across virtual hosts in Apache]&lt;br /&gt;
&lt;br /&gt;
== CentOS common configuration changes ==&lt;br /&gt;
&lt;br /&gt;
Keep alives:&lt;br /&gt;
 # KeepAlive Off&lt;br /&gt;
 KeepAlive On&lt;br /&gt;
&lt;br /&gt;
Hide Apache version (in likely in /etc/apache2/conf-enabled/security.conf):&lt;br /&gt;
 # ServerTokens Full&lt;br /&gt;
 ServerTokens Prod&lt;br /&gt;
&lt;br /&gt;
 # ServerSignature On&lt;br /&gt;
 ServerSignature Off&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
PHP config in /etc/php.ini (now likely in /etc/php/8.3/apache2/php.ini):&lt;br /&gt;
 expose_php = Off&lt;br /&gt;
&lt;br /&gt;
==Forwarding / Rewriting / Proxying Traffic==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
NameVirtualHost *:80&lt;br /&gt;
&amp;lt;VirtualHost *:80&amp;gt;&lt;br /&gt;
    ServerName t0e.org&lt;br /&gt;
    ServerAlias www.t0e.org&lt;br /&gt;
&lt;br /&gt;
    #Forwarding Traffic&lt;br /&gt;
    RewriteEngine on&lt;br /&gt;
    RewriteRule ^(/.*)  http://localhost:8080/$1   [P]&lt;br /&gt;
&lt;br /&gt;
    ServerAdmin admin@t0e.org&lt;br /&gt;
    ErrorLog logs/t0e.org-error_log&lt;br /&gt;
    CustomLog logs/t0e.org-access_log common&lt;br /&gt;
&amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Apache module mod_rewrite - RewriteRule - http://httpd.apache.org/docs/1.3/mod/mod_rewrite.html#RewriteRule&lt;br /&gt;
 a2enmod rewrite&lt;br /&gt;
&lt;br /&gt;
 a2enmod proxy_http&lt;br /&gt;
&lt;br /&gt;
[http://httpd.apache.org/docs/1.3/mod/mod_rewrite.html Module mod_rewrite - URL Rewriting Engine]:&lt;br /&gt;
*RewriteEngine&lt;br /&gt;
*RewriteCond&lt;br /&gt;
*RewriteRule&lt;br /&gt;
&lt;br /&gt;
[http://httpd.apache.org/docs/1.3/misc/rewriteguide.html Apache 1.3 - URL Rewriting Guide]&lt;br /&gt;
&lt;br /&gt;
[http://httpd.apache.org/docs/1.3/mod/mod_proxy.html Apache module mod_proxy]:&lt;br /&gt;
*ProxyPass&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;VirtualHost *:80&amp;gt;&lt;br /&gt;
    ServerName home.burgenerfamily.com&lt;br /&gt;
    DocumentRoot /www/home&lt;br /&gt;
    &amp;lt;Directory /www/home&amp;gt;&lt;br /&gt;
        Options FollowSymLinks&lt;br /&gt;
        RewriteEngine On&lt;br /&gt;
        # allow existing files and directories to pass through&lt;br /&gt;
        RewriteCond %{REQUEST_FILENAME} !-f&lt;br /&gt;
        RewriteCond %{REQUEST_FILENAME} !-d&lt;br /&gt;
        #RewriteRule ^static - [L,NC] &lt;br /&gt;
        #RewriteCond %{REQUEST_FILENAME} !^favicon.ico$&lt;br /&gt;
        #RewriteCond %{REQUEST_FILENAME} !^static/&lt;br /&gt;
        #RewriteRule ^(.+)$ /index.php?title=$1 [PT,L,QSA]&lt;br /&gt;
        RewriteRule ^(.*)$ /index.php/$1 [L,QSA]&lt;br /&gt;
    &amp;lt;/Directory&amp;gt;&lt;br /&gt;
    ErrorLog logs/home.burgenerfamily.com-error_log&lt;br /&gt;
    CustomLog logs/home.burgenerfamily.com-access_log common&lt;br /&gt;
&amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Proxy Pass ==&lt;br /&gt;
&lt;br /&gt;
Enable Proxy: [https://www.digitalocean.com/community/tutorials/how-to-use-apache-as-a-reverse-proxy-with-mod_proxy-on-ubuntu-16-04]&lt;br /&gt;
 sudo a2enmod proxy&lt;br /&gt;
 sudo a2enmod proxy_http&lt;br /&gt;
 systemctl restart apache2&lt;br /&gt;
&lt;br /&gt;
Similar to forwarding, but takes care of redirects:&lt;br /&gt;
&lt;br /&gt;
   ProxyPass         /mirror/foo/ http://foo.com/&lt;br /&gt;
   ProxyPassReverse  /mirror/foo/ http://foo.com/&lt;br /&gt;
&lt;br /&gt;
Suppose the local server has address http://wibble.org/; then&lt;br /&gt;
&lt;br /&gt;
   ProxyPass         /mirror/foo/ http://foo.com/&lt;br /&gt;
   ProxyPassReverse  /mirror/foo/ http://foo.com/&lt;br /&gt;
&lt;br /&gt;
will not only cause a local request for the &amp;lt;http://wibble.org/mirror/foo/bar&amp;gt; to be internally converted into a proxy request to &amp;lt;http://foo.com/bar&amp;gt; (the functionality ProxyPass provides here). It also takes care of redirects the server foo.com sends: when http://foo.com/bar is redirected by him to http://foo.com/quux Apache adjusts this to http://wibble.org/mirror/foo/quux before forwarding the HTTP redirect response to the client. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;VirtualHost *:80&amp;gt;&lt;br /&gt;
    ServerName wiki.oeey.com&lt;br /&gt;
&lt;br /&gt;
    # Reverse Proxy&lt;br /&gt;
    ProxyPass         / http://localhost:8080/&lt;br /&gt;
    ProxyPassReverse  / http://localhost:8080/&lt;br /&gt;
&lt;br /&gt;
    ServerAdmin website@oeey.com&lt;br /&gt;
    ErrorLog logs/wiki-error_log&lt;br /&gt;
    CustomLog logs/wiki-access_log common&lt;br /&gt;
&amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Proxy Pass to Jenkins: [https://wiki.jenkins-ci.org/display/JENKINS/Running+Jenkins+behind+Apache]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
NameVirtualHost *:80&lt;br /&gt;
&amp;lt;VirtualHost *:80&amp;gt;&lt;br /&gt;
    ServerName jenkins.oeey.com&lt;br /&gt;
&lt;br /&gt;
    #Forwarding Traffic&lt;br /&gt;
    #RewriteEngine on&lt;br /&gt;
    #RewriteRule ^(/.*)  http://localhost:8080/$1   [P]&lt;br /&gt;
&lt;br /&gt;
    ProxyPass         /  http://localhost:8080/ nocanon&lt;br /&gt;
    ProxyPassReverse  /  http://localhost:8080/&lt;br /&gt;
    ProxyRequests     Off&lt;br /&gt;
    ProxyPreserveHost On&lt;br /&gt;
    AllowEncodedSlashes NoDecode&lt;br /&gt;
&lt;br /&gt;
    # Local reverse proxy authorization override&lt;br /&gt;
    # Most unix distribution deny proxy by default (ie /etc/apache2/mods-enabled/proxy.conf in Ubuntu)&lt;br /&gt;
    &amp;lt;Proxy http://localhost:8080/*&amp;gt;&lt;br /&gt;
        Order deny,allow&lt;br /&gt;
        Allow from all&lt;br /&gt;
    &amp;lt;/Proxy&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    ServerAdmin admin@oeey.com&lt;br /&gt;
    ErrorLog logs/jenkins.oeey.com-error_log&lt;br /&gt;
    CustomLog logs/jenkins.oeey.com-access_log common&lt;br /&gt;
&amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Proxy Pass HTTPS ===&lt;br /&gt;
&lt;br /&gt;
Proxy Pass to Jenkins:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
NameVirtualHost *:443&lt;br /&gt;
&amp;lt;VirtualHost *:443&amp;gt;&lt;br /&gt;
    ServerName jenkins.oeey.com&lt;br /&gt;
&lt;br /&gt;
    # Enable SSL Support&lt;br /&gt;
    SSLEngine on&lt;br /&gt;
    SSLCertificateFile /etc/pki/tls/certs/localhost.crt&lt;br /&gt;
    SSLCertificateKeyFile /etc/pki/tls/private/localhost.key&lt;br /&gt;
&lt;br /&gt;
    #Forwarding Traffic&lt;br /&gt;
    #RewriteEngine on&lt;br /&gt;
    #RewriteRule ^(/.*)  http://localhost:8080/$1   [P]&lt;br /&gt;
&lt;br /&gt;
    ProxyPass         /  http://localhost:8080/ nocanon&lt;br /&gt;
    ProxyPassReverse  /  http://localhost:8080/&lt;br /&gt;
    ProxyPassReverse  /  http://jenkins.oeey.com/&lt;br /&gt;
    ProxyRequests     Off&lt;br /&gt;
    ProxyPreserveHost On&lt;br /&gt;
    AllowEncodedSlashes NoDecode&lt;br /&gt;
    RequestHeader set X-Forwarded-Proto &amp;quot;http&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # Local reverse proxy authorization override&lt;br /&gt;
    # Most unix distribution deny proxy by default (ie /etc/apache2/mods-enabled/proxy.conf in Ubuntu)&lt;br /&gt;
    &amp;lt;Proxy http://localhost:8080/jenkins*&amp;gt;&lt;br /&gt;
        Order deny,allow&lt;br /&gt;
        Allow from all&lt;br /&gt;
    &amp;lt;/Proxy&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    ServerAdmin admin@oeey.com&lt;br /&gt;
    ErrorLog logs/jenkins.oeey.com-error_log&lt;br /&gt;
    CustomLog logs/jenkins.oeey.com-access_log common&lt;br /&gt;
&amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Redirect ==&lt;br /&gt;
&lt;br /&gt;
Redirect with URI intact:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
NameVirtualHost *:80&lt;br /&gt;
&amp;lt;VirtualHost *:80&amp;gt;&lt;br /&gt;
    ServerName test.oeey.com&lt;br /&gt;
    Redirect permanent / http://www.oeey.com/&lt;br /&gt;
&amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Redirect users to HTTPS with URI intact:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
NameVirtualHost *:80&lt;br /&gt;
&amp;lt;VirtualHost *:80&amp;gt;&lt;br /&gt;
    ServerName test.oeey.com&lt;br /&gt;
    Redirect permanent / https://test.oeey.com/&lt;br /&gt;
&amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Can be wrapped in Location (if you want)&lt;br /&gt;
 &amp;lt;Location /&amp;gt;&lt;br /&gt;
   Redirect permanent / https://test.oeey.com/&lt;br /&gt;
 &amp;lt;/Location&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Redirect with RewriteEngine with URI intact:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
NameVirtualHost *:80&lt;br /&gt;
&amp;lt;VirtualHost *:80&amp;gt;&lt;br /&gt;
    ServerName test.oeey.com&lt;br /&gt;
&lt;br /&gt;
    # Redirect HTTP to HTTPS&lt;br /&gt;
    RewriteEngine On&lt;br /&gt;
    RewriteCond %{HTTPS} off&lt;br /&gt;
    RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}&lt;br /&gt;
&amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Redirect removing URI:&lt;br /&gt;
 NameVirtualHost *:80&lt;br /&gt;
 &amp;lt;VirtualHost *:80&amp;gt;&lt;br /&gt;
     ServerName test.oeey.com&lt;br /&gt;
     RedirectMatch &amp;quot;(.*)&amp;quot; &amp;quot;http://www.oeey.com/&amp;quot;&lt;br /&gt;
 &amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[http://httpd.apache.org/docs/2.0/mod/mod_alias.html Apache Module mod_alias]:&lt;br /&gt;
*Alias&lt;br /&gt;
*Redirect&lt;br /&gt;
*RedirectPermanent&lt;br /&gt;
&lt;br /&gt;
== Default Directory Index ==&lt;br /&gt;
&lt;br /&gt;
to set the default pages to try and load (e.g. index.html, index.php):&lt;br /&gt;
 DirectoryIndex index.html index.php&lt;br /&gt;
&lt;br /&gt;
== Directory Index ==&lt;br /&gt;
&lt;br /&gt;
To show full file names:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  &amp;lt;Directory /&amp;gt;&lt;br /&gt;
    Options Indexes&lt;br /&gt;
    IndexOptions NameWidth=*&lt;br /&gt;
  &amp;lt;/Directory&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sample:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;Directory &amp;quot;/www&amp;quot;&amp;gt;&lt;br /&gt;
    Options Indexes FollowSymLinks&lt;br /&gt;
    IndexOptions FancyIndexing NameWidth=*&lt;br /&gt;
    AllowOverride None&lt;br /&gt;
    Require all granted&lt;br /&gt;
&amp;lt;/Directory&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Hide Apache and PHP Banner ==&lt;br /&gt;
&lt;br /&gt;
Hide PHP version (X-Powered-By) - Edit php.ini: [http://www.ducea.com/2006/06/16/apache-tips-tricks-hide-php-version-x-powered-by/]&lt;br /&gt;
 expose_php = Off&lt;br /&gt;
&lt;br /&gt;
Hide Apache version: [http://www.itsolutionskb.com/2008/10/hide-apache-information/]&lt;br /&gt;
 # ServerSignature On&lt;br /&gt;
 ServerSignature Off&lt;br /&gt;
 &lt;br /&gt;
 # ServerTokens Full&lt;br /&gt;
 ServerTokens Prod&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* Hide Apache ServerSignature/ServerTokens/PHP X-Powered-By - http://www.if-not-true-then-false.com/2009/howto-hide-and-modify-apache-server-information-serversignature-and-servertokens-and-hide-php-version-x-powered-by/&lt;br /&gt;
&lt;br /&gt;
== .htaccess ==&lt;br /&gt;
&lt;br /&gt;
Override configuration settings on a per directory (and sub directories) level with:&lt;br /&gt;
 .htaccess&lt;br /&gt;
&lt;br /&gt;
Allow override of all configuration options:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;Directory /var/www/html&amp;gt;&lt;br /&gt;
  AllowOverride All&lt;br /&gt;
&amp;lt;/Directory&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example directory browsing in .htaccess:&lt;br /&gt;
 Options +indexes&lt;br /&gt;
&lt;br /&gt;
Redirect to index.php:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RewriteEngine on&lt;br /&gt;
RewriteCond %{REQUEST_FILENAME} !-f&lt;br /&gt;
RewriteCond %{REQUEST_FILENAME} !-d&lt;br /&gt;
RewriteRule ^(.*)$ /index.php?path=$1 [NC,L,QSA]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 a2enmod rewrite&lt;br /&gt;
 #a2enmod proxy_http&lt;br /&gt;
&lt;br /&gt;
== Allow from networks ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;Directory &amp;quot;...&amp;quot;&amp;gt;&lt;br /&gt;
    Order Deny,Allow&lt;br /&gt;
    Deny from all&lt;br /&gt;
    Allow from 127.0.0.0/255.255.255.0  10.10.0.0/16&lt;br /&gt;
&amp;lt;/Directory&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Log Files ==&lt;br /&gt;
&lt;br /&gt;
    ErrorLog logs/test.com-error_log&lt;br /&gt;
    CustomLog logs/test.com-access_log common&lt;br /&gt;
&lt;br /&gt;
Make sure the soft link exists:&lt;br /&gt;
 ln -s /var/log/httpd /etc/httpd/logs      # RHEL based&lt;br /&gt;
 ln -s /var/log/apache2 /etc/apache2/logs  # Debian Based&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*[http://httpd.apache.org/docs/2.0/logs.html Log Files v2.0]&lt;br /&gt;
*[http://httpd.apache.org/docs/1.3/logs.html#accesslog Log files v1.3]&lt;br /&gt;
&lt;br /&gt;
===Log HTTPS X-Forwarded-For===&lt;br /&gt;
[http://www.webmasterworld.com/forum92/6134.htm Log the X-Forwarded-For] header in apache...&lt;br /&gt;
 LogFormat &amp;quot;[X-Forwarded-For: %{X-Forwarded-For}i] %h %l %u %t \&amp;quot;%r\&amp;quot; %&amp;gt;s %b \&amp;quot;%{Referer}i\&amp;quot; \&amp;quot;%{User-Agent}i\&amp;quot;&amp;quot; combined&lt;br /&gt;
 LogFormat &amp;quot;[X-Forwarded-For: %{X-Forwarded-For}i] %h %l %u %t \&amp;quot;%r\&amp;quot; %&amp;gt;s %b&amp;quot; common&lt;br /&gt;
 LogFormat &amp;quot;%{Referer}i -&amp;gt; %U&amp;quot; referer&lt;br /&gt;
 LogFormat &amp;quot;%{User-agent}i&amp;quot; agent&lt;br /&gt;
&lt;br /&gt;
== PHP ==&lt;br /&gt;
&lt;br /&gt;
Install PHP with Apache: (Ubuntu)&lt;br /&gt;
 #apt-get install apache2 php5 libapache2-mod-php5&lt;br /&gt;
 apt-get install apache2 php libapache2-mod-php&lt;br /&gt;
&lt;br /&gt;
== Apache SSL ==&lt;br /&gt;
&lt;br /&gt;
Enable SSL with...&lt;br /&gt;
&lt;br /&gt;
Apache can do virtual SSL hosting!&lt;br /&gt;
&lt;br /&gt;
Install mod_ssl: [https://help.ubuntu.com/10.04/serverguide/httpd.html]&lt;br /&gt;
 # redhat / rhel&lt;br /&gt;
 sudo yum install mod_ssl&lt;br /&gt;
&lt;br /&gt;
 # debian / ubuntu&lt;br /&gt;
 sudo a2enmod ssl&lt;br /&gt;
 sudo a2ensite default-ssl&lt;br /&gt;
 systemctl reload apache2&lt;br /&gt;
&lt;br /&gt;
/etc/httpd/conf.d/ssl.conf:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LoadModule ssl_module modules/mod_ssl.so&lt;br /&gt;
Listen 443&lt;br /&gt;
AddType application/x-x509-ca-cert .crt&lt;br /&gt;
AddType application/x-pkcs7-crl    .crl&lt;br /&gt;
SSLPassPhraseDialog  builtin&lt;br /&gt;
SSLSessionCache         shmcb:/var/cache/mod_ssl/scache(512000)&lt;br /&gt;
SSLSessionCacheTimeout  300&lt;br /&gt;
SSLMutex default&lt;br /&gt;
SSLRandomSeed startup file:/dev/urandom  256&lt;br /&gt;
SSLRandomSeed connect builtin&lt;br /&gt;
SSLCryptoDevice builtin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: Delete the default VirtualHost section so we can add our own.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# SSL Configuration - from ssl.conf virtual host example&lt;br /&gt;
SSLEngine On&lt;br /&gt;
SSLProtocol all -SSLv2&lt;br /&gt;
SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM:+LOW&lt;br /&gt;
SSLCertificateFile /etc/pki/tls/certs/localhost.crt&lt;br /&gt;
SSLCertificateKeyFile /etc/pki/tls/private/localhost.key&lt;br /&gt;
&lt;br /&gt;
CustomLog logs/ssl_request_log \&lt;br /&gt;
          &amp;quot;%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \&amp;quot;%r\&amp;quot; %b&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# SSL configuration&lt;br /&gt;
SSLEngine On&lt;br /&gt;
SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL&lt;br /&gt;
SSLCertificateFile /etc/apache2/ssl/cert.crt&lt;br /&gt;
SSLCertificateKeyFile /etc/apache2/ssl/cert.key&lt;br /&gt;
SSLCertificateChainFile /etc/apache2/ssl/sf_bundle.crt&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
NameVirtualHost *:80&lt;br /&gt;
&amp;lt;VirtualHost *:80&amp;gt;&lt;br /&gt;
    ServerName default.t0e.org&lt;br /&gt;
&lt;br /&gt;
    # Redirect HTTP to HTTPS&lt;br /&gt;
    RewriteEngine On&lt;br /&gt;
    RewriteCond %{HTTPS} off&lt;br /&gt;
    RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}&lt;br /&gt;
&amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&lt;br /&gt;
NameVirtualHost *:443&lt;br /&gt;
&amp;lt;VirtualHost *:443&amp;gt;&lt;br /&gt;
    ServerName kb.t0e.org&lt;br /&gt;
&lt;br /&gt;
    # SSL Enabled: (only once in config file)&lt;br /&gt;
    SSLEngine on&lt;br /&gt;
    SSLCertificateFile /etc/t0e.org.pem&lt;br /&gt;
    SSLCertificateKeyFile /etc/t0e.org.pem&lt;br /&gt;
    SSLProtocol all -SSLv2&lt;br /&gt;
    SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM:+LOW&lt;br /&gt;
&lt;br /&gt;
    DocumentRoot /www&lt;br /&gt;
&lt;br /&gt;
    ServerAdmin admin@kb.t0e.org.com&lt;br /&gt;
    ErrorLog logs/kb.t0e.org-error_log&lt;br /&gt;
    CustomLog logs/kb.t0e.org-access_log common&lt;br /&gt;
&amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;VirtualHost *:443&amp;gt;&lt;br /&gt;
    ServerName wiki.t0e.org&lt;br /&gt;
&lt;br /&gt;
    DocumentRoot /www&lt;br /&gt;
&lt;br /&gt;
    ServerAdmin admin@wiki.t0e.org.com&lt;br /&gt;
    ErrorLog logs/wiki.t0e.org-error_log&lt;br /&gt;
    CustomLog logs/wiki.t0e.org-access_log common&lt;br /&gt;
&amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: With SSL, Apache will always use the first default virtual hosts&#039; certificate, so it only makes sense to define it there.&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
*[http://www.apache-ssl.org/ Apache SSL]&lt;br /&gt;
*[http://httpd.apache.org/docs/2.0/ssl/ Apache SSL/TLS Encryption Documentation]&lt;br /&gt;
*[http://httpd.apache.org/docs/2.0/mod/mod_ssl.html mod_ssl]&lt;br /&gt;
*[http://www.securityfocus.com/infocus/1818 Article: Apache 2 with SSL/TLS: Step-by-Step, Part 1]&lt;br /&gt;
*[http://www.vanemery.com/Linux/Apache/apache-SSL.html Van&#039;s Apache SSL/TLS mini-HOWTO]&lt;br /&gt;
*[http://tomcat.apache.org/tomcat-3.3-doc/tomcat-ssl-howto.html Tomcat SSL Configuration]&lt;br /&gt;
*[http://httpd.apache.org/docs/2.0/ssl/ssl_faq.html Apache: SSL/TLS Strong Encryption: FAQ]&lt;br /&gt;
*[http://www.networkworld.com/columnists/2006/011606internet.html Getting SSL to work across virtual hosts in Apache]&lt;br /&gt;
*[http://www.faqs.org/docs/Linux-HOWTO/SSL-RedHat-HOWTO.html Building a Secure RedHat Apache Server HOWTO]&lt;br /&gt;
* CommonMisconfigurations - Httpd Wiki - http://wiki.apache.org/httpd/CommonMisconfigurations&lt;br /&gt;
&lt;br /&gt;
--- chain ---&lt;br /&gt;
&lt;br /&gt;
If you have a chain, create the pem as &amp;quot;key, cert, chain&amp;quot; and set Apache config like so:&lt;br /&gt;
&lt;br /&gt;
    SSLCertificateFile /etc/ssl.pem&lt;br /&gt;
    SSLCertificateKeyFile /etc/ssl.pem&lt;br /&gt;
    SSLCertificateChainFile /etc/ssl.pem&lt;br /&gt;
&lt;br /&gt;
or just&lt;br /&gt;
&lt;br /&gt;
    SSLCertificateFile /etc/ssl.pem&lt;br /&gt;
    SSLCertificateChainFile /etc/ssl.pem&lt;br /&gt;
&lt;br /&gt;
=== Ubuntu SnakeOil Cert ===&lt;br /&gt;
&lt;br /&gt;
Install the snakoil fake cert &amp;lt;ref&amp;gt;https://superuser.com/questions/58149/host-based-snakeoil-certificates-in-ubuntu&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 sudo apt-get install ssl-cert&lt;br /&gt;
&lt;br /&gt;
 sudo make-ssl-cert generate-default-snakeoil --force-overwrite&lt;br /&gt;
&lt;br /&gt;
 /etc/ssl/certs/ssl-cert-snakeoil.pem&lt;br /&gt;
 /etc/ssl/private/ssl-cert-snakeoil.key&lt;br /&gt;
&lt;br /&gt;
== Linux System Password Protection ==&lt;br /&gt;
&lt;br /&gt;
Using system accounts for HTTP authentication - http://wiki.zs64.net/Using_system_accounts_for_HTTP_authentication&lt;br /&gt;
&lt;br /&gt;
  httpd.conf&lt;br /&gt;
&lt;br /&gt;
Edit httpd.conf to add these lines to the general configuration:&lt;br /&gt;
&lt;br /&gt;
LoadModule              auth_external_module    libexec/apache2/mod_auth_external.so&lt;br /&gt;
&lt;br /&gt;
(Should have been added by installing the port already.)&lt;br /&gt;
&lt;br /&gt;
Add these lines to each virtual host where you&#039;d like to use system accounts for authentication:&lt;br /&gt;
&lt;br /&gt;
AddExternalAuth         pwauth  /usr/local/bin/pwauth&lt;br /&gt;
SetExternalAuthMethod   pwauth  pipe&lt;br /&gt;
&lt;br /&gt;
Add these lines to each Directory or Location section that you want protected by authentication:&lt;br /&gt;
&lt;br /&gt;
AuthType        Basic&lt;br /&gt;
AuthExternal    pwauth&lt;br /&gt;
require         valid-user&lt;br /&gt;
&lt;br /&gt;
== Password Protection with .htaccess and htpasswd ==&lt;br /&gt;
&lt;br /&gt;
*[http://www.javascriptkit.com/howto/htaccess3.shtml Comprehensive guide to .htaccess: Password protection]&lt;br /&gt;
*[http://apache-server.com/tutorials/ATusing-htaccess.html Using .htaccess Files with Apache]&lt;br /&gt;
*[http://www.4webhelp.net/tutorials/misc/htaccess.php Password Protection by Rod]&lt;br /&gt;
*[http://www.spoono.com/php/tutorials/tutorial.php?id=30 .htaccess Password Protection in PHP]&lt;br /&gt;
&lt;br /&gt;
Sample .htaccess file:&lt;br /&gt;
&lt;br /&gt;
 AuthUserFile /var/www/htpasswd&lt;br /&gt;
 AuthGroupFile /dev/null&lt;br /&gt;
 AuthName &amp;quot;Secret Place&amp;quot;&lt;br /&gt;
 AuthType Basic&lt;br /&gt;
 Require valid-user&lt;br /&gt;
 &lt;br /&gt;
 #Require user &amp;lt;user&amp;gt;&lt;br /&gt;
 #Require group &amp;lt;group&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
To use with httpd.conf or virtual.conf, wrap in &amp;quot;&amp;lt;Directory&amp;gt;&amp;quot; tags:&lt;br /&gt;
 &amp;lt;Directory /&amp;gt;&lt;br /&gt;
   AuthUserFile ...&lt;br /&gt;
   ...&lt;br /&gt;
 &amp;lt;/Directory&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: if you want in your httpd.conf (or virtual.conf) surround with &amp;quot;&amp;lt;Location /&amp;gt;...&amp;lt;/Location&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
To add password file:&lt;br /&gt;
 htpasswd -c /var/www/htpasswd admin&lt;br /&gt;
 htpasswd /var/www/htpasswd user1&lt;br /&gt;
&lt;br /&gt;
 # if you want to create a blank username with password:&lt;br /&gt;
 htpasswd /path/htpasswd &#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To use .htaccess:&lt;br /&gt;
 &amp;lt;Directory /&amp;gt;&lt;br /&gt;
     Options FollowSymLinks&lt;br /&gt;
     AllowOverride &#039;&#039;&#039;AuthConfig&#039;&#039;&#039;&lt;br /&gt;
 &amp;lt;/Directory&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Or user the [http://www.webmaster-toolkit.com/htaccess-generator.shtml .htaccess generator]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[http://httpd.apache.org/docs/2.2/mod/core.html#require Apache HTTP Server - Require Directive]:&lt;br /&gt;
&lt;br /&gt;
Require user userid [userid] ...&lt;br /&gt;
:Only the named users can access the resource.&lt;br /&gt;
Require group group-name [group-name] ...&lt;br /&gt;
:Only users in the named groups can access the resource.&lt;br /&gt;
Require valid-user&lt;br /&gt;
:All valid users can access the resource. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
AuthType Basic&lt;br /&gt;
AuthName &amp;quot;Restricted Resource&amp;quot;&lt;br /&gt;
AuthUserFile /web/users&lt;br /&gt;
AuthGroupFile /web/groups&lt;br /&gt;
Require group admin &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== web based htpasswd manager ===&lt;br /&gt;
&lt;br /&gt;
see [[change_htpasswd.pl]]&lt;br /&gt;
&lt;br /&gt;
[http://home.xnet.com/~efflandt/pub/htpasswd.pl htpasswd.cgi by David Efflandt]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Perl CGI Script to Modify User Passwords:&lt;br /&gt;
&lt;br /&gt;
This allows users to manage / change their own passwords.&lt;br /&gt;
&lt;br /&gt;
Use the Perl CGI script [http://home.xnet.com/%7Eefflandt/pub/htpasswd.pl htpasswd.pl] [[http://www.yolinux.com/TUTORIALS/src/htpasswd_pl.txt cache]]&lt;br /&gt;
&lt;br /&gt;
* Edit location of Perl .i.e.: /usr/bin/perl&lt;br /&gt;
** Not /usr/local/bin/perl&lt;br /&gt;
* Edit the script to specify location of the password file i.e. /var/www/PasswordDir/.htpasswd&lt;br /&gt;
* SELinux users must add the correct attribute i.e. chcon -R -h -t httpd_sys_content_t /var/www/PasswordDir&lt;br /&gt;
* The password file must be located in a directory where CGI is allowed to modify files.&lt;br /&gt;
&lt;br /&gt;
File: httpd.conf (portion):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
..&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;Directory &amp;quot;/var/www/PasswordDir&amp;quot;&amp;gt;&lt;br /&gt;
    Options -Indexes&lt;br /&gt;
    AllowOverride None&lt;br /&gt;
    Options None&lt;br /&gt;
    Order allow,deny&lt;br /&gt;
    Allow from all&lt;br /&gt;
&amp;lt;/Directory&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
..&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Directory Browsing==&lt;br /&gt;
 DocumentRoot /www/files&lt;br /&gt;
 &amp;lt;Directory /&amp;gt;&lt;br /&gt;
     Options FollowSymLinks &#039;&#039;&#039;+Indexes&#039;&#039;&#039;&lt;br /&gt;
     AllowOverride None&lt;br /&gt;
 &amp;lt;/Directory&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: The &#039;+&#039; may not be needed.&lt;br /&gt;
&lt;br /&gt;
In a .htaccess:&lt;br /&gt;
 Options +indexes&lt;br /&gt;
&lt;br /&gt;
Long file names: [http://www.networkworld.com/article/2311687/software/showing-long-file-names-in-apache-directory-listings.html]&lt;br /&gt;
 IndexOptions NameWidth=*&lt;br /&gt;
&lt;br /&gt;
For root indexes, the welcome.conf may be overriding with the welcome screen.  Make the following change: [http://www.linuxquestions.org/questions/linux-general-1/apache-2-root-directory-listing-201356/]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;LocationMatch &amp;quot;^/$&amp;gt;&lt;br /&gt;
    #Options -Indexes&lt;br /&gt;
    Options Indexes&lt;br /&gt;
    ErrorDocument 403 /error/noindex.html&lt;br /&gt;
&amp;lt;/LocationMatch&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== cgi ==&lt;br /&gt;
&lt;br /&gt;
Script Alias folder:&lt;br /&gt;
 ScriptAlias /cgi-bin/ &amp;quot;C:/Program Files/Apache Group/Apache/cgi-bin/&amp;quot; &lt;br /&gt;
 ScriptAlias /cgi-bin/ &amp;quot;/var/www/cgi-bin/&amp;quot;&lt;br /&gt;
&lt;br /&gt;
My favorite option, make all .cgi files executable: (This will need to be surrounded with &#039;&amp;lt;Location /&amp;gt;&#039; or &#039;&amp;lt;Directory /&amp;gt;&#039; tags)&lt;br /&gt;
 AddHandler cgi-script .cgi &lt;br /&gt;
 Options +ExecCGI &lt;br /&gt;
&lt;br /&gt;
Note: Make sure to &#039;chmod +x&#039; the files.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;VirtualHost *:80&amp;gt;&lt;br /&gt;
    ServerName hg.t0e.org&lt;br /&gt;
&lt;br /&gt;
    DirectoryIndex hgweb.cgi&lt;br /&gt;
    DocumentRoot /www/hg&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;Location /&amp;gt;&lt;br /&gt;
        AddHandler cgi-script .cgi&lt;br /&gt;
        Options +ExecCGI&lt;br /&gt;
    &amp;lt;/Location&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    ServerAdmin admin@hg.t0e.org&lt;br /&gt;
    ErrorLog logs/hg.t0e.org-error_log&lt;br /&gt;
    CustomLog logs/hg.t0e.org-access_log common&lt;br /&gt;
&amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Source: [http://www.thesitewizard.com/archive/addcgitoapache.shtml How to Add CGI Script Support (Perl, Python, etc) to Your Apache Server on Windows (thesitewizard.com)]&lt;br /&gt;
&lt;br /&gt;
--&lt;br /&gt;
&lt;br /&gt;
Only files without an extension:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;VirtualHost *:80&amp;gt;&lt;br /&gt;
    ServerName pi.t0e.org&lt;br /&gt;
    DocumentRoot /www/pi&lt;br /&gt;
    &amp;lt;Directory /&amp;gt;&lt;br /&gt;
        AllowOverride All&lt;br /&gt;
    &amp;lt;/Directory&amp;gt;&lt;br /&gt;
    DirectoryIndex index index.php index.html index.htm&lt;br /&gt;
    &amp;lt;Files ~ &amp;quot;^[a-zA-Z]*$&amp;quot;&amp;gt;&lt;br /&gt;
        SetHandler cgi-script&lt;br /&gt;
        Options +ExecCGI&lt;br /&gt;
    &amp;lt;/Files&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
=== CentOS Default ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#&lt;br /&gt;
# ScriptAliases are essentially the same as Aliases, except that&lt;br /&gt;
# documents in the realname directory are treated as applications and&lt;br /&gt;
# run by the server when requested rather than as documents sent to the client.&lt;br /&gt;
# The same rules about trailing &amp;quot;/&amp;quot; apply to ScriptAlias directives as to&lt;br /&gt;
# Alias.&lt;br /&gt;
#&lt;br /&gt;
ScriptAlias /cgi-bin/ &amp;quot;/var/www/cgi-bin/&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
# &amp;quot;/var/www/cgi-bin&amp;quot; should be changed to whatever your ScriptAliased&lt;br /&gt;
# CGI directory exists, if you have that configured.&lt;br /&gt;
#&lt;br /&gt;
&amp;lt;Directory &amp;quot;/var/www/cgi-bin&amp;quot;&amp;gt;&lt;br /&gt;
    AllowOverride None&lt;br /&gt;
    Options None&lt;br /&gt;
    Order allow,deny&lt;br /&gt;
    Allow from all&lt;br /&gt;
&amp;lt;/Directory&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Python CGI ==&lt;br /&gt;
&lt;br /&gt;
See [[Python#Apache_CGI]]&lt;br /&gt;
&lt;br /&gt;
==mod_proxy==&lt;br /&gt;
*http://www.apachetutor.org/admin/reverseproxies&lt;br /&gt;
*http://www.linuxfocus.org/English/March2000/article147.html&lt;br /&gt;
*http://www.linuxhelp.net/guides/apacheproxy/&lt;br /&gt;
*http://webauth.stanford.edu/manual/mod/mod_proxy.html&lt;br /&gt;
*http://www.apachetutor.org/admin/reverseproxies&lt;br /&gt;
*http://confluence.atlassian.com/display/DOC/Using+Apache+with+mod_proxy&lt;br /&gt;
*http://www.serverwatch.com/tutorials/article.php/3290851&lt;br /&gt;
*http://apache.webthing.com/mod_proxy_html/&lt;br /&gt;
*http://www.ibm.com/developerworks/linux/library/wa-lampsec/index.html&lt;br /&gt;
&lt;br /&gt;
== prefork vs worker ==&lt;br /&gt;
&lt;br /&gt;
Prefork performs better.  Worker uses less memory.  Prefork is most commonly used, and is the better choice for a web server.&lt;br /&gt;
&lt;br /&gt;
To see which is compiled, and look for prefork.c or worker.c:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# httpd -l&lt;br /&gt;
 &lt;br /&gt;
Compiled in modules:&lt;br /&gt;
  core.c&lt;br /&gt;
  prefork.c&lt;br /&gt;
  http_core.c&lt;br /&gt;
  mod_so.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Statistics ==&lt;br /&gt;
&lt;br /&gt;
=== Connections ===&lt;br /&gt;
&lt;br /&gt;
Count active connections:&lt;br /&gt;
 netstat -ant | grep ESTABLISHED | grep :80 | wc -l&lt;br /&gt;
&lt;br /&gt;
From PHP:&lt;br /&gt;
 &amp;lt;?php&lt;br /&gt;
 $number_of_users = shell_exec(&#039;netstat -ant | grep ESTABLISHED | grep :80 | wc -l&#039;);&lt;br /&gt;
 echo $number_of_users;&lt;br /&gt;
 ?&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* [http://www.experts-exchange.com/OS/Linux/Q_22825240.html Find out how many connections are on an apache server : apache, connections, many, find, server]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== [http://httpd.apache.org/docs/2.0/mod/mod_status.html mod_status] ===&lt;br /&gt;
&lt;br /&gt;
[http://httpd.apache.org/docs/2.0/mod/mod_status.html mod_status - Apache HTTP Server]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Summary&lt;br /&gt;
&lt;br /&gt;
The Status module allows a server administrator to find out how well their server is performing. A HTML page is presented that gives the current server statistics in an easily readable form. If required this page can be made to automatically refresh (given a compatible browser). Another page gives a simple machine-readable list of the current server state.&lt;br /&gt;
&lt;br /&gt;
The details given are:&lt;br /&gt;
&lt;br /&gt;
* The number of worker serving requests&lt;br /&gt;
* The number of idle worker&lt;br /&gt;
* The status of each worker, the number of requests that worker has performed and the total number of bytes served by the worker (*)&lt;br /&gt;
* A total number of accesses and byte count served (*)&lt;br /&gt;
* The time the server was started/restarted and the time it has been running for&lt;br /&gt;
* Averages giving the number of requests per second, the number of bytes served per second and the average number of bytes per request (*)&lt;br /&gt;
* The current percentage CPU used by each worker and in total by Apache (*)&lt;br /&gt;
* The current hosts and requests being processed (*)&lt;br /&gt;
&lt;br /&gt;
The lines marked &amp;quot;(*)&amp;quot; are only available if ExtendedStatus is On.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LoadModule status_module modules/mod_status.so&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
# ExtendedStatus controls whether Apache will generate &amp;quot;full&amp;quot; status&lt;br /&gt;
# information (ExtendedStatus On) or just basic information (ExtendedStatus&lt;br /&gt;
# Off) when the &amp;quot;server-status&amp;quot; handler is called. The default is Off.&lt;br /&gt;
#&lt;br /&gt;
#ExtendedStatus On&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
# Allow server status reports generated by mod_status,&lt;br /&gt;
# with the URL of http://servername/server-status&lt;br /&gt;
# Change the &amp;quot;.example.com&amp;quot; to match your domain to enable.&lt;br /&gt;
#&lt;br /&gt;
#&amp;lt;Location /server-status&amp;gt;&lt;br /&gt;
#    SetHandler server-status&lt;br /&gt;
#    Order deny,allow&lt;br /&gt;
#    Deny from all&lt;br /&gt;
#    Allow from .example.com&lt;br /&gt;
#&amp;lt;/Location&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* [http://httpd.apache.org/docs/2.0/mod/mod_status.html mod_status - Apache HTTP Server]&lt;br /&gt;
* [http://www.experts-exchange.com/OS/Linux/Q_22825240.html Find out how many connections are on an apache server : apache, connections, many, find, server]&lt;br /&gt;
&lt;br /&gt;
== TRACE and TRACK ==&lt;br /&gt;
&lt;br /&gt;
ISO Audit may result in this &amp;quot;Medium&amp;quot; risk detected:&lt;br /&gt;
&lt;br /&gt;
:&amp;quot;HTTP Methods Allowed.  It is observed that HTTP methods GET HEAD TRACE OPTIONS are allowed on this host.  Disable all unnecessary methods.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
:&amp;quot;HTTP TRACE / TRACK Methods Allowed.  The remote webserver supports the TRACE and/or TRACK methods.  TRACE and TRACK are HTTP methods that are used to debug web server connections.  Disable these methods.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Disabling TRACE ===&lt;br /&gt;
&lt;br /&gt;
[http://rackerhacker.com/2007/08/28/apache-disable-trace-and-track-methods/ Apache: Disable TRACE and TRACK methods | Racker Hacker]:&lt;br /&gt;
&lt;br /&gt;
Lots of PCI Compliance and vulnerability scan vendors will complain about TRACE and TRACK methods being enabled on your server. Since most providers run Nessus, you&#039;ll see this fairly often. Here&#039;s the rewrite rules to add:&lt;br /&gt;
&lt;br /&gt;
 RewriteEngine on&lt;br /&gt;
 RewriteCond %{REQUEST_METHOD} ^(TRACE|TRACK)&lt;br /&gt;
 RewriteRule .* - [F]&lt;br /&gt;
&lt;br /&gt;
These directives will need to be added to each VirtualHost.&lt;br /&gt;
&lt;br /&gt;
For apache version 1.3.34 (or later 1.3.x versions), or apache 2.0.55 (or later), this has been made easy. Just add the line TraceEnable off&lt;br /&gt;
&lt;br /&gt;
 TraceEnable off&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[http://publib.boulder.ibm.com/httpserv/ihsdiag/http_trace.html Disabling the HTTP TRACE method]:&lt;br /&gt;
&lt;br /&gt;
The HTTP TRACE request method causes the data received by IBM HTTP Server from the client to be sent back to the client, as in the following example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ telnet 127.0.0.1 8080&lt;br /&gt;
Trying...&lt;br /&gt;
Connected to 127.0.0.1.&lt;br /&gt;
Escape character is &#039;^]&#039;.&lt;br /&gt;
TRACE / HTTP/1.0&lt;br /&gt;
Host: foo&lt;br /&gt;
A: b&lt;br /&gt;
C: d&lt;br /&gt;
&lt;br /&gt;
HTTP/1.1 200 OK&lt;br /&gt;
Date: Mon, 04 Oct 2004 14:07:59 GMT&lt;br /&gt;
Server: IBM_HTTP_SERVER&lt;br /&gt;
Connection: close&lt;br /&gt;
Content-Type: message/http&lt;br /&gt;
&lt;br /&gt;
TRACE / HTTP/1.0&lt;br /&gt;
A: b&lt;br /&gt;
C: d&lt;br /&gt;
Host: foo&lt;br /&gt;
&lt;br /&gt;
Connection closed.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The TRACE capability could be used by vulnerable or malicious applications to trick a web browser into issuing a TRACE request against an arbitrary site and then send the response to the TRACE to a third party using web browser features.&lt;br /&gt;
&lt;br /&gt;
Making the required configuration changes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;VirtualHost www.example.com&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
# disable TRACE in the www.example.com virtual host&lt;br /&gt;
RewriteEngine On &lt;br /&gt;
RewriteCond %{REQUEST_METHOD} ^TRACE &lt;br /&gt;
RewriteRule .* - [F] &lt;br /&gt;
&amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Using SSL:&lt;br /&gt;
 $ /usr/linux/bin/openssl s_client -connect 127.0.0.1:8444&lt;br /&gt;
&lt;br /&gt;
For more information...&lt;br /&gt;
&lt;br /&gt;
More background information on the concerns with TRACE is provided at http://www.apacheweek.com/issues/03-01-24#news.&lt;br /&gt;
&lt;br /&gt;
Other:&lt;br /&gt;
* Apache Tips: Disable the HTTP TRACE method | MDLog:/sysadmin - http://www.ducea.com/2007/10/22/apache-tips-disable-the-http-trace-method/&lt;br /&gt;
&lt;br /&gt;
=== TraceEnable ===&lt;br /&gt;
&lt;br /&gt;
Apache Core Features - http://httpd.apache.org/docs/1.3/mod/core.html#traceenable&lt;br /&gt;
&lt;br /&gt;
TraceEnable:&lt;br /&gt;
 Syntax: TraceEnable [on|off|extended]&lt;br /&gt;
 Default: TraceEnable on&lt;br /&gt;
 Context: server config&lt;br /&gt;
 Status: core (Windows, NetWare)&lt;br /&gt;
 Compatibility: Available only in Apache 1.3.34, 2.0.55 and later&lt;br /&gt;
&lt;br /&gt;
This directive overrides the behavior of TRACE for both the core server and mod_proxy. The default TraceEnable on permits TRACE requests per RFC 2616, which disallows any request body to accompany the request. TraceEnable off causes the core server and mod_proxy to return a 405 FORBIDDEN error to the client.&lt;br /&gt;
&lt;br /&gt;
Finally, for testing and diagnostic purposes only, request bodies may be allowed using the non-compliant TraceEnable extended directive. The core (as an origin server) will restrict the request body to 64k (plus 8k for chunk headers if Transfer-Encoding: chunked is used). The core will reflect the full headers and all chunk headers with the request body. As a proxy server, the request body is not restricted to 64k. At this time the Apache 1.3 mod_proxy does not permit chunked request bodies for any request, including the extended TRACE request.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Disabling TRACK ===&lt;br /&gt;
&lt;br /&gt;
The HTTP TRACK method&lt;br /&gt;
&lt;br /&gt;
The TRACK method is a type of request supported by Microsoft web servers. It is not RFC compliant and is not supported directly by IBM HTTP Server. The method may be utilized as part of a cross-site scripting attack. See Vulnerability Note VU#288308 for more information.&lt;br /&gt;
&lt;br /&gt;
Even though IBM HTTP Server does not support the TRACK method natively, it is possible for plug-in modules to provide support for it. To disable this capability for plug-in modules, in addition to disabling the TRACE method, add these two additional directives after the existing RewriteCond and RewriteRule directives which are used to disable TRACE:&lt;br /&gt;
&lt;br /&gt;
RewriteCond %{REQUEST_METHOD} ^TRACK&lt;br /&gt;
RewriteRule .* - [F]&lt;br /&gt;
&lt;br /&gt;
Here is a full example showing the directives to disable both TRACE and TRACK:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;VirtualHost www.example.com&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
# disable TRACE and TRACK in the www.example.com virtual host&lt;br /&gt;
RewriteEngine On &lt;br /&gt;
RewriteCond %{REQUEST_METHOD} ^TRACE &lt;br /&gt;
RewriteRule .* - [F] &lt;br /&gt;
RewriteCond %{REQUEST_METHOD} ^TRACK&lt;br /&gt;
RewriteRule .* - [F] &lt;br /&gt;
&amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Attack ===&lt;br /&gt;
&lt;br /&gt;
Cross-Site Tracing issues&lt;br /&gt;
&lt;br /&gt;
Earlier this week a paper was published, [http://www.cgisecurity.com/whitehat-mirror/WH-WhitePaper_XST_ebook.pdf &amp;quot;Cross-Site Tracing&amp;quot;] which gave details of how the TRACE HTTP request could be used in Cross-Site Scripting attacks. Unfortunately this issue has not been very well understood by the media and has received a unwarranted amount of attention.&lt;br /&gt;
&lt;br /&gt;
When an HTTP TRACE request is sent to a web server that supports it, that server will respond echoing the data that is passed to it, including any HTTP headers. The paper explains that some browsers can be scripted to perform a TRACE request. A browser with this functionality could be made to issue a TRACE request against an arbitrary site and pass the results on elsewhere. Since browsers will only send authentication details and cookies to the sites that issue them this means a user having a browser with this functionality could be tricked into sending their cookies or authentication details for arbitrary sites to an attacker.&lt;br /&gt;
&lt;br /&gt;
For example, if you visited a page that an attacker has carefully crafted, the page could cause your browser to bounce a TRACE request against some site for which you have authentication cookies. The result of the TRACE will be a copy of what was sent to the site, which will therefore include those cookies or authentication data. The carefully crafted page can then pass that information on to the attacker.&lt;br /&gt;
&lt;br /&gt;
TRACE requests can be disabled by making a change to the Apache server configuration. Unfortunately it is not possible to do this using the Limit directive since the processing for the TRACE request skips this authorisation checking. Instead the following lines can be added which make use of the mod_rewrite module.&lt;br /&gt;
&lt;br /&gt;
    RewriteEngine On &lt;br /&gt;
    RewriteCond %{REQUEST_METHOD} ^TRACE &lt;br /&gt;
    RewriteRule .* - [F] &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Although the particular attack highlighted made use of the TRACE functionality to grab authentication details, this isn&#039;t a vulnerability in TRACE, or in the Apache web server.&#039;&#039;&#039; The same browser functionality that permits the published attack can be used for different attacks even if TRACE is disabled on the remote web server. For example an attacker could create a carefully crafted page that when visited submits a hidden request to some arbitrary site through your browser, grabs the result and passes it to the attacker.&lt;br /&gt;
&lt;br /&gt;
== Performance Tuning ==&lt;br /&gt;
&lt;br /&gt;
See [[Linux Performance Tuning]]&lt;br /&gt;
&lt;br /&gt;
[http://www.linuxjournal.com/article/6041 Apache and Firewall Performance Tips from the Xenu.net Masters]&lt;br /&gt;
&lt;br /&gt;
=== CentOS January 2009 Thread ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
-------- Original Message --------&lt;br /&gt;
Subject: 	[CentOS] Apache Server Tuning for Performance&lt;br /&gt;
Date: 	Wed, 21 Jan 2009 00:09:38 +0530&lt;br /&gt;
From: 	linux-crazy &amp;lt;hicheerup@gmail.com&amp;gt;&lt;br /&gt;
Reply-To: 	CentOS mailing list &amp;lt;centos@centos.org&amp;gt;&lt;br /&gt;
To: 	CentOS mailing list &amp;lt;centos@centos.org&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Hi all,&lt;br /&gt;
&lt;br /&gt;
I am facing  facing performance issues with our web servers which is&lt;br /&gt;
working for concurrent  250 requests properly and then stops&lt;br /&gt;
responding when the requests are more than 250 .&lt;br /&gt;
&lt;br /&gt;
The current configuration parameters are as follows :&lt;br /&gt;
&lt;br /&gt;
apachectl -version&lt;br /&gt;
Server version: Apache/2.0.52&lt;br /&gt;
Server built:   Jan 30 2007 09:56:16&lt;br /&gt;
&lt;br /&gt;
Kernel : 2.6.9-55.ELsmp #1 SMP Fri Apr 20 16:36:54 EDT 2007 x86_64&lt;br /&gt;
x86_64 x86_64 GNU/Linux&lt;br /&gt;
&lt;br /&gt;
Server Hardware :&lt;br /&gt;
MAIN MEMORY&lt;br /&gt;
(i) Memory Size 4 GB  Dual-Core Intel 5160 processors.&lt;br /&gt;
&lt;br /&gt;
httpd.conf&lt;br /&gt;
&lt;br /&gt;
Timeout 300&lt;br /&gt;
KeepAlive On&lt;br /&gt;
MaxKeepAliveRequests 1000&lt;br /&gt;
KeepAliveTimeout 150&lt;br /&gt;
&lt;br /&gt;
## Server-Pool Size Regulation (MPM specific)&lt;br /&gt;
# prefork MPM&lt;br /&gt;
&lt;br /&gt;
# StartServers: number of server processes to start&lt;br /&gt;
# MinSpareServers: minimum number of server processes which are kept spare&lt;br /&gt;
# MaxSpareServers: maximum number of server processes which are kept spare&lt;br /&gt;
# ServerLimit: maximum value for MaxClients for the lifetime of the server&lt;br /&gt;
# MaxClients: maximum number of server processes allowed to start&lt;br /&gt;
# MaxRequestsPerChild: maximum number of requests a server process serves&lt;br /&gt;
&lt;br /&gt;
&amp;lt;IfModule prefork.c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
StartServers       8&lt;br /&gt;
MinSpareServers    5&lt;br /&gt;
MaxSpareServers   20&lt;br /&gt;
ServerLimit      251&lt;br /&gt;
MaxClients       251&lt;br /&gt;
MaxRequestsPerChild  4000&lt;br /&gt;
&amp;lt;/IfModule&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# worker MPM&lt;br /&gt;
# StartServers: initial number of server processes to start&lt;br /&gt;
# MaxClients: maximum number of simultaneous client connections&lt;br /&gt;
# MinSpareThreads: minimum number of worker threads which are kept spare&lt;br /&gt;
# MaxSpareThreads: maximum number of worker threads which are kept spare&lt;br /&gt;
# ThreadsPerChild: constant number of worker threads in each server process&lt;br /&gt;
# MaxRequestsPerChild: maximum number of requests a server process serves&lt;br /&gt;
&amp;lt;IfModule worker.c&amp;gt;&lt;br /&gt;
StartServers         2&lt;br /&gt;
MaxClients        150&lt;br /&gt;
MinSpareThreads     25&lt;br /&gt;
MaxSpareThreads     75&lt;br /&gt;
ThreadsPerChild     25&lt;br /&gt;
MaxRequestsPerChild  0&lt;br /&gt;
&amp;lt;/IfModule&amp;gt;&lt;br /&gt;
&lt;br /&gt;
     I want to  know about  the difference  between worker MPM and&lt;br /&gt;
Prefork MPM , how to find out which one will be used by my apache&lt;br /&gt;
server and  the recommended one   for highly loaded server.If some one&lt;br /&gt;
provide me the link that best explains above two comparison also  be&lt;br /&gt;
very use full.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 Can any one guide me tuning to be  done for the maximum utilization&lt;br /&gt;
of the Resources  and better performance of the Servers.&lt;br /&gt;
&lt;br /&gt;
 Regards,&lt;br /&gt;
lingu&lt;br /&gt;
_______________________________________________&lt;br /&gt;
CentOS mailing list&lt;br /&gt;
CentOS@centos.org&lt;br /&gt;
http://lists.centos.org/mailman/listinfo/centos&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Only use prefork MPM (worker is for Win32, AFAIK).&lt;br /&gt;
&lt;br /&gt;
If you set ServerLimit to 251, that&#039;s the limit.&lt;br /&gt;
Set ServerLimit and MaxClients to the same value.&lt;br /&gt;
(Larger than 250)&lt;br /&gt;
OK?&lt;br /&gt;
And take a couple of minutes to study the apache documentation. It&#039;s  &lt;br /&gt;
actually quite good and tranlated into many languages...&lt;br /&gt;
&lt;br /&gt;
BUT: what your server is being able to handle also depends on what you  &lt;br /&gt;
actually serve (PHP/JSP/Servelets/Perl/whatever!&lt;br /&gt;
&lt;br /&gt;
This is usually not a problem that is easily described and solved in  &lt;br /&gt;
two sentences.&lt;br /&gt;
&lt;br /&gt;
Rainer&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Increase your MaxClients configuration, also enable if you&lt;br /&gt;
haven&#039;t already the server-status module and monitor the&lt;br /&gt;
server via http://&amp;lt;your server name&amp;gt;/server-status it will&lt;br /&gt;
show how many workers are busy and what they are doing.&lt;br /&gt;
&lt;br /&gt;
As for which to use, prefork is the old forked method of&lt;br /&gt;
doing things, the other uses threads. Depending on what kind&lt;br /&gt;
of application your running on top of apache, if it is not&lt;br /&gt;
thread safe(at some point many PHP modules were not thread&lt;br /&gt;
safe), you may want to use prefork. Otherwise you can use&lt;br /&gt;
the threading model.&lt;br /&gt;
&lt;br /&gt;
If your not sure I&#039;d say stick to prefork to be safe until&lt;br /&gt;
you can determine for sure that threading is safe.&lt;br /&gt;
&lt;br /&gt;
nate&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Most list members would likely advise sticking with the prefork &lt;br /&gt;
configuration.  Without knowing what kind of applications you are &lt;br /&gt;
running on your webserver, I wouldn&#039;t suggest changing it.&lt;br /&gt;
&lt;br /&gt;
Merely increasing the number of workers might make performance worse.&lt;br /&gt;
&lt;br /&gt;
Use ps or top to figure out how much each apache worker is using. Then &lt;br /&gt;
decide how much ram you want to dedicate on your server to Apache, &lt;br /&gt;
without going into swap. (Over-allocating and then paging out memory &lt;br /&gt;
will only make performance much worse.) For example, if I have 2G or &lt;br /&gt;
ram, and I want 1.5 for apache workers, my average apache worker size &lt;br /&gt;
(resident memory) is 65MB, then I have room for 23 workers. (1024 * 1.5 &lt;br /&gt;
) / 65. (There are more accurate ways to calculate this usage, like &lt;br /&gt;
taking shared memory into account.)&lt;br /&gt;
&lt;br /&gt;
Upgrading the ram in your web server is a pretty fast interim solution.&lt;br /&gt;
&lt;br /&gt;
Consider your application performance, too. The longer a request in your &lt;br /&gt;
application takes, the more workers are in use on your web server, &lt;br /&gt;
taking up more memory. If you have long-running queries in your &lt;br /&gt;
database, take care of those first.&lt;br /&gt;
&lt;br /&gt;
Good luck&lt;br /&gt;
&lt;br /&gt;
Jed&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Jed Reynolds wrote:&lt;br /&gt;
&amp;gt; &lt;br /&gt;
&amp;gt; Merely increasing the number of workers might make performance worse.&lt;br /&gt;
&amp;gt; &lt;br /&gt;
&amp;gt; Use ps or top to figure out how much each apache worker is using. Then &lt;br /&gt;
&amp;gt; decide how much ram you want to dedicate on your server to Apache, &lt;br /&gt;
&amp;gt; without going into swap. (Over-allocating and then paging out memory &lt;br /&gt;
&amp;gt; will only make performance much worse.)  For example, if I have 2G or&lt;br /&gt;
&amp;gt; ram, and I want 1.5 for apache workers, my average apache worker size &lt;br /&gt;
&amp;gt; (resident memory) is 65MB, then I have room for 23 workers. (1024 * 1.5 &lt;br /&gt;
&amp;gt; ) / 65. (There are more accurate ways to calculate this usage, like &lt;br /&gt;
&amp;gt; taking shared memory into account.)&lt;br /&gt;
&lt;br /&gt;
Pay attention to shared memory when doing this.  A freshly-forked &lt;br /&gt;
process shares virtually all RAM with its parent.  How much and how &lt;br /&gt;
quickly this changes varies wildly with the application type and &lt;br /&gt;
activity that causes the child&#039;s data to become unique.  With some types &lt;br /&gt;
of applications (especially mod_perl) you may want to tune down the &lt;br /&gt;
number of hits each child services to increase memory sharing.  Also, if &lt;br /&gt;
you are running external cgi programs you must take them into account.&lt;br /&gt;
&lt;br /&gt;
&amp;gt; Upgrading the ram in your web server is a pretty fast interim solution.&lt;br /&gt;
&amp;gt; &lt;br /&gt;
&amp;gt; Consider your application performance, too. The longer a request in your &lt;br /&gt;
&amp;gt; application takes, the more workers are in use on your web server, &lt;br /&gt;
&amp;gt; taking up more memory. If you have long-running queries in your &lt;br /&gt;
&amp;gt; database, take care of those first.&lt;br /&gt;
&lt;br /&gt;
You may also have to turn off or tune down the HTTP 1.1 connection &lt;br /&gt;
keepalives, trading the time it takes to establish a new connection for &lt;br /&gt;
the RAM it takes to keep the associated process waiting for another &lt;br /&gt;
request from the same client.&lt;br /&gt;
&lt;br /&gt;
-- &lt;br /&gt;
   Les Mikesell&lt;br /&gt;
    lesmikesell@gmail.com&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Also take a look at apache alternatives like lighttpd and nginx. In certain&lt;br /&gt;
cases they do miracles.&lt;br /&gt;
&lt;br /&gt;
Jure Pečar&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
I don&#039;t know about lighttpd (our results were mixed) - but NGINX is  &lt;br /&gt;
really _very_ fast.&lt;br /&gt;
Last time I checked, it seems to be the fastest way to accelerate  &lt;br /&gt;
webpage-delivery on generic hardware and with OSS-software.&lt;br /&gt;
&lt;br /&gt;
But it&#039;s not a feature-monster like apache, so you still need that.&lt;br /&gt;
&lt;br /&gt;
Rainer&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Linux-crazy wrote on Wed, 21 Jan 2009 00:09:38 +0530:&lt;br /&gt;
&lt;br /&gt;
&amp;gt; KeepAliveTimeout 150&lt;br /&gt;
&lt;br /&gt;
My god, reduce this to 10 or 5.&lt;br /&gt;
&lt;br /&gt;
&amp;gt; ServerLimit      251&lt;br /&gt;
&amp;gt; MaxClients       251&lt;br /&gt;
&lt;br /&gt;
There&#039;s your limit. However, you should check with your hardware if upping &lt;br /&gt;
it is really desirable. With 4 GB I think you won&#039;t be able to handle much &lt;br /&gt;
more anyway.&lt;br /&gt;
&lt;br /&gt;
Kai&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Kai Schaetzl wrote:&lt;br /&gt;
&amp;gt; There&#039;s your limit. However, you should check with your hardware if upping &lt;br /&gt;
&amp;gt; it is really desirable. With 4 GB I think you won&#039;t be able to handle much &lt;br /&gt;
&amp;gt; more anyway.&lt;br /&gt;
&lt;br /&gt;
That really depends. If you only shove out static pages and have one or&lt;br /&gt;
two or three odd cgis on the machine, you can flatten down the httpd&lt;br /&gt;
binary quite a bit by throwing out unneeded modules.&lt;br /&gt;
&lt;br /&gt;
500 to 750 clients shouldn&#039;t be that much of a problem then ...&lt;br /&gt;
&lt;br /&gt;
Cheers,&lt;br /&gt;
&lt;br /&gt;
Ralph&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Ralph Angenendt wrote on Wed, 21 Jan 2009 10:52:59 +0100:&lt;br /&gt;
&lt;br /&gt;
&amp;gt; That really depends. If you only shove out static pages and have one or&lt;br /&gt;
&amp;gt; two or three odd cgis on the machine, you can flatten down the httpd&lt;br /&gt;
&amp;gt; binary quite a bit by throwing out unneeded modules.&lt;br /&gt;
&amp;gt; &lt;br /&gt;
&amp;gt; 500 to 750 clients shouldn&#039;t be that much of a problem then ...&lt;br /&gt;
&lt;br /&gt;
Sure it depends ;-) I do serve dynamic pages but by removing the really &lt;br /&gt;
unnecessary modules I made my httpds much faster (especially on pipelined &lt;br /&gt;
image downloads) and they only have some 10 MB (RES) per worker.&lt;br /&gt;
&lt;br /&gt;
But I would expect that they are running the default set of modules.&lt;br /&gt;
&lt;br /&gt;
Kai&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Kai Schaetzl schrieb:&lt;br /&gt;
&amp;gt; Ralph Angenendt wrote on Wed, 21 Jan 2009 10:52:59 +0100:&lt;br /&gt;
&amp;gt;&lt;br /&gt;
&amp;gt;   &lt;br /&gt;
&amp;gt;&amp;gt; That really depends. If you only shove out static pages and have one or&lt;br /&gt;
&amp;gt;&amp;gt; two or three odd cgis on the machine, you can flatten down the httpd&lt;br /&gt;
&amp;gt;&amp;gt; binary quite a bit by throwing out unneeded modules.&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt; 500 to 750 clients shouldn&#039;t be that much of a problem then ...&lt;br /&gt;
&amp;gt;&amp;gt;     &lt;br /&gt;
&amp;gt;&lt;br /&gt;
&amp;gt; Sure it depends ;-) I do serve dynamic pages but by removing the really &lt;br /&gt;
&amp;gt; unnecessary modules I made my httpds much faster (especially on pipelined &lt;br /&gt;
&amp;gt; image downloads) and they only have some 10 MB (RES) per worker.&lt;br /&gt;
&amp;gt;&lt;br /&gt;
&amp;gt; But I would expect that they are running the default set of modules.&lt;br /&gt;
&amp;gt;&lt;br /&gt;
&amp;gt; Kai&lt;br /&gt;
&amp;gt;&lt;br /&gt;
&amp;gt;   &lt;br /&gt;
&lt;br /&gt;
If you can separate-out the images to a specific URL (img.domain.com)&lt;br /&gt;
and put them all in the same directory, you can use NGINX to serve them.&lt;br /&gt;
Of course, the actual transfer-speed will not increase much - but&lt;br /&gt;
latency will go down to the absolute minimum.&lt;br /&gt;
And latency is what makes a page appear &amp;quot;fast&amp;quot; or &amp;quot;slow&amp;quot; to customers.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Ralph Angenendt wrote:&lt;br /&gt;
&amp;gt; Kai Schaetzl wrote:&lt;br /&gt;
&amp;gt;&amp;gt; There&#039;s your limit. However, you should check with your hardware if upping&lt;br /&gt;
&amp;gt;&amp;gt; it is really desirable. With 4 GB I think you won&#039;t be able to handle much&lt;br /&gt;
&amp;gt;&amp;gt; more anyway.&lt;br /&gt;
&amp;gt;&lt;br /&gt;
&amp;gt; That really depends. If you only shove out static pages and have one or&lt;br /&gt;
&amp;gt; two or three odd cgis on the machine, you can flatten down the httpd&lt;br /&gt;
&amp;gt; binary quite a bit by throwing out unneeded modules.&lt;br /&gt;
&amp;gt;&lt;br /&gt;
&amp;gt; 500 to 750 clients shouldn&#039;t be that much of a problem then ...&lt;br /&gt;
&lt;br /&gt;
Yeah gotta monitor it.. just checked in on some servers I ran at&lt;br /&gt;
my last company and the front end proxies (99% mod_proxy) seem to&lt;br /&gt;
peak out traffic wise at about 230 workers. For no other reason other&lt;br /&gt;
than because I could each proxy has 8 apache instances running(4 for&lt;br /&gt;
HTTP 4 for HTTPS). CPU usage peaks at around 3%(dual proc single core),&lt;br /&gt;
memory usage around 800MB. About 100 idle workers. Keepalive was set&lt;br /&gt;
to 300 seconds due to poor application design.&lt;br /&gt;
&lt;br /&gt;
One set of back end apache servers peaks traffic wise at around 100&lt;br /&gt;
active workers, though memory usage was higher, around 2GB because&lt;br /&gt;
of mod_fcgid running ruby on rails. CPU usage seems to be at around&lt;br /&gt;
25%(dual proc quad core) for that one application.&lt;br /&gt;
&lt;br /&gt;
Each back end application had it&#039;s own dedicated apache instance(11&lt;br /&gt;
apps) for maximum stability/best performance monitoring. The bulk&lt;br /&gt;
of them ran on the same physical hardware though.&lt;br /&gt;
&lt;br /&gt;
Traffic routing was handled by a combination of F5 load balancers&lt;br /&gt;
and the apache servers previously mentioned(F5 iRules were too slow&lt;br /&gt;
and F5&#039;s TMM was not scalable at the time).&lt;br /&gt;
&lt;br /&gt;
nate&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt; &lt;br /&gt;
&amp;gt; &amp;gt; KeepAliveTimeout 150&lt;br /&gt;
&amp;gt; &lt;br /&gt;
&amp;gt;reduce this to 10 or 5.&lt;br /&gt;
&amp;gt; &lt;br /&gt;
&amp;gt; &lt;br /&gt;
&amp;gt; Kai&lt;br /&gt;
&amp;gt; &lt;br /&gt;
&amp;gt; --&lt;br /&gt;
&amp;gt; Kai Schätzl, Berlin, Germany&lt;br /&gt;
&lt;br /&gt;
Kai,&lt;br /&gt;
&lt;br /&gt;
what do you think about the &amp;quot;general Timeout&lt;br /&gt;
&lt;br /&gt;
it is set to 300&lt;br /&gt;
&lt;br /&gt;
ive never much thought about it, yet should we be consider and possible&lt;br /&gt;
reduce that one too?&lt;br /&gt;
&lt;br /&gt;
 - rh&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RobertH wrote on Wed, 21 Jan 2009 11:26:41 -0800:&lt;br /&gt;
&lt;br /&gt;
&amp;gt; what do you think about the &amp;quot;general Timeout&lt;br /&gt;
&amp;gt; &lt;br /&gt;
&amp;gt; it is set to 300&lt;br /&gt;
&amp;gt; &lt;br /&gt;
&amp;gt; ive never much thought about it, yet should we be consider and possible&lt;br /&gt;
&amp;gt; reduce that one too?&lt;br /&gt;
&lt;br /&gt;
I&#039;m using 120, but I don&#039;t think reducing this value has much impact.&lt;br /&gt;
&lt;br /&gt;
Kai&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Load Balancer ==&lt;br /&gt;
&lt;br /&gt;
Apache Load Balancer&lt;br /&gt;
&lt;br /&gt;
mod_proxy_balancer - Apache HTTP Server - mod_proxy_balancer - http://httpd.apache.org/docs/2.2/mod/mod_proxy_balancer.html&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;Proxy balancer://mycluster&amp;gt;&lt;br /&gt;
BalancerMember http://192.168.1.50:80&lt;br /&gt;
BalancerMember http://192.168.1.51:80&lt;br /&gt;
&amp;lt;/Proxy&amp;gt;&lt;br /&gt;
ProxyPass /test balancer://mycluster &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== User Directories ==&lt;br /&gt;
&lt;br /&gt;
Default:&lt;br /&gt;
 UserDir public_html &lt;br /&gt;
&lt;br /&gt;
Results in:&lt;br /&gt;
 ~/public_html/&lt;br /&gt;
&lt;br /&gt;
To disable user directories:&lt;br /&gt;
 UserDir disabled&lt;br /&gt;
&lt;br /&gt;
Ubuntu user dir config:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        UserDir public_html&lt;br /&gt;
        UserDir disabled root&lt;br /&gt;
&lt;br /&gt;
        &amp;lt;Directory /home/*/public_html&amp;gt;&lt;br /&gt;
                AllowOverride FileInfo AuthConfig Limit Indexes&lt;br /&gt;
                Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec&lt;br /&gt;
                &amp;lt;Limit GET POST OPTIONS&amp;gt;&lt;br /&gt;
                        Order allow,deny&lt;br /&gt;
                        Allow from all&lt;br /&gt;
                &amp;lt;/Limit&amp;gt;&lt;br /&gt;
                &amp;lt;LimitExcept GET POST OPTIONS&amp;gt;&lt;br /&gt;
                        Order deny,allow&lt;br /&gt;
                        Deny from all&lt;br /&gt;
                &amp;lt;/LimitExcept&amp;gt;&lt;br /&gt;
        &amp;lt;/Directory&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* Per-user web directories - Apache HTTP Server - http://httpd.apache.org/docs/2.2/howto/public_html.html&lt;br /&gt;
* mod_userdir - Apache HTTP Server - http://httpd.apache.org/docs/2.2/mod/mod_userdir.html#userdir&lt;br /&gt;
&lt;br /&gt;
== Minimal Memory Instance ==&lt;br /&gt;
&lt;br /&gt;
Assuming running prefork module (check with &#039;apache -l&#039;):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
KeepAlive off&lt;br /&gt;
&lt;br /&gt;
&amp;lt;IfModule mpm_prefork_module&amp;gt;&lt;br /&gt;
StartServers          2&lt;br /&gt;
MinSpareServers       2&lt;br /&gt;
MaxSpareServers      5&lt;br /&gt;
ServerLimit          20&lt;br /&gt;
MaxClients           20&lt;br /&gt;
MaxRequestsPerChild  10000&lt;br /&gt;
&amp;lt;/IfModule&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* Running Apache On A Memory-Constrained VPS | Kalzumeus Software - http://www.kalzumeus.com/2010/06/19/running-apache-on-a-memory-constrained-vps/&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
TODO See:&lt;br /&gt;
*  http://wiki.vpslink.com/Low_memory_MySQL_/_Apache_configurations&lt;br /&gt;
* http://www.narga.net/optimizing-apachephpmysql-low-memory-server/&lt;br /&gt;
&lt;br /&gt;
== LDAP Authentication ==&lt;br /&gt;
&lt;br /&gt;
 # Red Hat / RHEL&lt;br /&gt;
 sudo yum install mod_ldap&lt;br /&gt;
 # allow ldap to connect through selinux:&lt;br /&gt;
 sudo setsebool -P httpd_can_network_connect on&lt;br /&gt;
&lt;br /&gt;
 mod_ldap - Apache HTTP Server Version 2.4&lt;br /&gt;
 https://httpd.apache.org/docs/2.4/mod/mod_ldap.html&lt;br /&gt;
&lt;br /&gt;
== Issues ==&lt;br /&gt;
&lt;br /&gt;
=== Could not reliably determine domain name ===&lt;br /&gt;
&lt;br /&gt;
Warning:&lt;br /&gt;
 Could not reliably determine the server&#039;s fully qualified domain name&lt;br /&gt;
&lt;br /&gt;
Solution:&lt;br /&gt;
* Force ServerName in apache configs [http://askubuntu.com/questions/256013/could-not-reliably-determine-the-servers-fully-qualified-domain-name]&lt;br /&gt;
 ServerName localhost&lt;br /&gt;
&lt;br /&gt;
=== client denied by server configuration ===&lt;br /&gt;
&lt;br /&gt;
browser:&lt;br /&gt;
 403 Forbidden - You don&#039;t have permission to access / on this server.&lt;br /&gt;
&lt;br /&gt;
Error:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
==&amp;gt; httpd/default-error_log &amp;lt;==&lt;br /&gt;
[Mon Sep 01 21:42:02.273169 2014] [authz_core:error] [pid 11221] [client 174.52.47.54:50675] AH01630: client denied by server configuration: /www/&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add Directory allow permissions: [http://stackoverflow.com/questions/19445686/ubuntu-server-apache-2-4-6-client-denied-by-server-configuration-php-fpm]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
DocumentRoot /www&lt;br /&gt;
&amp;lt;Directory /www&amp;gt;&lt;br /&gt;
  Order allow,deny&lt;br /&gt;
  Allow from all&lt;br /&gt;
&amp;lt;/Directory&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or this worked better for me: [http://stackoverflow.com/questions/19445686/ubuntu-server-apache-2-4-6-client-denied-by-server-configuration-php-fpm] [https://mikegriffin.ie/blog/20140130-authz-core-error-client-denied-by-server-configuration/]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
DocumentRoot /www&lt;br /&gt;
&amp;lt;Directory /www&amp;gt;&lt;br /&gt;
  Require all granted&lt;br /&gt;
&amp;lt;/Directory&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Actually this just worked on the latest Ubuntu system:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;Directory /www/&amp;gt;&lt;br /&gt;
        Options Indexes FollowSymLinks&lt;br /&gt;
        AllowOverride None&lt;br /&gt;
        Require all granted&lt;br /&gt;
&amp;lt;/Directory&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* ClientDeniedByServerConfiguration - Httpd Wiki - https://wiki.apache.org/httpd/ClientDeniedByServerConfiguration&lt;br /&gt;
&lt;br /&gt;
=== permissions missing component path ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
==&amp;gt; httpd/default-error_log &amp;lt;==&lt;br /&gt;
[Mon Sep 01 21:50:09.256120 2014] [core:error] [pid 11511] (13)Permission denied: [client 174.52.47.54:50744] AH00035: access to \&lt;br /&gt;
/index.html denied (filesystem path &#039;/www/index.html&#039;) because search permissions are missing on a component of the path&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== keywords ==&lt;br /&gt;
&lt;br /&gt;
[[Category:Linux]]&lt;br /&gt;
[[Category:Web Development ‎]]&lt;br /&gt;
[[Category:Web]]&lt;br /&gt;
[[Category:HTML]]&lt;br /&gt;
[[Category:Internet]]&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=Apache&amp;diff=9863</id>
		<title>Apache</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=Apache&amp;diff=9863"/>
		<updated>2026-04-27T19:15:12Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: /* .htaccess */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{subpages}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Apache]]&lt;br /&gt;
&lt;br /&gt;
== Install Apache ==&lt;br /&gt;
&lt;br /&gt;
 # Debian / Ubuntu&lt;br /&gt;
 sudo apt install apache2&lt;br /&gt;
&lt;br /&gt;
 # Redhat&lt;br /&gt;
 yum install httpd&lt;br /&gt;
&lt;br /&gt;
== Virtual Hosting ==&lt;br /&gt;
 touch /etc/httpd/conf.d/virtual.conf&lt;br /&gt;
&lt;br /&gt;
Virtual Host Configuration File:&lt;br /&gt;
 /etc/httpd/conf.d/virtual.conf:&lt;br /&gt;
&lt;br /&gt;
HTTP Virtual Host&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
NameVirtualHost *:80&lt;br /&gt;
&lt;br /&gt;
&amp;lt;VirtualHost *:80&amp;gt;&lt;br /&gt;
    ServerName t0e.org&lt;br /&gt;
    ServerAlias www.t0e.org&lt;br /&gt;
&lt;br /&gt;
    DocumentRoot /www&lt;br /&gt;
&lt;br /&gt;
    ServerAdmin admin@t0e.org&lt;br /&gt;
    ErrorLog logs/t0e.org-error_log&lt;br /&gt;
    CustomLog logs/t0e.org-access_log common&lt;br /&gt;
&amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;VirtualHost *:80&amp;gt;&lt;br /&gt;
    ServerName www2.t0e.org&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
HTTPS Virtual Host:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
NameVirtualHost *:443&lt;br /&gt;
&lt;br /&gt;
&amp;lt;VirtualHost *:443&amp;gt;&lt;br /&gt;
    ServerName t0e.org&lt;br /&gt;
    ServerAlias www.t0e.org&lt;br /&gt;
&lt;br /&gt;
    # SSL Enabled:&lt;br /&gt;
    SSLEngine on&lt;br /&gt;
    SSLCertificateFile /etc/t0e.org.pem&lt;br /&gt;
&lt;br /&gt;
    # If using a godaddy certificate chain:&lt;br /&gt;
    #SSLCertificateFile /etc/contractpal.net.pem&lt;br /&gt;
    #SSLCertificateKeyFile /etc/contractpal.net.pem&lt;br /&gt;
    #SSLCertificateChainFile /etc/contractpal.net.pem&lt;br /&gt;
&lt;br /&gt;
    #Forwarding Traffic&lt;br /&gt;
    # RewriteEngine on&lt;br /&gt;
    # RewriteRule ^(/.*)  http://localhost:8080/$1   [P]&lt;br /&gt;
&lt;br /&gt;
    DocumentRoot /www&lt;br /&gt;
&lt;br /&gt;
    ServerAdmin admin@t0e.org&lt;br /&gt;
    ErrorLog logs/t0e.org-error_log&lt;br /&gt;
    CustomLog logs/t0e.org-access_log common&lt;br /&gt;
&amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
*[http://www.onlamp.com/pub/a/apache/2005/02/17/apacheckbk.html A Day in the Life of #Apache: Running Name-Based SSL Virtual Hosts in Apache]&lt;br /&gt;
*[http://httpd.apache.org/docs/1.3/vhosts/name-based.html Apache: Name-based Virtual Host Support]&lt;br /&gt;
*[http://www.networkworld.com/columnists/2006/011606internet.html Getting SSL to work across virtual hosts in Apache]&lt;br /&gt;
&lt;br /&gt;
== CentOS common configuration changes ==&lt;br /&gt;
&lt;br /&gt;
Keep alives:&lt;br /&gt;
 # KeepAlive Off&lt;br /&gt;
 KeepAlive On&lt;br /&gt;
&lt;br /&gt;
Hide Apache version (in likely in /etc/apache2/conf-enabled/security.conf):&lt;br /&gt;
 # ServerTokens Full&lt;br /&gt;
 ServerTokens Prod&lt;br /&gt;
&lt;br /&gt;
 # ServerSignature On&lt;br /&gt;
 ServerSignature Off&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
PHP config in /etc/php.ini (now likely in /etc/php/8.3/apache2/php.ini):&lt;br /&gt;
 expose_php = Off&lt;br /&gt;
&lt;br /&gt;
==Forwarding / Rewriting / Proxying Traffic==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
NameVirtualHost *:80&lt;br /&gt;
&amp;lt;VirtualHost *:80&amp;gt;&lt;br /&gt;
    ServerName t0e.org&lt;br /&gt;
    ServerAlias www.t0e.org&lt;br /&gt;
&lt;br /&gt;
    #Forwarding Traffic&lt;br /&gt;
    RewriteEngine on&lt;br /&gt;
    RewriteRule ^(/.*)  http://localhost:8080/$1   [P]&lt;br /&gt;
&lt;br /&gt;
    ServerAdmin admin@t0e.org&lt;br /&gt;
    ErrorLog logs/t0e.org-error_log&lt;br /&gt;
    CustomLog logs/t0e.org-access_log common&lt;br /&gt;
&amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Apache module mod_rewrite - RewriteRule - http://httpd.apache.org/docs/1.3/mod/mod_rewrite.html#RewriteRule&lt;br /&gt;
 a2enmod rewrite&lt;br /&gt;
&lt;br /&gt;
 a2enmod proxy_http&lt;br /&gt;
&lt;br /&gt;
[http://httpd.apache.org/docs/1.3/mod/mod_rewrite.html Module mod_rewrite - URL Rewriting Engine]:&lt;br /&gt;
*RewriteEngine&lt;br /&gt;
*RewriteCond&lt;br /&gt;
*RewriteRule&lt;br /&gt;
&lt;br /&gt;
[http://httpd.apache.org/docs/1.3/misc/rewriteguide.html Apache 1.3 - URL Rewriting Guide]&lt;br /&gt;
&lt;br /&gt;
[http://httpd.apache.org/docs/1.3/mod/mod_proxy.html Apache module mod_proxy]:&lt;br /&gt;
*ProxyPass&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;VirtualHost *:80&amp;gt;&lt;br /&gt;
    ServerName home.burgenerfamily.com&lt;br /&gt;
    DocumentRoot /www/home&lt;br /&gt;
    &amp;lt;Directory /www/home&amp;gt;&lt;br /&gt;
        Options FollowSymLinks&lt;br /&gt;
        RewriteEngine On&lt;br /&gt;
        # allow existing files and directories to pass through&lt;br /&gt;
        RewriteCond %{REQUEST_FILENAME} !-f&lt;br /&gt;
        RewriteCond %{REQUEST_FILENAME} !-d&lt;br /&gt;
        #RewriteRule ^static - [L,NC] &lt;br /&gt;
        #RewriteCond %{REQUEST_FILENAME} !^favicon.ico$&lt;br /&gt;
        #RewriteCond %{REQUEST_FILENAME} !^static/&lt;br /&gt;
        #RewriteRule ^(.+)$ /index.php?title=$1 [PT,L,QSA]&lt;br /&gt;
        RewriteRule ^(.*)$ /index.php/$1 [L,QSA]&lt;br /&gt;
    &amp;lt;/Directory&amp;gt;&lt;br /&gt;
    ErrorLog logs/home.burgenerfamily.com-error_log&lt;br /&gt;
    CustomLog logs/home.burgenerfamily.com-access_log common&lt;br /&gt;
&amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Proxy Pass ==&lt;br /&gt;
&lt;br /&gt;
Enable Proxy: [https://www.digitalocean.com/community/tutorials/how-to-use-apache-as-a-reverse-proxy-with-mod_proxy-on-ubuntu-16-04]&lt;br /&gt;
 sudo a2enmod proxy&lt;br /&gt;
 sudo a2enmod proxy_http&lt;br /&gt;
 systemctl restart apache2&lt;br /&gt;
&lt;br /&gt;
Similar to forwarding, but takes care of redirects:&lt;br /&gt;
&lt;br /&gt;
   ProxyPass         /mirror/foo/ http://foo.com/&lt;br /&gt;
   ProxyPassReverse  /mirror/foo/ http://foo.com/&lt;br /&gt;
&lt;br /&gt;
Suppose the local server has address http://wibble.org/; then&lt;br /&gt;
&lt;br /&gt;
   ProxyPass         /mirror/foo/ http://foo.com/&lt;br /&gt;
   ProxyPassReverse  /mirror/foo/ http://foo.com/&lt;br /&gt;
&lt;br /&gt;
will not only cause a local request for the &amp;lt;http://wibble.org/mirror/foo/bar&amp;gt; to be internally converted into a proxy request to &amp;lt;http://foo.com/bar&amp;gt; (the functionality ProxyPass provides here). It also takes care of redirects the server foo.com sends: when http://foo.com/bar is redirected by him to http://foo.com/quux Apache adjusts this to http://wibble.org/mirror/foo/quux before forwarding the HTTP redirect response to the client. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;VirtualHost *:80&amp;gt;&lt;br /&gt;
    ServerName wiki.oeey.com&lt;br /&gt;
&lt;br /&gt;
    # Reverse Proxy&lt;br /&gt;
    ProxyPass         / http://localhost:8080/&lt;br /&gt;
    ProxyPassReverse  / http://localhost:8080/&lt;br /&gt;
&lt;br /&gt;
    ServerAdmin website@oeey.com&lt;br /&gt;
    ErrorLog logs/wiki-error_log&lt;br /&gt;
    CustomLog logs/wiki-access_log common&lt;br /&gt;
&amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Proxy Pass to Jenkins: [https://wiki.jenkins-ci.org/display/JENKINS/Running+Jenkins+behind+Apache]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
NameVirtualHost *:80&lt;br /&gt;
&amp;lt;VirtualHost *:80&amp;gt;&lt;br /&gt;
    ServerName jenkins.oeey.com&lt;br /&gt;
&lt;br /&gt;
    #Forwarding Traffic&lt;br /&gt;
    #RewriteEngine on&lt;br /&gt;
    #RewriteRule ^(/.*)  http://localhost:8080/$1   [P]&lt;br /&gt;
&lt;br /&gt;
    ProxyPass         /  http://localhost:8080/ nocanon&lt;br /&gt;
    ProxyPassReverse  /  http://localhost:8080/&lt;br /&gt;
    ProxyRequests     Off&lt;br /&gt;
    ProxyPreserveHost On&lt;br /&gt;
    AllowEncodedSlashes NoDecode&lt;br /&gt;
&lt;br /&gt;
    # Local reverse proxy authorization override&lt;br /&gt;
    # Most unix distribution deny proxy by default (ie /etc/apache2/mods-enabled/proxy.conf in Ubuntu)&lt;br /&gt;
    &amp;lt;Proxy http://localhost:8080/*&amp;gt;&lt;br /&gt;
        Order deny,allow&lt;br /&gt;
        Allow from all&lt;br /&gt;
    &amp;lt;/Proxy&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    ServerAdmin admin@oeey.com&lt;br /&gt;
    ErrorLog logs/jenkins.oeey.com-error_log&lt;br /&gt;
    CustomLog logs/jenkins.oeey.com-access_log common&lt;br /&gt;
&amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Proxy Pass HTTPS ===&lt;br /&gt;
&lt;br /&gt;
Proxy Pass to Jenkins:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
NameVirtualHost *:443&lt;br /&gt;
&amp;lt;VirtualHost *:443&amp;gt;&lt;br /&gt;
    ServerName jenkins.oeey.com&lt;br /&gt;
&lt;br /&gt;
    # Enable SSL Support&lt;br /&gt;
    SSLEngine on&lt;br /&gt;
    SSLCertificateFile /etc/pki/tls/certs/localhost.crt&lt;br /&gt;
    SSLCertificateKeyFile /etc/pki/tls/private/localhost.key&lt;br /&gt;
&lt;br /&gt;
    #Forwarding Traffic&lt;br /&gt;
    #RewriteEngine on&lt;br /&gt;
    #RewriteRule ^(/.*)  http://localhost:8080/$1   [P]&lt;br /&gt;
&lt;br /&gt;
    ProxyPass         /  http://localhost:8080/ nocanon&lt;br /&gt;
    ProxyPassReverse  /  http://localhost:8080/&lt;br /&gt;
    ProxyPassReverse  /  http://jenkins.oeey.com/&lt;br /&gt;
    ProxyRequests     Off&lt;br /&gt;
    ProxyPreserveHost On&lt;br /&gt;
    AllowEncodedSlashes NoDecode&lt;br /&gt;
    RequestHeader set X-Forwarded-Proto &amp;quot;http&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # Local reverse proxy authorization override&lt;br /&gt;
    # Most unix distribution deny proxy by default (ie /etc/apache2/mods-enabled/proxy.conf in Ubuntu)&lt;br /&gt;
    &amp;lt;Proxy http://localhost:8080/jenkins*&amp;gt;&lt;br /&gt;
        Order deny,allow&lt;br /&gt;
        Allow from all&lt;br /&gt;
    &amp;lt;/Proxy&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    ServerAdmin admin@oeey.com&lt;br /&gt;
    ErrorLog logs/jenkins.oeey.com-error_log&lt;br /&gt;
    CustomLog logs/jenkins.oeey.com-access_log common&lt;br /&gt;
&amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Redirect ==&lt;br /&gt;
&lt;br /&gt;
Redirect with URI intact:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
NameVirtualHost *:80&lt;br /&gt;
&amp;lt;VirtualHost *:80&amp;gt;&lt;br /&gt;
    ServerName test.oeey.com&lt;br /&gt;
    Redirect permanent / http://www.oeey.com/&lt;br /&gt;
&amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Redirect users to HTTPS with URI intact:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
NameVirtualHost *:80&lt;br /&gt;
&amp;lt;VirtualHost *:80&amp;gt;&lt;br /&gt;
    ServerName test.oeey.com&lt;br /&gt;
    Redirect permanent / https://test.oeey.com/&lt;br /&gt;
&amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Can be wrapped in Location (if you want)&lt;br /&gt;
 &amp;lt;Location /&amp;gt;&lt;br /&gt;
   Redirect permanent / https://test.oeey.com/&lt;br /&gt;
 &amp;lt;/Location&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Redirect with RewriteEngine with URI intact:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
NameVirtualHost *:80&lt;br /&gt;
&amp;lt;VirtualHost *:80&amp;gt;&lt;br /&gt;
    ServerName test.oeey.com&lt;br /&gt;
&lt;br /&gt;
    # Redirect HTTP to HTTPS&lt;br /&gt;
    RewriteEngine On&lt;br /&gt;
    RewriteCond %{HTTPS} off&lt;br /&gt;
    RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}&lt;br /&gt;
&amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Redirect removing URI:&lt;br /&gt;
 NameVirtualHost *:80&lt;br /&gt;
 &amp;lt;VirtualHost *:80&amp;gt;&lt;br /&gt;
     ServerName test.oeey.com&lt;br /&gt;
     RedirectMatch &amp;quot;(.*)&amp;quot; &amp;quot;http://www.oeey.com/&amp;quot;&lt;br /&gt;
 &amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[http://httpd.apache.org/docs/2.0/mod/mod_alias.html Apache Module mod_alias]:&lt;br /&gt;
*Alias&lt;br /&gt;
*Redirect&lt;br /&gt;
*RedirectPermanent&lt;br /&gt;
&lt;br /&gt;
== Default Directory Index ==&lt;br /&gt;
&lt;br /&gt;
to set the default pages to try and load (e.g. index.html, index.php):&lt;br /&gt;
 DirectoryIndex index.html index.php&lt;br /&gt;
&lt;br /&gt;
== Directory Index ==&lt;br /&gt;
&lt;br /&gt;
To show full file names:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  &amp;lt;Directory /&amp;gt;&lt;br /&gt;
    Options Indexes&lt;br /&gt;
    IndexOptions NameWidth=*&lt;br /&gt;
  &amp;lt;/Directory&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sample:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;Directory &amp;quot;/www&amp;quot;&amp;gt;&lt;br /&gt;
    Options Indexes FollowSymLinks&lt;br /&gt;
    IndexOptions FancyIndexing NameWidth=*&lt;br /&gt;
    AllowOverride None&lt;br /&gt;
    Require all granted&lt;br /&gt;
&amp;lt;/Directory&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Hide Apache and PHP Banner ==&lt;br /&gt;
&lt;br /&gt;
Hide PHP version (X-Powered-By) - Edit php.ini: [http://www.ducea.com/2006/06/16/apache-tips-tricks-hide-php-version-x-powered-by/]&lt;br /&gt;
 expose_php = Off&lt;br /&gt;
&lt;br /&gt;
Hide Apache version: [http://www.itsolutionskb.com/2008/10/hide-apache-information/]&lt;br /&gt;
 # ServerSignature On&lt;br /&gt;
 ServerSignature Off&lt;br /&gt;
 &lt;br /&gt;
 # ServerTokens Full&lt;br /&gt;
 ServerTokens Prod&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* Hide Apache ServerSignature/ServerTokens/PHP X-Powered-By - http://www.if-not-true-then-false.com/2009/howto-hide-and-modify-apache-server-information-serversignature-and-servertokens-and-hide-php-version-x-powered-by/&lt;br /&gt;
&lt;br /&gt;
== .htaccess ==&lt;br /&gt;
&lt;br /&gt;
Override configuration settings on a per directory (and sub directories) level with:&lt;br /&gt;
 .htaccess&lt;br /&gt;
&lt;br /&gt;
Allow override of all configuration options:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;Directory /&amp;gt;&lt;br /&gt;
  AllowOverride All&lt;br /&gt;
&amp;lt;/Directory&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example directory browsing in .htaccess:&lt;br /&gt;
 Options +indexes&lt;br /&gt;
&lt;br /&gt;
Redirect to index.php:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RewriteEngine on&lt;br /&gt;
RewriteCond %{REQUEST_FILENAME} !-f&lt;br /&gt;
RewriteCond %{REQUEST_FILENAME} !-d&lt;br /&gt;
RewriteRule ^(.*)$ /index.php?path=$1 [NC,L,QSA]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 a2enmod rewrite&lt;br /&gt;
 #a2enmod proxy_http&lt;br /&gt;
&lt;br /&gt;
== Allow from networks ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;Directory &amp;quot;...&amp;quot;&amp;gt;&lt;br /&gt;
    Order Deny,Allow&lt;br /&gt;
    Deny from all&lt;br /&gt;
    Allow from 127.0.0.0/255.255.255.0  10.10.0.0/16&lt;br /&gt;
&amp;lt;/Directory&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Log Files ==&lt;br /&gt;
&lt;br /&gt;
    ErrorLog logs/test.com-error_log&lt;br /&gt;
    CustomLog logs/test.com-access_log common&lt;br /&gt;
&lt;br /&gt;
Make sure the soft link exists:&lt;br /&gt;
 ln -s /var/log/httpd /etc/httpd/logs      # RHEL based&lt;br /&gt;
 ln -s /var/log/apache2 /etc/apache2/logs  # Debian Based&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*[http://httpd.apache.org/docs/2.0/logs.html Log Files v2.0]&lt;br /&gt;
*[http://httpd.apache.org/docs/1.3/logs.html#accesslog Log files v1.3]&lt;br /&gt;
&lt;br /&gt;
===Log HTTPS X-Forwarded-For===&lt;br /&gt;
[http://www.webmasterworld.com/forum92/6134.htm Log the X-Forwarded-For] header in apache...&lt;br /&gt;
 LogFormat &amp;quot;[X-Forwarded-For: %{X-Forwarded-For}i] %h %l %u %t \&amp;quot;%r\&amp;quot; %&amp;gt;s %b \&amp;quot;%{Referer}i\&amp;quot; \&amp;quot;%{User-Agent}i\&amp;quot;&amp;quot; combined&lt;br /&gt;
 LogFormat &amp;quot;[X-Forwarded-For: %{X-Forwarded-For}i] %h %l %u %t \&amp;quot;%r\&amp;quot; %&amp;gt;s %b&amp;quot; common&lt;br /&gt;
 LogFormat &amp;quot;%{Referer}i -&amp;gt; %U&amp;quot; referer&lt;br /&gt;
 LogFormat &amp;quot;%{User-agent}i&amp;quot; agent&lt;br /&gt;
&lt;br /&gt;
== PHP ==&lt;br /&gt;
&lt;br /&gt;
Install PHP with Apache: (Ubuntu)&lt;br /&gt;
 #apt-get install apache2 php5 libapache2-mod-php5&lt;br /&gt;
 apt-get install apache2 php libapache2-mod-php&lt;br /&gt;
&lt;br /&gt;
== Apache SSL ==&lt;br /&gt;
&lt;br /&gt;
Enable SSL with...&lt;br /&gt;
&lt;br /&gt;
Apache can do virtual SSL hosting!&lt;br /&gt;
&lt;br /&gt;
Install mod_ssl: [https://help.ubuntu.com/10.04/serverguide/httpd.html]&lt;br /&gt;
 # redhat / rhel&lt;br /&gt;
 sudo yum install mod_ssl&lt;br /&gt;
&lt;br /&gt;
 # debian / ubuntu&lt;br /&gt;
 sudo a2enmod ssl&lt;br /&gt;
 sudo a2ensite default-ssl&lt;br /&gt;
 systemctl reload apache2&lt;br /&gt;
&lt;br /&gt;
/etc/httpd/conf.d/ssl.conf:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LoadModule ssl_module modules/mod_ssl.so&lt;br /&gt;
Listen 443&lt;br /&gt;
AddType application/x-x509-ca-cert .crt&lt;br /&gt;
AddType application/x-pkcs7-crl    .crl&lt;br /&gt;
SSLPassPhraseDialog  builtin&lt;br /&gt;
SSLSessionCache         shmcb:/var/cache/mod_ssl/scache(512000)&lt;br /&gt;
SSLSessionCacheTimeout  300&lt;br /&gt;
SSLMutex default&lt;br /&gt;
SSLRandomSeed startup file:/dev/urandom  256&lt;br /&gt;
SSLRandomSeed connect builtin&lt;br /&gt;
SSLCryptoDevice builtin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: Delete the default VirtualHost section so we can add our own.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# SSL Configuration - from ssl.conf virtual host example&lt;br /&gt;
SSLEngine On&lt;br /&gt;
SSLProtocol all -SSLv2&lt;br /&gt;
SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM:+LOW&lt;br /&gt;
SSLCertificateFile /etc/pki/tls/certs/localhost.crt&lt;br /&gt;
SSLCertificateKeyFile /etc/pki/tls/private/localhost.key&lt;br /&gt;
&lt;br /&gt;
CustomLog logs/ssl_request_log \&lt;br /&gt;
          &amp;quot;%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \&amp;quot;%r\&amp;quot; %b&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# SSL configuration&lt;br /&gt;
SSLEngine On&lt;br /&gt;
SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL&lt;br /&gt;
SSLCertificateFile /etc/apache2/ssl/cert.crt&lt;br /&gt;
SSLCertificateKeyFile /etc/apache2/ssl/cert.key&lt;br /&gt;
SSLCertificateChainFile /etc/apache2/ssl/sf_bundle.crt&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
NameVirtualHost *:80&lt;br /&gt;
&amp;lt;VirtualHost *:80&amp;gt;&lt;br /&gt;
    ServerName default.t0e.org&lt;br /&gt;
&lt;br /&gt;
    # Redirect HTTP to HTTPS&lt;br /&gt;
    RewriteEngine On&lt;br /&gt;
    RewriteCond %{HTTPS} off&lt;br /&gt;
    RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}&lt;br /&gt;
&amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&lt;br /&gt;
NameVirtualHost *:443&lt;br /&gt;
&amp;lt;VirtualHost *:443&amp;gt;&lt;br /&gt;
    ServerName kb.t0e.org&lt;br /&gt;
&lt;br /&gt;
    # SSL Enabled: (only once in config file)&lt;br /&gt;
    SSLEngine on&lt;br /&gt;
    SSLCertificateFile /etc/t0e.org.pem&lt;br /&gt;
    SSLCertificateKeyFile /etc/t0e.org.pem&lt;br /&gt;
    SSLProtocol all -SSLv2&lt;br /&gt;
    SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM:+LOW&lt;br /&gt;
&lt;br /&gt;
    DocumentRoot /www&lt;br /&gt;
&lt;br /&gt;
    ServerAdmin admin@kb.t0e.org.com&lt;br /&gt;
    ErrorLog logs/kb.t0e.org-error_log&lt;br /&gt;
    CustomLog logs/kb.t0e.org-access_log common&lt;br /&gt;
&amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;VirtualHost *:443&amp;gt;&lt;br /&gt;
    ServerName wiki.t0e.org&lt;br /&gt;
&lt;br /&gt;
    DocumentRoot /www&lt;br /&gt;
&lt;br /&gt;
    ServerAdmin admin@wiki.t0e.org.com&lt;br /&gt;
    ErrorLog logs/wiki.t0e.org-error_log&lt;br /&gt;
    CustomLog logs/wiki.t0e.org-access_log common&lt;br /&gt;
&amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: With SSL, Apache will always use the first default virtual hosts&#039; certificate, so it only makes sense to define it there.&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
*[http://www.apache-ssl.org/ Apache SSL]&lt;br /&gt;
*[http://httpd.apache.org/docs/2.0/ssl/ Apache SSL/TLS Encryption Documentation]&lt;br /&gt;
*[http://httpd.apache.org/docs/2.0/mod/mod_ssl.html mod_ssl]&lt;br /&gt;
*[http://www.securityfocus.com/infocus/1818 Article: Apache 2 with SSL/TLS: Step-by-Step, Part 1]&lt;br /&gt;
*[http://www.vanemery.com/Linux/Apache/apache-SSL.html Van&#039;s Apache SSL/TLS mini-HOWTO]&lt;br /&gt;
*[http://tomcat.apache.org/tomcat-3.3-doc/tomcat-ssl-howto.html Tomcat SSL Configuration]&lt;br /&gt;
*[http://httpd.apache.org/docs/2.0/ssl/ssl_faq.html Apache: SSL/TLS Strong Encryption: FAQ]&lt;br /&gt;
*[http://www.networkworld.com/columnists/2006/011606internet.html Getting SSL to work across virtual hosts in Apache]&lt;br /&gt;
*[http://www.faqs.org/docs/Linux-HOWTO/SSL-RedHat-HOWTO.html Building a Secure RedHat Apache Server HOWTO]&lt;br /&gt;
* CommonMisconfigurations - Httpd Wiki - http://wiki.apache.org/httpd/CommonMisconfigurations&lt;br /&gt;
&lt;br /&gt;
--- chain ---&lt;br /&gt;
&lt;br /&gt;
If you have a chain, create the pem as &amp;quot;key, cert, chain&amp;quot; and set Apache config like so:&lt;br /&gt;
&lt;br /&gt;
    SSLCertificateFile /etc/ssl.pem&lt;br /&gt;
    SSLCertificateKeyFile /etc/ssl.pem&lt;br /&gt;
    SSLCertificateChainFile /etc/ssl.pem&lt;br /&gt;
&lt;br /&gt;
or just&lt;br /&gt;
&lt;br /&gt;
    SSLCertificateFile /etc/ssl.pem&lt;br /&gt;
    SSLCertificateChainFile /etc/ssl.pem&lt;br /&gt;
&lt;br /&gt;
=== Ubuntu SnakeOil Cert ===&lt;br /&gt;
&lt;br /&gt;
Install the snakoil fake cert &amp;lt;ref&amp;gt;https://superuser.com/questions/58149/host-based-snakeoil-certificates-in-ubuntu&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 sudo apt-get install ssl-cert&lt;br /&gt;
&lt;br /&gt;
 sudo make-ssl-cert generate-default-snakeoil --force-overwrite&lt;br /&gt;
&lt;br /&gt;
 /etc/ssl/certs/ssl-cert-snakeoil.pem&lt;br /&gt;
 /etc/ssl/private/ssl-cert-snakeoil.key&lt;br /&gt;
&lt;br /&gt;
== Linux System Password Protection ==&lt;br /&gt;
&lt;br /&gt;
Using system accounts for HTTP authentication - http://wiki.zs64.net/Using_system_accounts_for_HTTP_authentication&lt;br /&gt;
&lt;br /&gt;
  httpd.conf&lt;br /&gt;
&lt;br /&gt;
Edit httpd.conf to add these lines to the general configuration:&lt;br /&gt;
&lt;br /&gt;
LoadModule              auth_external_module    libexec/apache2/mod_auth_external.so&lt;br /&gt;
&lt;br /&gt;
(Should have been added by installing the port already.)&lt;br /&gt;
&lt;br /&gt;
Add these lines to each virtual host where you&#039;d like to use system accounts for authentication:&lt;br /&gt;
&lt;br /&gt;
AddExternalAuth         pwauth  /usr/local/bin/pwauth&lt;br /&gt;
SetExternalAuthMethod   pwauth  pipe&lt;br /&gt;
&lt;br /&gt;
Add these lines to each Directory or Location section that you want protected by authentication:&lt;br /&gt;
&lt;br /&gt;
AuthType        Basic&lt;br /&gt;
AuthExternal    pwauth&lt;br /&gt;
require         valid-user&lt;br /&gt;
&lt;br /&gt;
== Password Protection with .htaccess and htpasswd ==&lt;br /&gt;
&lt;br /&gt;
*[http://www.javascriptkit.com/howto/htaccess3.shtml Comprehensive guide to .htaccess: Password protection]&lt;br /&gt;
*[http://apache-server.com/tutorials/ATusing-htaccess.html Using .htaccess Files with Apache]&lt;br /&gt;
*[http://www.4webhelp.net/tutorials/misc/htaccess.php Password Protection by Rod]&lt;br /&gt;
*[http://www.spoono.com/php/tutorials/tutorial.php?id=30 .htaccess Password Protection in PHP]&lt;br /&gt;
&lt;br /&gt;
Sample .htaccess file:&lt;br /&gt;
&lt;br /&gt;
 AuthUserFile /var/www/htpasswd&lt;br /&gt;
 AuthGroupFile /dev/null&lt;br /&gt;
 AuthName &amp;quot;Secret Place&amp;quot;&lt;br /&gt;
 AuthType Basic&lt;br /&gt;
 Require valid-user&lt;br /&gt;
 &lt;br /&gt;
 #Require user &amp;lt;user&amp;gt;&lt;br /&gt;
 #Require group &amp;lt;group&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
To use with httpd.conf or virtual.conf, wrap in &amp;quot;&amp;lt;Directory&amp;gt;&amp;quot; tags:&lt;br /&gt;
 &amp;lt;Directory /&amp;gt;&lt;br /&gt;
   AuthUserFile ...&lt;br /&gt;
   ...&lt;br /&gt;
 &amp;lt;/Directory&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: if you want in your httpd.conf (or virtual.conf) surround with &amp;quot;&amp;lt;Location /&amp;gt;...&amp;lt;/Location&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
To add password file:&lt;br /&gt;
 htpasswd -c /var/www/htpasswd admin&lt;br /&gt;
 htpasswd /var/www/htpasswd user1&lt;br /&gt;
&lt;br /&gt;
 # if you want to create a blank username with password:&lt;br /&gt;
 htpasswd /path/htpasswd &#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To use .htaccess:&lt;br /&gt;
 &amp;lt;Directory /&amp;gt;&lt;br /&gt;
     Options FollowSymLinks&lt;br /&gt;
     AllowOverride &#039;&#039;&#039;AuthConfig&#039;&#039;&#039;&lt;br /&gt;
 &amp;lt;/Directory&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Or user the [http://www.webmaster-toolkit.com/htaccess-generator.shtml .htaccess generator]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[http://httpd.apache.org/docs/2.2/mod/core.html#require Apache HTTP Server - Require Directive]:&lt;br /&gt;
&lt;br /&gt;
Require user userid [userid] ...&lt;br /&gt;
:Only the named users can access the resource.&lt;br /&gt;
Require group group-name [group-name] ...&lt;br /&gt;
:Only users in the named groups can access the resource.&lt;br /&gt;
Require valid-user&lt;br /&gt;
:All valid users can access the resource. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
AuthType Basic&lt;br /&gt;
AuthName &amp;quot;Restricted Resource&amp;quot;&lt;br /&gt;
AuthUserFile /web/users&lt;br /&gt;
AuthGroupFile /web/groups&lt;br /&gt;
Require group admin &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== web based htpasswd manager ===&lt;br /&gt;
&lt;br /&gt;
see [[change_htpasswd.pl]]&lt;br /&gt;
&lt;br /&gt;
[http://home.xnet.com/~efflandt/pub/htpasswd.pl htpasswd.cgi by David Efflandt]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Perl CGI Script to Modify User Passwords:&lt;br /&gt;
&lt;br /&gt;
This allows users to manage / change their own passwords.&lt;br /&gt;
&lt;br /&gt;
Use the Perl CGI script [http://home.xnet.com/%7Eefflandt/pub/htpasswd.pl htpasswd.pl] [[http://www.yolinux.com/TUTORIALS/src/htpasswd_pl.txt cache]]&lt;br /&gt;
&lt;br /&gt;
* Edit location of Perl .i.e.: /usr/bin/perl&lt;br /&gt;
** Not /usr/local/bin/perl&lt;br /&gt;
* Edit the script to specify location of the password file i.e. /var/www/PasswordDir/.htpasswd&lt;br /&gt;
* SELinux users must add the correct attribute i.e. chcon -R -h -t httpd_sys_content_t /var/www/PasswordDir&lt;br /&gt;
* The password file must be located in a directory where CGI is allowed to modify files.&lt;br /&gt;
&lt;br /&gt;
File: httpd.conf (portion):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
..&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;Directory &amp;quot;/var/www/PasswordDir&amp;quot;&amp;gt;&lt;br /&gt;
    Options -Indexes&lt;br /&gt;
    AllowOverride None&lt;br /&gt;
    Options None&lt;br /&gt;
    Order allow,deny&lt;br /&gt;
    Allow from all&lt;br /&gt;
&amp;lt;/Directory&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
..&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Directory Browsing==&lt;br /&gt;
 DocumentRoot /www/files&lt;br /&gt;
 &amp;lt;Directory /&amp;gt;&lt;br /&gt;
     Options FollowSymLinks &#039;&#039;&#039;+Indexes&#039;&#039;&#039;&lt;br /&gt;
     AllowOverride None&lt;br /&gt;
 &amp;lt;/Directory&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: The &#039;+&#039; may not be needed.&lt;br /&gt;
&lt;br /&gt;
In a .htaccess:&lt;br /&gt;
 Options +indexes&lt;br /&gt;
&lt;br /&gt;
Long file names: [http://www.networkworld.com/article/2311687/software/showing-long-file-names-in-apache-directory-listings.html]&lt;br /&gt;
 IndexOptions NameWidth=*&lt;br /&gt;
&lt;br /&gt;
For root indexes, the welcome.conf may be overriding with the welcome screen.  Make the following change: [http://www.linuxquestions.org/questions/linux-general-1/apache-2-root-directory-listing-201356/]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;LocationMatch &amp;quot;^/$&amp;gt;&lt;br /&gt;
    #Options -Indexes&lt;br /&gt;
    Options Indexes&lt;br /&gt;
    ErrorDocument 403 /error/noindex.html&lt;br /&gt;
&amp;lt;/LocationMatch&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== cgi ==&lt;br /&gt;
&lt;br /&gt;
Script Alias folder:&lt;br /&gt;
 ScriptAlias /cgi-bin/ &amp;quot;C:/Program Files/Apache Group/Apache/cgi-bin/&amp;quot; &lt;br /&gt;
 ScriptAlias /cgi-bin/ &amp;quot;/var/www/cgi-bin/&amp;quot;&lt;br /&gt;
&lt;br /&gt;
My favorite option, make all .cgi files executable: (This will need to be surrounded with &#039;&amp;lt;Location /&amp;gt;&#039; or &#039;&amp;lt;Directory /&amp;gt;&#039; tags)&lt;br /&gt;
 AddHandler cgi-script .cgi &lt;br /&gt;
 Options +ExecCGI &lt;br /&gt;
&lt;br /&gt;
Note: Make sure to &#039;chmod +x&#039; the files.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;VirtualHost *:80&amp;gt;&lt;br /&gt;
    ServerName hg.t0e.org&lt;br /&gt;
&lt;br /&gt;
    DirectoryIndex hgweb.cgi&lt;br /&gt;
    DocumentRoot /www/hg&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;Location /&amp;gt;&lt;br /&gt;
        AddHandler cgi-script .cgi&lt;br /&gt;
        Options +ExecCGI&lt;br /&gt;
    &amp;lt;/Location&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    ServerAdmin admin@hg.t0e.org&lt;br /&gt;
    ErrorLog logs/hg.t0e.org-error_log&lt;br /&gt;
    CustomLog logs/hg.t0e.org-access_log common&lt;br /&gt;
&amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Source: [http://www.thesitewizard.com/archive/addcgitoapache.shtml How to Add CGI Script Support (Perl, Python, etc) to Your Apache Server on Windows (thesitewizard.com)]&lt;br /&gt;
&lt;br /&gt;
--&lt;br /&gt;
&lt;br /&gt;
Only files without an extension:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;VirtualHost *:80&amp;gt;&lt;br /&gt;
    ServerName pi.t0e.org&lt;br /&gt;
    DocumentRoot /www/pi&lt;br /&gt;
    &amp;lt;Directory /&amp;gt;&lt;br /&gt;
        AllowOverride All&lt;br /&gt;
    &amp;lt;/Directory&amp;gt;&lt;br /&gt;
    DirectoryIndex index index.php index.html index.htm&lt;br /&gt;
    &amp;lt;Files ~ &amp;quot;^[a-zA-Z]*$&amp;quot;&amp;gt;&lt;br /&gt;
        SetHandler cgi-script&lt;br /&gt;
        Options +ExecCGI&lt;br /&gt;
    &amp;lt;/Files&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
=== CentOS Default ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#&lt;br /&gt;
# ScriptAliases are essentially the same as Aliases, except that&lt;br /&gt;
# documents in the realname directory are treated as applications and&lt;br /&gt;
# run by the server when requested rather than as documents sent to the client.&lt;br /&gt;
# The same rules about trailing &amp;quot;/&amp;quot; apply to ScriptAlias directives as to&lt;br /&gt;
# Alias.&lt;br /&gt;
#&lt;br /&gt;
ScriptAlias /cgi-bin/ &amp;quot;/var/www/cgi-bin/&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
# &amp;quot;/var/www/cgi-bin&amp;quot; should be changed to whatever your ScriptAliased&lt;br /&gt;
# CGI directory exists, if you have that configured.&lt;br /&gt;
#&lt;br /&gt;
&amp;lt;Directory &amp;quot;/var/www/cgi-bin&amp;quot;&amp;gt;&lt;br /&gt;
    AllowOverride None&lt;br /&gt;
    Options None&lt;br /&gt;
    Order allow,deny&lt;br /&gt;
    Allow from all&lt;br /&gt;
&amp;lt;/Directory&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Python CGI ==&lt;br /&gt;
&lt;br /&gt;
See [[Python#Apache_CGI]]&lt;br /&gt;
&lt;br /&gt;
==mod_proxy==&lt;br /&gt;
*http://www.apachetutor.org/admin/reverseproxies&lt;br /&gt;
*http://www.linuxfocus.org/English/March2000/article147.html&lt;br /&gt;
*http://www.linuxhelp.net/guides/apacheproxy/&lt;br /&gt;
*http://webauth.stanford.edu/manual/mod/mod_proxy.html&lt;br /&gt;
*http://www.apachetutor.org/admin/reverseproxies&lt;br /&gt;
*http://confluence.atlassian.com/display/DOC/Using+Apache+with+mod_proxy&lt;br /&gt;
*http://www.serverwatch.com/tutorials/article.php/3290851&lt;br /&gt;
*http://apache.webthing.com/mod_proxy_html/&lt;br /&gt;
*http://www.ibm.com/developerworks/linux/library/wa-lampsec/index.html&lt;br /&gt;
&lt;br /&gt;
== prefork vs worker ==&lt;br /&gt;
&lt;br /&gt;
Prefork performs better.  Worker uses less memory.  Prefork is most commonly used, and is the better choice for a web server.&lt;br /&gt;
&lt;br /&gt;
To see which is compiled, and look for prefork.c or worker.c:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# httpd -l&lt;br /&gt;
 &lt;br /&gt;
Compiled in modules:&lt;br /&gt;
  core.c&lt;br /&gt;
  prefork.c&lt;br /&gt;
  http_core.c&lt;br /&gt;
  mod_so.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Statistics ==&lt;br /&gt;
&lt;br /&gt;
=== Connections ===&lt;br /&gt;
&lt;br /&gt;
Count active connections:&lt;br /&gt;
 netstat -ant | grep ESTABLISHED | grep :80 | wc -l&lt;br /&gt;
&lt;br /&gt;
From PHP:&lt;br /&gt;
 &amp;lt;?php&lt;br /&gt;
 $number_of_users = shell_exec(&#039;netstat -ant | grep ESTABLISHED | grep :80 | wc -l&#039;);&lt;br /&gt;
 echo $number_of_users;&lt;br /&gt;
 ?&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* [http://www.experts-exchange.com/OS/Linux/Q_22825240.html Find out how many connections are on an apache server : apache, connections, many, find, server]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== [http://httpd.apache.org/docs/2.0/mod/mod_status.html mod_status] ===&lt;br /&gt;
&lt;br /&gt;
[http://httpd.apache.org/docs/2.0/mod/mod_status.html mod_status - Apache HTTP Server]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Summary&lt;br /&gt;
&lt;br /&gt;
The Status module allows a server administrator to find out how well their server is performing. A HTML page is presented that gives the current server statistics in an easily readable form. If required this page can be made to automatically refresh (given a compatible browser). Another page gives a simple machine-readable list of the current server state.&lt;br /&gt;
&lt;br /&gt;
The details given are:&lt;br /&gt;
&lt;br /&gt;
* The number of worker serving requests&lt;br /&gt;
* The number of idle worker&lt;br /&gt;
* The status of each worker, the number of requests that worker has performed and the total number of bytes served by the worker (*)&lt;br /&gt;
* A total number of accesses and byte count served (*)&lt;br /&gt;
* The time the server was started/restarted and the time it has been running for&lt;br /&gt;
* Averages giving the number of requests per second, the number of bytes served per second and the average number of bytes per request (*)&lt;br /&gt;
* The current percentage CPU used by each worker and in total by Apache (*)&lt;br /&gt;
* The current hosts and requests being processed (*)&lt;br /&gt;
&lt;br /&gt;
The lines marked &amp;quot;(*)&amp;quot; are only available if ExtendedStatus is On.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LoadModule status_module modules/mod_status.so&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
# ExtendedStatus controls whether Apache will generate &amp;quot;full&amp;quot; status&lt;br /&gt;
# information (ExtendedStatus On) or just basic information (ExtendedStatus&lt;br /&gt;
# Off) when the &amp;quot;server-status&amp;quot; handler is called. The default is Off.&lt;br /&gt;
#&lt;br /&gt;
#ExtendedStatus On&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
# Allow server status reports generated by mod_status,&lt;br /&gt;
# with the URL of http://servername/server-status&lt;br /&gt;
# Change the &amp;quot;.example.com&amp;quot; to match your domain to enable.&lt;br /&gt;
#&lt;br /&gt;
#&amp;lt;Location /server-status&amp;gt;&lt;br /&gt;
#    SetHandler server-status&lt;br /&gt;
#    Order deny,allow&lt;br /&gt;
#    Deny from all&lt;br /&gt;
#    Allow from .example.com&lt;br /&gt;
#&amp;lt;/Location&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* [http://httpd.apache.org/docs/2.0/mod/mod_status.html mod_status - Apache HTTP Server]&lt;br /&gt;
* [http://www.experts-exchange.com/OS/Linux/Q_22825240.html Find out how many connections are on an apache server : apache, connections, many, find, server]&lt;br /&gt;
&lt;br /&gt;
== TRACE and TRACK ==&lt;br /&gt;
&lt;br /&gt;
ISO Audit may result in this &amp;quot;Medium&amp;quot; risk detected:&lt;br /&gt;
&lt;br /&gt;
:&amp;quot;HTTP Methods Allowed.  It is observed that HTTP methods GET HEAD TRACE OPTIONS are allowed on this host.  Disable all unnecessary methods.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
:&amp;quot;HTTP TRACE / TRACK Methods Allowed.  The remote webserver supports the TRACE and/or TRACK methods.  TRACE and TRACK are HTTP methods that are used to debug web server connections.  Disable these methods.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Disabling TRACE ===&lt;br /&gt;
&lt;br /&gt;
[http://rackerhacker.com/2007/08/28/apache-disable-trace-and-track-methods/ Apache: Disable TRACE and TRACK methods | Racker Hacker]:&lt;br /&gt;
&lt;br /&gt;
Lots of PCI Compliance and vulnerability scan vendors will complain about TRACE and TRACK methods being enabled on your server. Since most providers run Nessus, you&#039;ll see this fairly often. Here&#039;s the rewrite rules to add:&lt;br /&gt;
&lt;br /&gt;
 RewriteEngine on&lt;br /&gt;
 RewriteCond %{REQUEST_METHOD} ^(TRACE|TRACK)&lt;br /&gt;
 RewriteRule .* - [F]&lt;br /&gt;
&lt;br /&gt;
These directives will need to be added to each VirtualHost.&lt;br /&gt;
&lt;br /&gt;
For apache version 1.3.34 (or later 1.3.x versions), or apache 2.0.55 (or later), this has been made easy. Just add the line TraceEnable off&lt;br /&gt;
&lt;br /&gt;
 TraceEnable off&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[http://publib.boulder.ibm.com/httpserv/ihsdiag/http_trace.html Disabling the HTTP TRACE method]:&lt;br /&gt;
&lt;br /&gt;
The HTTP TRACE request method causes the data received by IBM HTTP Server from the client to be sent back to the client, as in the following example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ telnet 127.0.0.1 8080&lt;br /&gt;
Trying...&lt;br /&gt;
Connected to 127.0.0.1.&lt;br /&gt;
Escape character is &#039;^]&#039;.&lt;br /&gt;
TRACE / HTTP/1.0&lt;br /&gt;
Host: foo&lt;br /&gt;
A: b&lt;br /&gt;
C: d&lt;br /&gt;
&lt;br /&gt;
HTTP/1.1 200 OK&lt;br /&gt;
Date: Mon, 04 Oct 2004 14:07:59 GMT&lt;br /&gt;
Server: IBM_HTTP_SERVER&lt;br /&gt;
Connection: close&lt;br /&gt;
Content-Type: message/http&lt;br /&gt;
&lt;br /&gt;
TRACE / HTTP/1.0&lt;br /&gt;
A: b&lt;br /&gt;
C: d&lt;br /&gt;
Host: foo&lt;br /&gt;
&lt;br /&gt;
Connection closed.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The TRACE capability could be used by vulnerable or malicious applications to trick a web browser into issuing a TRACE request against an arbitrary site and then send the response to the TRACE to a third party using web browser features.&lt;br /&gt;
&lt;br /&gt;
Making the required configuration changes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;VirtualHost www.example.com&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
# disable TRACE in the www.example.com virtual host&lt;br /&gt;
RewriteEngine On &lt;br /&gt;
RewriteCond %{REQUEST_METHOD} ^TRACE &lt;br /&gt;
RewriteRule .* - [F] &lt;br /&gt;
&amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Using SSL:&lt;br /&gt;
 $ /usr/linux/bin/openssl s_client -connect 127.0.0.1:8444&lt;br /&gt;
&lt;br /&gt;
For more information...&lt;br /&gt;
&lt;br /&gt;
More background information on the concerns with TRACE is provided at http://www.apacheweek.com/issues/03-01-24#news.&lt;br /&gt;
&lt;br /&gt;
Other:&lt;br /&gt;
* Apache Tips: Disable the HTTP TRACE method | MDLog:/sysadmin - http://www.ducea.com/2007/10/22/apache-tips-disable-the-http-trace-method/&lt;br /&gt;
&lt;br /&gt;
=== TraceEnable ===&lt;br /&gt;
&lt;br /&gt;
Apache Core Features - http://httpd.apache.org/docs/1.3/mod/core.html#traceenable&lt;br /&gt;
&lt;br /&gt;
TraceEnable:&lt;br /&gt;
 Syntax: TraceEnable [on|off|extended]&lt;br /&gt;
 Default: TraceEnable on&lt;br /&gt;
 Context: server config&lt;br /&gt;
 Status: core (Windows, NetWare)&lt;br /&gt;
 Compatibility: Available only in Apache 1.3.34, 2.0.55 and later&lt;br /&gt;
&lt;br /&gt;
This directive overrides the behavior of TRACE for both the core server and mod_proxy. The default TraceEnable on permits TRACE requests per RFC 2616, which disallows any request body to accompany the request. TraceEnable off causes the core server and mod_proxy to return a 405 FORBIDDEN error to the client.&lt;br /&gt;
&lt;br /&gt;
Finally, for testing and diagnostic purposes only, request bodies may be allowed using the non-compliant TraceEnable extended directive. The core (as an origin server) will restrict the request body to 64k (plus 8k for chunk headers if Transfer-Encoding: chunked is used). The core will reflect the full headers and all chunk headers with the request body. As a proxy server, the request body is not restricted to 64k. At this time the Apache 1.3 mod_proxy does not permit chunked request bodies for any request, including the extended TRACE request.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Disabling TRACK ===&lt;br /&gt;
&lt;br /&gt;
The HTTP TRACK method&lt;br /&gt;
&lt;br /&gt;
The TRACK method is a type of request supported by Microsoft web servers. It is not RFC compliant and is not supported directly by IBM HTTP Server. The method may be utilized as part of a cross-site scripting attack. See Vulnerability Note VU#288308 for more information.&lt;br /&gt;
&lt;br /&gt;
Even though IBM HTTP Server does not support the TRACK method natively, it is possible for plug-in modules to provide support for it. To disable this capability for plug-in modules, in addition to disabling the TRACE method, add these two additional directives after the existing RewriteCond and RewriteRule directives which are used to disable TRACE:&lt;br /&gt;
&lt;br /&gt;
RewriteCond %{REQUEST_METHOD} ^TRACK&lt;br /&gt;
RewriteRule .* - [F]&lt;br /&gt;
&lt;br /&gt;
Here is a full example showing the directives to disable both TRACE and TRACK:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;VirtualHost www.example.com&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
# disable TRACE and TRACK in the www.example.com virtual host&lt;br /&gt;
RewriteEngine On &lt;br /&gt;
RewriteCond %{REQUEST_METHOD} ^TRACE &lt;br /&gt;
RewriteRule .* - [F] &lt;br /&gt;
RewriteCond %{REQUEST_METHOD} ^TRACK&lt;br /&gt;
RewriteRule .* - [F] &lt;br /&gt;
&amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Attack ===&lt;br /&gt;
&lt;br /&gt;
Cross-Site Tracing issues&lt;br /&gt;
&lt;br /&gt;
Earlier this week a paper was published, [http://www.cgisecurity.com/whitehat-mirror/WH-WhitePaper_XST_ebook.pdf &amp;quot;Cross-Site Tracing&amp;quot;] which gave details of how the TRACE HTTP request could be used in Cross-Site Scripting attacks. Unfortunately this issue has not been very well understood by the media and has received a unwarranted amount of attention.&lt;br /&gt;
&lt;br /&gt;
When an HTTP TRACE request is sent to a web server that supports it, that server will respond echoing the data that is passed to it, including any HTTP headers. The paper explains that some browsers can be scripted to perform a TRACE request. A browser with this functionality could be made to issue a TRACE request against an arbitrary site and pass the results on elsewhere. Since browsers will only send authentication details and cookies to the sites that issue them this means a user having a browser with this functionality could be tricked into sending their cookies or authentication details for arbitrary sites to an attacker.&lt;br /&gt;
&lt;br /&gt;
For example, if you visited a page that an attacker has carefully crafted, the page could cause your browser to bounce a TRACE request against some site for which you have authentication cookies. The result of the TRACE will be a copy of what was sent to the site, which will therefore include those cookies or authentication data. The carefully crafted page can then pass that information on to the attacker.&lt;br /&gt;
&lt;br /&gt;
TRACE requests can be disabled by making a change to the Apache server configuration. Unfortunately it is not possible to do this using the Limit directive since the processing for the TRACE request skips this authorisation checking. Instead the following lines can be added which make use of the mod_rewrite module.&lt;br /&gt;
&lt;br /&gt;
    RewriteEngine On &lt;br /&gt;
    RewriteCond %{REQUEST_METHOD} ^TRACE &lt;br /&gt;
    RewriteRule .* - [F] &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Although the particular attack highlighted made use of the TRACE functionality to grab authentication details, this isn&#039;t a vulnerability in TRACE, or in the Apache web server.&#039;&#039;&#039; The same browser functionality that permits the published attack can be used for different attacks even if TRACE is disabled on the remote web server. For example an attacker could create a carefully crafted page that when visited submits a hidden request to some arbitrary site through your browser, grabs the result and passes it to the attacker.&lt;br /&gt;
&lt;br /&gt;
== Performance Tuning ==&lt;br /&gt;
&lt;br /&gt;
See [[Linux Performance Tuning]]&lt;br /&gt;
&lt;br /&gt;
[http://www.linuxjournal.com/article/6041 Apache and Firewall Performance Tips from the Xenu.net Masters]&lt;br /&gt;
&lt;br /&gt;
=== CentOS January 2009 Thread ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
-------- Original Message --------&lt;br /&gt;
Subject: 	[CentOS] Apache Server Tuning for Performance&lt;br /&gt;
Date: 	Wed, 21 Jan 2009 00:09:38 +0530&lt;br /&gt;
From: 	linux-crazy &amp;lt;hicheerup@gmail.com&amp;gt;&lt;br /&gt;
Reply-To: 	CentOS mailing list &amp;lt;centos@centos.org&amp;gt;&lt;br /&gt;
To: 	CentOS mailing list &amp;lt;centos@centos.org&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Hi all,&lt;br /&gt;
&lt;br /&gt;
I am facing  facing performance issues with our web servers which is&lt;br /&gt;
working for concurrent  250 requests properly and then stops&lt;br /&gt;
responding when the requests are more than 250 .&lt;br /&gt;
&lt;br /&gt;
The current configuration parameters are as follows :&lt;br /&gt;
&lt;br /&gt;
apachectl -version&lt;br /&gt;
Server version: Apache/2.0.52&lt;br /&gt;
Server built:   Jan 30 2007 09:56:16&lt;br /&gt;
&lt;br /&gt;
Kernel : 2.6.9-55.ELsmp #1 SMP Fri Apr 20 16:36:54 EDT 2007 x86_64&lt;br /&gt;
x86_64 x86_64 GNU/Linux&lt;br /&gt;
&lt;br /&gt;
Server Hardware :&lt;br /&gt;
MAIN MEMORY&lt;br /&gt;
(i) Memory Size 4 GB  Dual-Core Intel 5160 processors.&lt;br /&gt;
&lt;br /&gt;
httpd.conf&lt;br /&gt;
&lt;br /&gt;
Timeout 300&lt;br /&gt;
KeepAlive On&lt;br /&gt;
MaxKeepAliveRequests 1000&lt;br /&gt;
KeepAliveTimeout 150&lt;br /&gt;
&lt;br /&gt;
## Server-Pool Size Regulation (MPM specific)&lt;br /&gt;
# prefork MPM&lt;br /&gt;
&lt;br /&gt;
# StartServers: number of server processes to start&lt;br /&gt;
# MinSpareServers: minimum number of server processes which are kept spare&lt;br /&gt;
# MaxSpareServers: maximum number of server processes which are kept spare&lt;br /&gt;
# ServerLimit: maximum value for MaxClients for the lifetime of the server&lt;br /&gt;
# MaxClients: maximum number of server processes allowed to start&lt;br /&gt;
# MaxRequestsPerChild: maximum number of requests a server process serves&lt;br /&gt;
&lt;br /&gt;
&amp;lt;IfModule prefork.c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
StartServers       8&lt;br /&gt;
MinSpareServers    5&lt;br /&gt;
MaxSpareServers   20&lt;br /&gt;
ServerLimit      251&lt;br /&gt;
MaxClients       251&lt;br /&gt;
MaxRequestsPerChild  4000&lt;br /&gt;
&amp;lt;/IfModule&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# worker MPM&lt;br /&gt;
# StartServers: initial number of server processes to start&lt;br /&gt;
# MaxClients: maximum number of simultaneous client connections&lt;br /&gt;
# MinSpareThreads: minimum number of worker threads which are kept spare&lt;br /&gt;
# MaxSpareThreads: maximum number of worker threads which are kept spare&lt;br /&gt;
# ThreadsPerChild: constant number of worker threads in each server process&lt;br /&gt;
# MaxRequestsPerChild: maximum number of requests a server process serves&lt;br /&gt;
&amp;lt;IfModule worker.c&amp;gt;&lt;br /&gt;
StartServers         2&lt;br /&gt;
MaxClients        150&lt;br /&gt;
MinSpareThreads     25&lt;br /&gt;
MaxSpareThreads     75&lt;br /&gt;
ThreadsPerChild     25&lt;br /&gt;
MaxRequestsPerChild  0&lt;br /&gt;
&amp;lt;/IfModule&amp;gt;&lt;br /&gt;
&lt;br /&gt;
     I want to  know about  the difference  between worker MPM and&lt;br /&gt;
Prefork MPM , how to find out which one will be used by my apache&lt;br /&gt;
server and  the recommended one   for highly loaded server.If some one&lt;br /&gt;
provide me the link that best explains above two comparison also  be&lt;br /&gt;
very use full.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 Can any one guide me tuning to be  done for the maximum utilization&lt;br /&gt;
of the Resources  and better performance of the Servers.&lt;br /&gt;
&lt;br /&gt;
 Regards,&lt;br /&gt;
lingu&lt;br /&gt;
_______________________________________________&lt;br /&gt;
CentOS mailing list&lt;br /&gt;
CentOS@centos.org&lt;br /&gt;
http://lists.centos.org/mailman/listinfo/centos&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Only use prefork MPM (worker is for Win32, AFAIK).&lt;br /&gt;
&lt;br /&gt;
If you set ServerLimit to 251, that&#039;s the limit.&lt;br /&gt;
Set ServerLimit and MaxClients to the same value.&lt;br /&gt;
(Larger than 250)&lt;br /&gt;
OK?&lt;br /&gt;
And take a couple of minutes to study the apache documentation. It&#039;s  &lt;br /&gt;
actually quite good and tranlated into many languages...&lt;br /&gt;
&lt;br /&gt;
BUT: what your server is being able to handle also depends on what you  &lt;br /&gt;
actually serve (PHP/JSP/Servelets/Perl/whatever!&lt;br /&gt;
&lt;br /&gt;
This is usually not a problem that is easily described and solved in  &lt;br /&gt;
two sentences.&lt;br /&gt;
&lt;br /&gt;
Rainer&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Increase your MaxClients configuration, also enable if you&lt;br /&gt;
haven&#039;t already the server-status module and monitor the&lt;br /&gt;
server via http://&amp;lt;your server name&amp;gt;/server-status it will&lt;br /&gt;
show how many workers are busy and what they are doing.&lt;br /&gt;
&lt;br /&gt;
As for which to use, prefork is the old forked method of&lt;br /&gt;
doing things, the other uses threads. Depending on what kind&lt;br /&gt;
of application your running on top of apache, if it is not&lt;br /&gt;
thread safe(at some point many PHP modules were not thread&lt;br /&gt;
safe), you may want to use prefork. Otherwise you can use&lt;br /&gt;
the threading model.&lt;br /&gt;
&lt;br /&gt;
If your not sure I&#039;d say stick to prefork to be safe until&lt;br /&gt;
you can determine for sure that threading is safe.&lt;br /&gt;
&lt;br /&gt;
nate&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Most list members would likely advise sticking with the prefork &lt;br /&gt;
configuration.  Without knowing what kind of applications you are &lt;br /&gt;
running on your webserver, I wouldn&#039;t suggest changing it.&lt;br /&gt;
&lt;br /&gt;
Merely increasing the number of workers might make performance worse.&lt;br /&gt;
&lt;br /&gt;
Use ps or top to figure out how much each apache worker is using. Then &lt;br /&gt;
decide how much ram you want to dedicate on your server to Apache, &lt;br /&gt;
without going into swap. (Over-allocating and then paging out memory &lt;br /&gt;
will only make performance much worse.) For example, if I have 2G or &lt;br /&gt;
ram, and I want 1.5 for apache workers, my average apache worker size &lt;br /&gt;
(resident memory) is 65MB, then I have room for 23 workers. (1024 * 1.5 &lt;br /&gt;
) / 65. (There are more accurate ways to calculate this usage, like &lt;br /&gt;
taking shared memory into account.)&lt;br /&gt;
&lt;br /&gt;
Upgrading the ram in your web server is a pretty fast interim solution.&lt;br /&gt;
&lt;br /&gt;
Consider your application performance, too. The longer a request in your &lt;br /&gt;
application takes, the more workers are in use on your web server, &lt;br /&gt;
taking up more memory. If you have long-running queries in your &lt;br /&gt;
database, take care of those first.&lt;br /&gt;
&lt;br /&gt;
Good luck&lt;br /&gt;
&lt;br /&gt;
Jed&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Jed Reynolds wrote:&lt;br /&gt;
&amp;gt; &lt;br /&gt;
&amp;gt; Merely increasing the number of workers might make performance worse.&lt;br /&gt;
&amp;gt; &lt;br /&gt;
&amp;gt; Use ps or top to figure out how much each apache worker is using. Then &lt;br /&gt;
&amp;gt; decide how much ram you want to dedicate on your server to Apache, &lt;br /&gt;
&amp;gt; without going into swap. (Over-allocating and then paging out memory &lt;br /&gt;
&amp;gt; will only make performance much worse.)  For example, if I have 2G or&lt;br /&gt;
&amp;gt; ram, and I want 1.5 for apache workers, my average apache worker size &lt;br /&gt;
&amp;gt; (resident memory) is 65MB, then I have room for 23 workers. (1024 * 1.5 &lt;br /&gt;
&amp;gt; ) / 65. (There are more accurate ways to calculate this usage, like &lt;br /&gt;
&amp;gt; taking shared memory into account.)&lt;br /&gt;
&lt;br /&gt;
Pay attention to shared memory when doing this.  A freshly-forked &lt;br /&gt;
process shares virtually all RAM with its parent.  How much and how &lt;br /&gt;
quickly this changes varies wildly with the application type and &lt;br /&gt;
activity that causes the child&#039;s data to become unique.  With some types &lt;br /&gt;
of applications (especially mod_perl) you may want to tune down the &lt;br /&gt;
number of hits each child services to increase memory sharing.  Also, if &lt;br /&gt;
you are running external cgi programs you must take them into account.&lt;br /&gt;
&lt;br /&gt;
&amp;gt; Upgrading the ram in your web server is a pretty fast interim solution.&lt;br /&gt;
&amp;gt; &lt;br /&gt;
&amp;gt; Consider your application performance, too. The longer a request in your &lt;br /&gt;
&amp;gt; application takes, the more workers are in use on your web server, &lt;br /&gt;
&amp;gt; taking up more memory. If you have long-running queries in your &lt;br /&gt;
&amp;gt; database, take care of those first.&lt;br /&gt;
&lt;br /&gt;
You may also have to turn off or tune down the HTTP 1.1 connection &lt;br /&gt;
keepalives, trading the time it takes to establish a new connection for &lt;br /&gt;
the RAM it takes to keep the associated process waiting for another &lt;br /&gt;
request from the same client.&lt;br /&gt;
&lt;br /&gt;
-- &lt;br /&gt;
   Les Mikesell&lt;br /&gt;
    lesmikesell@gmail.com&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Also take a look at apache alternatives like lighttpd and nginx. In certain&lt;br /&gt;
cases they do miracles.&lt;br /&gt;
&lt;br /&gt;
Jure Pečar&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
I don&#039;t know about lighttpd (our results were mixed) - but NGINX is  &lt;br /&gt;
really _very_ fast.&lt;br /&gt;
Last time I checked, it seems to be the fastest way to accelerate  &lt;br /&gt;
webpage-delivery on generic hardware and with OSS-software.&lt;br /&gt;
&lt;br /&gt;
But it&#039;s not a feature-monster like apache, so you still need that.&lt;br /&gt;
&lt;br /&gt;
Rainer&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Linux-crazy wrote on Wed, 21 Jan 2009 00:09:38 +0530:&lt;br /&gt;
&lt;br /&gt;
&amp;gt; KeepAliveTimeout 150&lt;br /&gt;
&lt;br /&gt;
My god, reduce this to 10 or 5.&lt;br /&gt;
&lt;br /&gt;
&amp;gt; ServerLimit      251&lt;br /&gt;
&amp;gt; MaxClients       251&lt;br /&gt;
&lt;br /&gt;
There&#039;s your limit. However, you should check with your hardware if upping &lt;br /&gt;
it is really desirable. With 4 GB I think you won&#039;t be able to handle much &lt;br /&gt;
more anyway.&lt;br /&gt;
&lt;br /&gt;
Kai&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Kai Schaetzl wrote:&lt;br /&gt;
&amp;gt; There&#039;s your limit. However, you should check with your hardware if upping &lt;br /&gt;
&amp;gt; it is really desirable. With 4 GB I think you won&#039;t be able to handle much &lt;br /&gt;
&amp;gt; more anyway.&lt;br /&gt;
&lt;br /&gt;
That really depends. If you only shove out static pages and have one or&lt;br /&gt;
two or three odd cgis on the machine, you can flatten down the httpd&lt;br /&gt;
binary quite a bit by throwing out unneeded modules.&lt;br /&gt;
&lt;br /&gt;
500 to 750 clients shouldn&#039;t be that much of a problem then ...&lt;br /&gt;
&lt;br /&gt;
Cheers,&lt;br /&gt;
&lt;br /&gt;
Ralph&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Ralph Angenendt wrote on Wed, 21 Jan 2009 10:52:59 +0100:&lt;br /&gt;
&lt;br /&gt;
&amp;gt; That really depends. If you only shove out static pages and have one or&lt;br /&gt;
&amp;gt; two or three odd cgis on the machine, you can flatten down the httpd&lt;br /&gt;
&amp;gt; binary quite a bit by throwing out unneeded modules.&lt;br /&gt;
&amp;gt; &lt;br /&gt;
&amp;gt; 500 to 750 clients shouldn&#039;t be that much of a problem then ...&lt;br /&gt;
&lt;br /&gt;
Sure it depends ;-) I do serve dynamic pages but by removing the really &lt;br /&gt;
unnecessary modules I made my httpds much faster (especially on pipelined &lt;br /&gt;
image downloads) and they only have some 10 MB (RES) per worker.&lt;br /&gt;
&lt;br /&gt;
But I would expect that they are running the default set of modules.&lt;br /&gt;
&lt;br /&gt;
Kai&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Kai Schaetzl schrieb:&lt;br /&gt;
&amp;gt; Ralph Angenendt wrote on Wed, 21 Jan 2009 10:52:59 +0100:&lt;br /&gt;
&amp;gt;&lt;br /&gt;
&amp;gt;   &lt;br /&gt;
&amp;gt;&amp;gt; That really depends. If you only shove out static pages and have one or&lt;br /&gt;
&amp;gt;&amp;gt; two or three odd cgis on the machine, you can flatten down the httpd&lt;br /&gt;
&amp;gt;&amp;gt; binary quite a bit by throwing out unneeded modules.&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt; 500 to 750 clients shouldn&#039;t be that much of a problem then ...&lt;br /&gt;
&amp;gt;&amp;gt;     &lt;br /&gt;
&amp;gt;&lt;br /&gt;
&amp;gt; Sure it depends ;-) I do serve dynamic pages but by removing the really &lt;br /&gt;
&amp;gt; unnecessary modules I made my httpds much faster (especially on pipelined &lt;br /&gt;
&amp;gt; image downloads) and they only have some 10 MB (RES) per worker.&lt;br /&gt;
&amp;gt;&lt;br /&gt;
&amp;gt; But I would expect that they are running the default set of modules.&lt;br /&gt;
&amp;gt;&lt;br /&gt;
&amp;gt; Kai&lt;br /&gt;
&amp;gt;&lt;br /&gt;
&amp;gt;   &lt;br /&gt;
&lt;br /&gt;
If you can separate-out the images to a specific URL (img.domain.com)&lt;br /&gt;
and put them all in the same directory, you can use NGINX to serve them.&lt;br /&gt;
Of course, the actual transfer-speed will not increase much - but&lt;br /&gt;
latency will go down to the absolute minimum.&lt;br /&gt;
And latency is what makes a page appear &amp;quot;fast&amp;quot; or &amp;quot;slow&amp;quot; to customers.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Ralph Angenendt wrote:&lt;br /&gt;
&amp;gt; Kai Schaetzl wrote:&lt;br /&gt;
&amp;gt;&amp;gt; There&#039;s your limit. However, you should check with your hardware if upping&lt;br /&gt;
&amp;gt;&amp;gt; it is really desirable. With 4 GB I think you won&#039;t be able to handle much&lt;br /&gt;
&amp;gt;&amp;gt; more anyway.&lt;br /&gt;
&amp;gt;&lt;br /&gt;
&amp;gt; That really depends. If you only shove out static pages and have one or&lt;br /&gt;
&amp;gt; two or three odd cgis on the machine, you can flatten down the httpd&lt;br /&gt;
&amp;gt; binary quite a bit by throwing out unneeded modules.&lt;br /&gt;
&amp;gt;&lt;br /&gt;
&amp;gt; 500 to 750 clients shouldn&#039;t be that much of a problem then ...&lt;br /&gt;
&lt;br /&gt;
Yeah gotta monitor it.. just checked in on some servers I ran at&lt;br /&gt;
my last company and the front end proxies (99% mod_proxy) seem to&lt;br /&gt;
peak out traffic wise at about 230 workers. For no other reason other&lt;br /&gt;
than because I could each proxy has 8 apache instances running(4 for&lt;br /&gt;
HTTP 4 for HTTPS). CPU usage peaks at around 3%(dual proc single core),&lt;br /&gt;
memory usage around 800MB. About 100 idle workers. Keepalive was set&lt;br /&gt;
to 300 seconds due to poor application design.&lt;br /&gt;
&lt;br /&gt;
One set of back end apache servers peaks traffic wise at around 100&lt;br /&gt;
active workers, though memory usage was higher, around 2GB because&lt;br /&gt;
of mod_fcgid running ruby on rails. CPU usage seems to be at around&lt;br /&gt;
25%(dual proc quad core) for that one application.&lt;br /&gt;
&lt;br /&gt;
Each back end application had it&#039;s own dedicated apache instance(11&lt;br /&gt;
apps) for maximum stability/best performance monitoring. The bulk&lt;br /&gt;
of them ran on the same physical hardware though.&lt;br /&gt;
&lt;br /&gt;
Traffic routing was handled by a combination of F5 load balancers&lt;br /&gt;
and the apache servers previously mentioned(F5 iRules were too slow&lt;br /&gt;
and F5&#039;s TMM was not scalable at the time).&lt;br /&gt;
&lt;br /&gt;
nate&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt; &lt;br /&gt;
&amp;gt; &amp;gt; KeepAliveTimeout 150&lt;br /&gt;
&amp;gt; &lt;br /&gt;
&amp;gt;reduce this to 10 or 5.&lt;br /&gt;
&amp;gt; &lt;br /&gt;
&amp;gt; &lt;br /&gt;
&amp;gt; Kai&lt;br /&gt;
&amp;gt; &lt;br /&gt;
&amp;gt; --&lt;br /&gt;
&amp;gt; Kai Schätzl, Berlin, Germany&lt;br /&gt;
&lt;br /&gt;
Kai,&lt;br /&gt;
&lt;br /&gt;
what do you think about the &amp;quot;general Timeout&lt;br /&gt;
&lt;br /&gt;
it is set to 300&lt;br /&gt;
&lt;br /&gt;
ive never much thought about it, yet should we be consider and possible&lt;br /&gt;
reduce that one too?&lt;br /&gt;
&lt;br /&gt;
 - rh&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RobertH wrote on Wed, 21 Jan 2009 11:26:41 -0800:&lt;br /&gt;
&lt;br /&gt;
&amp;gt; what do you think about the &amp;quot;general Timeout&lt;br /&gt;
&amp;gt; &lt;br /&gt;
&amp;gt; it is set to 300&lt;br /&gt;
&amp;gt; &lt;br /&gt;
&amp;gt; ive never much thought about it, yet should we be consider and possible&lt;br /&gt;
&amp;gt; reduce that one too?&lt;br /&gt;
&lt;br /&gt;
I&#039;m using 120, but I don&#039;t think reducing this value has much impact.&lt;br /&gt;
&lt;br /&gt;
Kai&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Load Balancer ==&lt;br /&gt;
&lt;br /&gt;
Apache Load Balancer&lt;br /&gt;
&lt;br /&gt;
mod_proxy_balancer - Apache HTTP Server - mod_proxy_balancer - http://httpd.apache.org/docs/2.2/mod/mod_proxy_balancer.html&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;Proxy balancer://mycluster&amp;gt;&lt;br /&gt;
BalancerMember http://192.168.1.50:80&lt;br /&gt;
BalancerMember http://192.168.1.51:80&lt;br /&gt;
&amp;lt;/Proxy&amp;gt;&lt;br /&gt;
ProxyPass /test balancer://mycluster &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== User Directories ==&lt;br /&gt;
&lt;br /&gt;
Default:&lt;br /&gt;
 UserDir public_html &lt;br /&gt;
&lt;br /&gt;
Results in:&lt;br /&gt;
 ~/public_html/&lt;br /&gt;
&lt;br /&gt;
To disable user directories:&lt;br /&gt;
 UserDir disabled&lt;br /&gt;
&lt;br /&gt;
Ubuntu user dir config:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        UserDir public_html&lt;br /&gt;
        UserDir disabled root&lt;br /&gt;
&lt;br /&gt;
        &amp;lt;Directory /home/*/public_html&amp;gt;&lt;br /&gt;
                AllowOverride FileInfo AuthConfig Limit Indexes&lt;br /&gt;
                Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec&lt;br /&gt;
                &amp;lt;Limit GET POST OPTIONS&amp;gt;&lt;br /&gt;
                        Order allow,deny&lt;br /&gt;
                        Allow from all&lt;br /&gt;
                &amp;lt;/Limit&amp;gt;&lt;br /&gt;
                &amp;lt;LimitExcept GET POST OPTIONS&amp;gt;&lt;br /&gt;
                        Order deny,allow&lt;br /&gt;
                        Deny from all&lt;br /&gt;
                &amp;lt;/LimitExcept&amp;gt;&lt;br /&gt;
        &amp;lt;/Directory&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* Per-user web directories - Apache HTTP Server - http://httpd.apache.org/docs/2.2/howto/public_html.html&lt;br /&gt;
* mod_userdir - Apache HTTP Server - http://httpd.apache.org/docs/2.2/mod/mod_userdir.html#userdir&lt;br /&gt;
&lt;br /&gt;
== Minimal Memory Instance ==&lt;br /&gt;
&lt;br /&gt;
Assuming running prefork module (check with &#039;apache -l&#039;):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
KeepAlive off&lt;br /&gt;
&lt;br /&gt;
&amp;lt;IfModule mpm_prefork_module&amp;gt;&lt;br /&gt;
StartServers          2&lt;br /&gt;
MinSpareServers       2&lt;br /&gt;
MaxSpareServers      5&lt;br /&gt;
ServerLimit          20&lt;br /&gt;
MaxClients           20&lt;br /&gt;
MaxRequestsPerChild  10000&lt;br /&gt;
&amp;lt;/IfModule&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* Running Apache On A Memory-Constrained VPS | Kalzumeus Software - http://www.kalzumeus.com/2010/06/19/running-apache-on-a-memory-constrained-vps/&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
TODO See:&lt;br /&gt;
*  http://wiki.vpslink.com/Low_memory_MySQL_/_Apache_configurations&lt;br /&gt;
* http://www.narga.net/optimizing-apachephpmysql-low-memory-server/&lt;br /&gt;
&lt;br /&gt;
== LDAP Authentication ==&lt;br /&gt;
&lt;br /&gt;
 # Red Hat / RHEL&lt;br /&gt;
 sudo yum install mod_ldap&lt;br /&gt;
 # allow ldap to connect through selinux:&lt;br /&gt;
 sudo setsebool -P httpd_can_network_connect on&lt;br /&gt;
&lt;br /&gt;
 mod_ldap - Apache HTTP Server Version 2.4&lt;br /&gt;
 https://httpd.apache.org/docs/2.4/mod/mod_ldap.html&lt;br /&gt;
&lt;br /&gt;
== Issues ==&lt;br /&gt;
&lt;br /&gt;
=== Could not reliably determine domain name ===&lt;br /&gt;
&lt;br /&gt;
Warning:&lt;br /&gt;
 Could not reliably determine the server&#039;s fully qualified domain name&lt;br /&gt;
&lt;br /&gt;
Solution:&lt;br /&gt;
* Force ServerName in apache configs [http://askubuntu.com/questions/256013/could-not-reliably-determine-the-servers-fully-qualified-domain-name]&lt;br /&gt;
 ServerName localhost&lt;br /&gt;
&lt;br /&gt;
=== client denied by server configuration ===&lt;br /&gt;
&lt;br /&gt;
browser:&lt;br /&gt;
 403 Forbidden - You don&#039;t have permission to access / on this server.&lt;br /&gt;
&lt;br /&gt;
Error:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
==&amp;gt; httpd/default-error_log &amp;lt;==&lt;br /&gt;
[Mon Sep 01 21:42:02.273169 2014] [authz_core:error] [pid 11221] [client 174.52.47.54:50675] AH01630: client denied by server configuration: /www/&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add Directory allow permissions: [http://stackoverflow.com/questions/19445686/ubuntu-server-apache-2-4-6-client-denied-by-server-configuration-php-fpm]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
DocumentRoot /www&lt;br /&gt;
&amp;lt;Directory /www&amp;gt;&lt;br /&gt;
  Order allow,deny&lt;br /&gt;
  Allow from all&lt;br /&gt;
&amp;lt;/Directory&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or this worked better for me: [http://stackoverflow.com/questions/19445686/ubuntu-server-apache-2-4-6-client-denied-by-server-configuration-php-fpm] [https://mikegriffin.ie/blog/20140130-authz-core-error-client-denied-by-server-configuration/]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
DocumentRoot /www&lt;br /&gt;
&amp;lt;Directory /www&amp;gt;&lt;br /&gt;
  Require all granted&lt;br /&gt;
&amp;lt;/Directory&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Actually this just worked on the latest Ubuntu system:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;Directory /www/&amp;gt;&lt;br /&gt;
        Options Indexes FollowSymLinks&lt;br /&gt;
        AllowOverride None&lt;br /&gt;
        Require all granted&lt;br /&gt;
&amp;lt;/Directory&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* ClientDeniedByServerConfiguration - Httpd Wiki - https://wiki.apache.org/httpd/ClientDeniedByServerConfiguration&lt;br /&gt;
&lt;br /&gt;
=== permissions missing component path ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
==&amp;gt; httpd/default-error_log &amp;lt;==&lt;br /&gt;
[Mon Sep 01 21:50:09.256120 2014] [core:error] [pid 11511] (13)Permission denied: [client 174.52.47.54:50744] AH00035: access to \&lt;br /&gt;
/index.html denied (filesystem path &#039;/www/index.html&#039;) because search permissions are missing on a component of the path&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== keywords ==&lt;br /&gt;
&lt;br /&gt;
[[Category:Linux]]&lt;br /&gt;
[[Category:Web Development ‎]]&lt;br /&gt;
[[Category:Web]]&lt;br /&gt;
[[Category:HTML]]&lt;br /&gt;
[[Category:Internet]]&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=Apache&amp;diff=9862</id>
		<title>Apache</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=Apache&amp;diff=9862"/>
		<updated>2026-04-27T19:13:44Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: /* .htaccess */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{subpages}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Apache]]&lt;br /&gt;
&lt;br /&gt;
== Install Apache ==&lt;br /&gt;
&lt;br /&gt;
 # Debian / Ubuntu&lt;br /&gt;
 sudo apt install apache2&lt;br /&gt;
&lt;br /&gt;
 # Redhat&lt;br /&gt;
 yum install httpd&lt;br /&gt;
&lt;br /&gt;
== Virtual Hosting ==&lt;br /&gt;
 touch /etc/httpd/conf.d/virtual.conf&lt;br /&gt;
&lt;br /&gt;
Virtual Host Configuration File:&lt;br /&gt;
 /etc/httpd/conf.d/virtual.conf:&lt;br /&gt;
&lt;br /&gt;
HTTP Virtual Host&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
NameVirtualHost *:80&lt;br /&gt;
&lt;br /&gt;
&amp;lt;VirtualHost *:80&amp;gt;&lt;br /&gt;
    ServerName t0e.org&lt;br /&gt;
    ServerAlias www.t0e.org&lt;br /&gt;
&lt;br /&gt;
    DocumentRoot /www&lt;br /&gt;
&lt;br /&gt;
    ServerAdmin admin@t0e.org&lt;br /&gt;
    ErrorLog logs/t0e.org-error_log&lt;br /&gt;
    CustomLog logs/t0e.org-access_log common&lt;br /&gt;
&amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;VirtualHost *:80&amp;gt;&lt;br /&gt;
    ServerName www2.t0e.org&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
HTTPS Virtual Host:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
NameVirtualHost *:443&lt;br /&gt;
&lt;br /&gt;
&amp;lt;VirtualHost *:443&amp;gt;&lt;br /&gt;
    ServerName t0e.org&lt;br /&gt;
    ServerAlias www.t0e.org&lt;br /&gt;
&lt;br /&gt;
    # SSL Enabled:&lt;br /&gt;
    SSLEngine on&lt;br /&gt;
    SSLCertificateFile /etc/t0e.org.pem&lt;br /&gt;
&lt;br /&gt;
    # If using a godaddy certificate chain:&lt;br /&gt;
    #SSLCertificateFile /etc/contractpal.net.pem&lt;br /&gt;
    #SSLCertificateKeyFile /etc/contractpal.net.pem&lt;br /&gt;
    #SSLCertificateChainFile /etc/contractpal.net.pem&lt;br /&gt;
&lt;br /&gt;
    #Forwarding Traffic&lt;br /&gt;
    # RewriteEngine on&lt;br /&gt;
    # RewriteRule ^(/.*)  http://localhost:8080/$1   [P]&lt;br /&gt;
&lt;br /&gt;
    DocumentRoot /www&lt;br /&gt;
&lt;br /&gt;
    ServerAdmin admin@t0e.org&lt;br /&gt;
    ErrorLog logs/t0e.org-error_log&lt;br /&gt;
    CustomLog logs/t0e.org-access_log common&lt;br /&gt;
&amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
*[http://www.onlamp.com/pub/a/apache/2005/02/17/apacheckbk.html A Day in the Life of #Apache: Running Name-Based SSL Virtual Hosts in Apache]&lt;br /&gt;
*[http://httpd.apache.org/docs/1.3/vhosts/name-based.html Apache: Name-based Virtual Host Support]&lt;br /&gt;
*[http://www.networkworld.com/columnists/2006/011606internet.html Getting SSL to work across virtual hosts in Apache]&lt;br /&gt;
&lt;br /&gt;
== CentOS common configuration changes ==&lt;br /&gt;
&lt;br /&gt;
Keep alives:&lt;br /&gt;
 # KeepAlive Off&lt;br /&gt;
 KeepAlive On&lt;br /&gt;
&lt;br /&gt;
Hide Apache version (in likely in /etc/apache2/conf-enabled/security.conf):&lt;br /&gt;
 # ServerTokens Full&lt;br /&gt;
 ServerTokens Prod&lt;br /&gt;
&lt;br /&gt;
 # ServerSignature On&lt;br /&gt;
 ServerSignature Off&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
PHP config in /etc/php.ini (now likely in /etc/php/8.3/apache2/php.ini):&lt;br /&gt;
 expose_php = Off&lt;br /&gt;
&lt;br /&gt;
==Forwarding / Rewriting / Proxying Traffic==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
NameVirtualHost *:80&lt;br /&gt;
&amp;lt;VirtualHost *:80&amp;gt;&lt;br /&gt;
    ServerName t0e.org&lt;br /&gt;
    ServerAlias www.t0e.org&lt;br /&gt;
&lt;br /&gt;
    #Forwarding Traffic&lt;br /&gt;
    RewriteEngine on&lt;br /&gt;
    RewriteRule ^(/.*)  http://localhost:8080/$1   [P]&lt;br /&gt;
&lt;br /&gt;
    ServerAdmin admin@t0e.org&lt;br /&gt;
    ErrorLog logs/t0e.org-error_log&lt;br /&gt;
    CustomLog logs/t0e.org-access_log common&lt;br /&gt;
&amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Apache module mod_rewrite - RewriteRule - http://httpd.apache.org/docs/1.3/mod/mod_rewrite.html#RewriteRule&lt;br /&gt;
 a2enmod rewrite&lt;br /&gt;
&lt;br /&gt;
 a2enmod proxy_http&lt;br /&gt;
&lt;br /&gt;
[http://httpd.apache.org/docs/1.3/mod/mod_rewrite.html Module mod_rewrite - URL Rewriting Engine]:&lt;br /&gt;
*RewriteEngine&lt;br /&gt;
*RewriteCond&lt;br /&gt;
*RewriteRule&lt;br /&gt;
&lt;br /&gt;
[http://httpd.apache.org/docs/1.3/misc/rewriteguide.html Apache 1.3 - URL Rewriting Guide]&lt;br /&gt;
&lt;br /&gt;
[http://httpd.apache.org/docs/1.3/mod/mod_proxy.html Apache module mod_proxy]:&lt;br /&gt;
*ProxyPass&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;VirtualHost *:80&amp;gt;&lt;br /&gt;
    ServerName home.burgenerfamily.com&lt;br /&gt;
    DocumentRoot /www/home&lt;br /&gt;
    &amp;lt;Directory /www/home&amp;gt;&lt;br /&gt;
        Options FollowSymLinks&lt;br /&gt;
        RewriteEngine On&lt;br /&gt;
        # allow existing files and directories to pass through&lt;br /&gt;
        RewriteCond %{REQUEST_FILENAME} !-f&lt;br /&gt;
        RewriteCond %{REQUEST_FILENAME} !-d&lt;br /&gt;
        #RewriteRule ^static - [L,NC] &lt;br /&gt;
        #RewriteCond %{REQUEST_FILENAME} !^favicon.ico$&lt;br /&gt;
        #RewriteCond %{REQUEST_FILENAME} !^static/&lt;br /&gt;
        #RewriteRule ^(.+)$ /index.php?title=$1 [PT,L,QSA]&lt;br /&gt;
        RewriteRule ^(.*)$ /index.php/$1 [L,QSA]&lt;br /&gt;
    &amp;lt;/Directory&amp;gt;&lt;br /&gt;
    ErrorLog logs/home.burgenerfamily.com-error_log&lt;br /&gt;
    CustomLog logs/home.burgenerfamily.com-access_log common&lt;br /&gt;
&amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Proxy Pass ==&lt;br /&gt;
&lt;br /&gt;
Enable Proxy: [https://www.digitalocean.com/community/tutorials/how-to-use-apache-as-a-reverse-proxy-with-mod_proxy-on-ubuntu-16-04]&lt;br /&gt;
 sudo a2enmod proxy&lt;br /&gt;
 sudo a2enmod proxy_http&lt;br /&gt;
 systemctl restart apache2&lt;br /&gt;
&lt;br /&gt;
Similar to forwarding, but takes care of redirects:&lt;br /&gt;
&lt;br /&gt;
   ProxyPass         /mirror/foo/ http://foo.com/&lt;br /&gt;
   ProxyPassReverse  /mirror/foo/ http://foo.com/&lt;br /&gt;
&lt;br /&gt;
Suppose the local server has address http://wibble.org/; then&lt;br /&gt;
&lt;br /&gt;
   ProxyPass         /mirror/foo/ http://foo.com/&lt;br /&gt;
   ProxyPassReverse  /mirror/foo/ http://foo.com/&lt;br /&gt;
&lt;br /&gt;
will not only cause a local request for the &amp;lt;http://wibble.org/mirror/foo/bar&amp;gt; to be internally converted into a proxy request to &amp;lt;http://foo.com/bar&amp;gt; (the functionality ProxyPass provides here). It also takes care of redirects the server foo.com sends: when http://foo.com/bar is redirected by him to http://foo.com/quux Apache adjusts this to http://wibble.org/mirror/foo/quux before forwarding the HTTP redirect response to the client. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;VirtualHost *:80&amp;gt;&lt;br /&gt;
    ServerName wiki.oeey.com&lt;br /&gt;
&lt;br /&gt;
    # Reverse Proxy&lt;br /&gt;
    ProxyPass         / http://localhost:8080/&lt;br /&gt;
    ProxyPassReverse  / http://localhost:8080/&lt;br /&gt;
&lt;br /&gt;
    ServerAdmin website@oeey.com&lt;br /&gt;
    ErrorLog logs/wiki-error_log&lt;br /&gt;
    CustomLog logs/wiki-access_log common&lt;br /&gt;
&amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Proxy Pass to Jenkins: [https://wiki.jenkins-ci.org/display/JENKINS/Running+Jenkins+behind+Apache]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
NameVirtualHost *:80&lt;br /&gt;
&amp;lt;VirtualHost *:80&amp;gt;&lt;br /&gt;
    ServerName jenkins.oeey.com&lt;br /&gt;
&lt;br /&gt;
    #Forwarding Traffic&lt;br /&gt;
    #RewriteEngine on&lt;br /&gt;
    #RewriteRule ^(/.*)  http://localhost:8080/$1   [P]&lt;br /&gt;
&lt;br /&gt;
    ProxyPass         /  http://localhost:8080/ nocanon&lt;br /&gt;
    ProxyPassReverse  /  http://localhost:8080/&lt;br /&gt;
    ProxyRequests     Off&lt;br /&gt;
    ProxyPreserveHost On&lt;br /&gt;
    AllowEncodedSlashes NoDecode&lt;br /&gt;
&lt;br /&gt;
    # Local reverse proxy authorization override&lt;br /&gt;
    # Most unix distribution deny proxy by default (ie /etc/apache2/mods-enabled/proxy.conf in Ubuntu)&lt;br /&gt;
    &amp;lt;Proxy http://localhost:8080/*&amp;gt;&lt;br /&gt;
        Order deny,allow&lt;br /&gt;
        Allow from all&lt;br /&gt;
    &amp;lt;/Proxy&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    ServerAdmin admin@oeey.com&lt;br /&gt;
    ErrorLog logs/jenkins.oeey.com-error_log&lt;br /&gt;
    CustomLog logs/jenkins.oeey.com-access_log common&lt;br /&gt;
&amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Proxy Pass HTTPS ===&lt;br /&gt;
&lt;br /&gt;
Proxy Pass to Jenkins:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
NameVirtualHost *:443&lt;br /&gt;
&amp;lt;VirtualHost *:443&amp;gt;&lt;br /&gt;
    ServerName jenkins.oeey.com&lt;br /&gt;
&lt;br /&gt;
    # Enable SSL Support&lt;br /&gt;
    SSLEngine on&lt;br /&gt;
    SSLCertificateFile /etc/pki/tls/certs/localhost.crt&lt;br /&gt;
    SSLCertificateKeyFile /etc/pki/tls/private/localhost.key&lt;br /&gt;
&lt;br /&gt;
    #Forwarding Traffic&lt;br /&gt;
    #RewriteEngine on&lt;br /&gt;
    #RewriteRule ^(/.*)  http://localhost:8080/$1   [P]&lt;br /&gt;
&lt;br /&gt;
    ProxyPass         /  http://localhost:8080/ nocanon&lt;br /&gt;
    ProxyPassReverse  /  http://localhost:8080/&lt;br /&gt;
    ProxyPassReverse  /  http://jenkins.oeey.com/&lt;br /&gt;
    ProxyRequests     Off&lt;br /&gt;
    ProxyPreserveHost On&lt;br /&gt;
    AllowEncodedSlashes NoDecode&lt;br /&gt;
    RequestHeader set X-Forwarded-Proto &amp;quot;http&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # Local reverse proxy authorization override&lt;br /&gt;
    # Most unix distribution deny proxy by default (ie /etc/apache2/mods-enabled/proxy.conf in Ubuntu)&lt;br /&gt;
    &amp;lt;Proxy http://localhost:8080/jenkins*&amp;gt;&lt;br /&gt;
        Order deny,allow&lt;br /&gt;
        Allow from all&lt;br /&gt;
    &amp;lt;/Proxy&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    ServerAdmin admin@oeey.com&lt;br /&gt;
    ErrorLog logs/jenkins.oeey.com-error_log&lt;br /&gt;
    CustomLog logs/jenkins.oeey.com-access_log common&lt;br /&gt;
&amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Redirect ==&lt;br /&gt;
&lt;br /&gt;
Redirect with URI intact:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
NameVirtualHost *:80&lt;br /&gt;
&amp;lt;VirtualHost *:80&amp;gt;&lt;br /&gt;
    ServerName test.oeey.com&lt;br /&gt;
    Redirect permanent / http://www.oeey.com/&lt;br /&gt;
&amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Redirect users to HTTPS with URI intact:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
NameVirtualHost *:80&lt;br /&gt;
&amp;lt;VirtualHost *:80&amp;gt;&lt;br /&gt;
    ServerName test.oeey.com&lt;br /&gt;
    Redirect permanent / https://test.oeey.com/&lt;br /&gt;
&amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Can be wrapped in Location (if you want)&lt;br /&gt;
 &amp;lt;Location /&amp;gt;&lt;br /&gt;
   Redirect permanent / https://test.oeey.com/&lt;br /&gt;
 &amp;lt;/Location&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Redirect with RewriteEngine with URI intact:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
NameVirtualHost *:80&lt;br /&gt;
&amp;lt;VirtualHost *:80&amp;gt;&lt;br /&gt;
    ServerName test.oeey.com&lt;br /&gt;
&lt;br /&gt;
    # Redirect HTTP to HTTPS&lt;br /&gt;
    RewriteEngine On&lt;br /&gt;
    RewriteCond %{HTTPS} off&lt;br /&gt;
    RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}&lt;br /&gt;
&amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Redirect removing URI:&lt;br /&gt;
 NameVirtualHost *:80&lt;br /&gt;
 &amp;lt;VirtualHost *:80&amp;gt;&lt;br /&gt;
     ServerName test.oeey.com&lt;br /&gt;
     RedirectMatch &amp;quot;(.*)&amp;quot; &amp;quot;http://www.oeey.com/&amp;quot;&lt;br /&gt;
 &amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[http://httpd.apache.org/docs/2.0/mod/mod_alias.html Apache Module mod_alias]:&lt;br /&gt;
*Alias&lt;br /&gt;
*Redirect&lt;br /&gt;
*RedirectPermanent&lt;br /&gt;
&lt;br /&gt;
== Default Directory Index ==&lt;br /&gt;
&lt;br /&gt;
to set the default pages to try and load (e.g. index.html, index.php):&lt;br /&gt;
 DirectoryIndex index.html index.php&lt;br /&gt;
&lt;br /&gt;
== Directory Index ==&lt;br /&gt;
&lt;br /&gt;
To show full file names:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  &amp;lt;Directory /&amp;gt;&lt;br /&gt;
    Options Indexes&lt;br /&gt;
    IndexOptions NameWidth=*&lt;br /&gt;
  &amp;lt;/Directory&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sample:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;Directory &amp;quot;/www&amp;quot;&amp;gt;&lt;br /&gt;
    Options Indexes FollowSymLinks&lt;br /&gt;
    IndexOptions FancyIndexing NameWidth=*&lt;br /&gt;
    AllowOverride None&lt;br /&gt;
    Require all granted&lt;br /&gt;
&amp;lt;/Directory&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Hide Apache and PHP Banner ==&lt;br /&gt;
&lt;br /&gt;
Hide PHP version (X-Powered-By) - Edit php.ini: [http://www.ducea.com/2006/06/16/apache-tips-tricks-hide-php-version-x-powered-by/]&lt;br /&gt;
 expose_php = Off&lt;br /&gt;
&lt;br /&gt;
Hide Apache version: [http://www.itsolutionskb.com/2008/10/hide-apache-information/]&lt;br /&gt;
 # ServerSignature On&lt;br /&gt;
 ServerSignature Off&lt;br /&gt;
 &lt;br /&gt;
 # ServerTokens Full&lt;br /&gt;
 ServerTokens Prod&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* Hide Apache ServerSignature/ServerTokens/PHP X-Powered-By - http://www.if-not-true-then-false.com/2009/howto-hide-and-modify-apache-server-information-serversignature-and-servertokens-and-hide-php-version-x-powered-by/&lt;br /&gt;
&lt;br /&gt;
== .htaccess ==&lt;br /&gt;
&lt;br /&gt;
Override configuration settings on a per directory (and sub directories) level with:&lt;br /&gt;
 .htaccess&lt;br /&gt;
&lt;br /&gt;
Allow override of all configuration options:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;Directory /&amp;gt;&lt;br /&gt;
  AllowOverride All&lt;br /&gt;
&amp;lt;/Directory&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example directory browsing in .htaccess:&lt;br /&gt;
 Options +indexes&lt;br /&gt;
&lt;br /&gt;
Redirect to index.php:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RewriteEngine on&lt;br /&gt;
RewriteCond %{REQUEST_FILENAME} !-f&lt;br /&gt;
RewriteCond %{REQUEST_FILENAME} !-d&lt;br /&gt;
RewriteRule ^(.*)$ /index.php?path=$1 [NC,L,QSA]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Allow from networks ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;Directory &amp;quot;...&amp;quot;&amp;gt;&lt;br /&gt;
    Order Deny,Allow&lt;br /&gt;
    Deny from all&lt;br /&gt;
    Allow from 127.0.0.0/255.255.255.0  10.10.0.0/16&lt;br /&gt;
&amp;lt;/Directory&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Log Files ==&lt;br /&gt;
&lt;br /&gt;
    ErrorLog logs/test.com-error_log&lt;br /&gt;
    CustomLog logs/test.com-access_log common&lt;br /&gt;
&lt;br /&gt;
Make sure the soft link exists:&lt;br /&gt;
 ln -s /var/log/httpd /etc/httpd/logs      # RHEL based&lt;br /&gt;
 ln -s /var/log/apache2 /etc/apache2/logs  # Debian Based&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*[http://httpd.apache.org/docs/2.0/logs.html Log Files v2.0]&lt;br /&gt;
*[http://httpd.apache.org/docs/1.3/logs.html#accesslog Log files v1.3]&lt;br /&gt;
&lt;br /&gt;
===Log HTTPS X-Forwarded-For===&lt;br /&gt;
[http://www.webmasterworld.com/forum92/6134.htm Log the X-Forwarded-For] header in apache...&lt;br /&gt;
 LogFormat &amp;quot;[X-Forwarded-For: %{X-Forwarded-For}i] %h %l %u %t \&amp;quot;%r\&amp;quot; %&amp;gt;s %b \&amp;quot;%{Referer}i\&amp;quot; \&amp;quot;%{User-Agent}i\&amp;quot;&amp;quot; combined&lt;br /&gt;
 LogFormat &amp;quot;[X-Forwarded-For: %{X-Forwarded-For}i] %h %l %u %t \&amp;quot;%r\&amp;quot; %&amp;gt;s %b&amp;quot; common&lt;br /&gt;
 LogFormat &amp;quot;%{Referer}i -&amp;gt; %U&amp;quot; referer&lt;br /&gt;
 LogFormat &amp;quot;%{User-agent}i&amp;quot; agent&lt;br /&gt;
&lt;br /&gt;
== PHP ==&lt;br /&gt;
&lt;br /&gt;
Install PHP with Apache: (Ubuntu)&lt;br /&gt;
 #apt-get install apache2 php5 libapache2-mod-php5&lt;br /&gt;
 apt-get install apache2 php libapache2-mod-php&lt;br /&gt;
&lt;br /&gt;
== Apache SSL ==&lt;br /&gt;
&lt;br /&gt;
Enable SSL with...&lt;br /&gt;
&lt;br /&gt;
Apache can do virtual SSL hosting!&lt;br /&gt;
&lt;br /&gt;
Install mod_ssl: [https://help.ubuntu.com/10.04/serverguide/httpd.html]&lt;br /&gt;
 # redhat / rhel&lt;br /&gt;
 sudo yum install mod_ssl&lt;br /&gt;
&lt;br /&gt;
 # debian / ubuntu&lt;br /&gt;
 sudo a2enmod ssl&lt;br /&gt;
 sudo a2ensite default-ssl&lt;br /&gt;
 systemctl reload apache2&lt;br /&gt;
&lt;br /&gt;
/etc/httpd/conf.d/ssl.conf:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LoadModule ssl_module modules/mod_ssl.so&lt;br /&gt;
Listen 443&lt;br /&gt;
AddType application/x-x509-ca-cert .crt&lt;br /&gt;
AddType application/x-pkcs7-crl    .crl&lt;br /&gt;
SSLPassPhraseDialog  builtin&lt;br /&gt;
SSLSessionCache         shmcb:/var/cache/mod_ssl/scache(512000)&lt;br /&gt;
SSLSessionCacheTimeout  300&lt;br /&gt;
SSLMutex default&lt;br /&gt;
SSLRandomSeed startup file:/dev/urandom  256&lt;br /&gt;
SSLRandomSeed connect builtin&lt;br /&gt;
SSLCryptoDevice builtin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: Delete the default VirtualHost section so we can add our own.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# SSL Configuration - from ssl.conf virtual host example&lt;br /&gt;
SSLEngine On&lt;br /&gt;
SSLProtocol all -SSLv2&lt;br /&gt;
SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM:+LOW&lt;br /&gt;
SSLCertificateFile /etc/pki/tls/certs/localhost.crt&lt;br /&gt;
SSLCertificateKeyFile /etc/pki/tls/private/localhost.key&lt;br /&gt;
&lt;br /&gt;
CustomLog logs/ssl_request_log \&lt;br /&gt;
          &amp;quot;%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \&amp;quot;%r\&amp;quot; %b&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# SSL configuration&lt;br /&gt;
SSLEngine On&lt;br /&gt;
SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL&lt;br /&gt;
SSLCertificateFile /etc/apache2/ssl/cert.crt&lt;br /&gt;
SSLCertificateKeyFile /etc/apache2/ssl/cert.key&lt;br /&gt;
SSLCertificateChainFile /etc/apache2/ssl/sf_bundle.crt&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
NameVirtualHost *:80&lt;br /&gt;
&amp;lt;VirtualHost *:80&amp;gt;&lt;br /&gt;
    ServerName default.t0e.org&lt;br /&gt;
&lt;br /&gt;
    # Redirect HTTP to HTTPS&lt;br /&gt;
    RewriteEngine On&lt;br /&gt;
    RewriteCond %{HTTPS} off&lt;br /&gt;
    RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}&lt;br /&gt;
&amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&lt;br /&gt;
NameVirtualHost *:443&lt;br /&gt;
&amp;lt;VirtualHost *:443&amp;gt;&lt;br /&gt;
    ServerName kb.t0e.org&lt;br /&gt;
&lt;br /&gt;
    # SSL Enabled: (only once in config file)&lt;br /&gt;
    SSLEngine on&lt;br /&gt;
    SSLCertificateFile /etc/t0e.org.pem&lt;br /&gt;
    SSLCertificateKeyFile /etc/t0e.org.pem&lt;br /&gt;
    SSLProtocol all -SSLv2&lt;br /&gt;
    SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM:+LOW&lt;br /&gt;
&lt;br /&gt;
    DocumentRoot /www&lt;br /&gt;
&lt;br /&gt;
    ServerAdmin admin@kb.t0e.org.com&lt;br /&gt;
    ErrorLog logs/kb.t0e.org-error_log&lt;br /&gt;
    CustomLog logs/kb.t0e.org-access_log common&lt;br /&gt;
&amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;VirtualHost *:443&amp;gt;&lt;br /&gt;
    ServerName wiki.t0e.org&lt;br /&gt;
&lt;br /&gt;
    DocumentRoot /www&lt;br /&gt;
&lt;br /&gt;
    ServerAdmin admin@wiki.t0e.org.com&lt;br /&gt;
    ErrorLog logs/wiki.t0e.org-error_log&lt;br /&gt;
    CustomLog logs/wiki.t0e.org-access_log common&lt;br /&gt;
&amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: With SSL, Apache will always use the first default virtual hosts&#039; certificate, so it only makes sense to define it there.&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
*[http://www.apache-ssl.org/ Apache SSL]&lt;br /&gt;
*[http://httpd.apache.org/docs/2.0/ssl/ Apache SSL/TLS Encryption Documentation]&lt;br /&gt;
*[http://httpd.apache.org/docs/2.0/mod/mod_ssl.html mod_ssl]&lt;br /&gt;
*[http://www.securityfocus.com/infocus/1818 Article: Apache 2 with SSL/TLS: Step-by-Step, Part 1]&lt;br /&gt;
*[http://www.vanemery.com/Linux/Apache/apache-SSL.html Van&#039;s Apache SSL/TLS mini-HOWTO]&lt;br /&gt;
*[http://tomcat.apache.org/tomcat-3.3-doc/tomcat-ssl-howto.html Tomcat SSL Configuration]&lt;br /&gt;
*[http://httpd.apache.org/docs/2.0/ssl/ssl_faq.html Apache: SSL/TLS Strong Encryption: FAQ]&lt;br /&gt;
*[http://www.networkworld.com/columnists/2006/011606internet.html Getting SSL to work across virtual hosts in Apache]&lt;br /&gt;
*[http://www.faqs.org/docs/Linux-HOWTO/SSL-RedHat-HOWTO.html Building a Secure RedHat Apache Server HOWTO]&lt;br /&gt;
* CommonMisconfigurations - Httpd Wiki - http://wiki.apache.org/httpd/CommonMisconfigurations&lt;br /&gt;
&lt;br /&gt;
--- chain ---&lt;br /&gt;
&lt;br /&gt;
If you have a chain, create the pem as &amp;quot;key, cert, chain&amp;quot; and set Apache config like so:&lt;br /&gt;
&lt;br /&gt;
    SSLCertificateFile /etc/ssl.pem&lt;br /&gt;
    SSLCertificateKeyFile /etc/ssl.pem&lt;br /&gt;
    SSLCertificateChainFile /etc/ssl.pem&lt;br /&gt;
&lt;br /&gt;
or just&lt;br /&gt;
&lt;br /&gt;
    SSLCertificateFile /etc/ssl.pem&lt;br /&gt;
    SSLCertificateChainFile /etc/ssl.pem&lt;br /&gt;
&lt;br /&gt;
=== Ubuntu SnakeOil Cert ===&lt;br /&gt;
&lt;br /&gt;
Install the snakoil fake cert &amp;lt;ref&amp;gt;https://superuser.com/questions/58149/host-based-snakeoil-certificates-in-ubuntu&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 sudo apt-get install ssl-cert&lt;br /&gt;
&lt;br /&gt;
 sudo make-ssl-cert generate-default-snakeoil --force-overwrite&lt;br /&gt;
&lt;br /&gt;
 /etc/ssl/certs/ssl-cert-snakeoil.pem&lt;br /&gt;
 /etc/ssl/private/ssl-cert-snakeoil.key&lt;br /&gt;
&lt;br /&gt;
== Linux System Password Protection ==&lt;br /&gt;
&lt;br /&gt;
Using system accounts for HTTP authentication - http://wiki.zs64.net/Using_system_accounts_for_HTTP_authentication&lt;br /&gt;
&lt;br /&gt;
  httpd.conf&lt;br /&gt;
&lt;br /&gt;
Edit httpd.conf to add these lines to the general configuration:&lt;br /&gt;
&lt;br /&gt;
LoadModule              auth_external_module    libexec/apache2/mod_auth_external.so&lt;br /&gt;
&lt;br /&gt;
(Should have been added by installing the port already.)&lt;br /&gt;
&lt;br /&gt;
Add these lines to each virtual host where you&#039;d like to use system accounts for authentication:&lt;br /&gt;
&lt;br /&gt;
AddExternalAuth         pwauth  /usr/local/bin/pwauth&lt;br /&gt;
SetExternalAuthMethod   pwauth  pipe&lt;br /&gt;
&lt;br /&gt;
Add these lines to each Directory or Location section that you want protected by authentication:&lt;br /&gt;
&lt;br /&gt;
AuthType        Basic&lt;br /&gt;
AuthExternal    pwauth&lt;br /&gt;
require         valid-user&lt;br /&gt;
&lt;br /&gt;
== Password Protection with .htaccess and htpasswd ==&lt;br /&gt;
&lt;br /&gt;
*[http://www.javascriptkit.com/howto/htaccess3.shtml Comprehensive guide to .htaccess: Password protection]&lt;br /&gt;
*[http://apache-server.com/tutorials/ATusing-htaccess.html Using .htaccess Files with Apache]&lt;br /&gt;
*[http://www.4webhelp.net/tutorials/misc/htaccess.php Password Protection by Rod]&lt;br /&gt;
*[http://www.spoono.com/php/tutorials/tutorial.php?id=30 .htaccess Password Protection in PHP]&lt;br /&gt;
&lt;br /&gt;
Sample .htaccess file:&lt;br /&gt;
&lt;br /&gt;
 AuthUserFile /var/www/htpasswd&lt;br /&gt;
 AuthGroupFile /dev/null&lt;br /&gt;
 AuthName &amp;quot;Secret Place&amp;quot;&lt;br /&gt;
 AuthType Basic&lt;br /&gt;
 Require valid-user&lt;br /&gt;
 &lt;br /&gt;
 #Require user &amp;lt;user&amp;gt;&lt;br /&gt;
 #Require group &amp;lt;group&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
To use with httpd.conf or virtual.conf, wrap in &amp;quot;&amp;lt;Directory&amp;gt;&amp;quot; tags:&lt;br /&gt;
 &amp;lt;Directory /&amp;gt;&lt;br /&gt;
   AuthUserFile ...&lt;br /&gt;
   ...&lt;br /&gt;
 &amp;lt;/Directory&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: if you want in your httpd.conf (or virtual.conf) surround with &amp;quot;&amp;lt;Location /&amp;gt;...&amp;lt;/Location&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
To add password file:&lt;br /&gt;
 htpasswd -c /var/www/htpasswd admin&lt;br /&gt;
 htpasswd /var/www/htpasswd user1&lt;br /&gt;
&lt;br /&gt;
 # if you want to create a blank username with password:&lt;br /&gt;
 htpasswd /path/htpasswd &#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To use .htaccess:&lt;br /&gt;
 &amp;lt;Directory /&amp;gt;&lt;br /&gt;
     Options FollowSymLinks&lt;br /&gt;
     AllowOverride &#039;&#039;&#039;AuthConfig&#039;&#039;&#039;&lt;br /&gt;
 &amp;lt;/Directory&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Or user the [http://www.webmaster-toolkit.com/htaccess-generator.shtml .htaccess generator]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[http://httpd.apache.org/docs/2.2/mod/core.html#require Apache HTTP Server - Require Directive]:&lt;br /&gt;
&lt;br /&gt;
Require user userid [userid] ...&lt;br /&gt;
:Only the named users can access the resource.&lt;br /&gt;
Require group group-name [group-name] ...&lt;br /&gt;
:Only users in the named groups can access the resource.&lt;br /&gt;
Require valid-user&lt;br /&gt;
:All valid users can access the resource. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
AuthType Basic&lt;br /&gt;
AuthName &amp;quot;Restricted Resource&amp;quot;&lt;br /&gt;
AuthUserFile /web/users&lt;br /&gt;
AuthGroupFile /web/groups&lt;br /&gt;
Require group admin &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== web based htpasswd manager ===&lt;br /&gt;
&lt;br /&gt;
see [[change_htpasswd.pl]]&lt;br /&gt;
&lt;br /&gt;
[http://home.xnet.com/~efflandt/pub/htpasswd.pl htpasswd.cgi by David Efflandt]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Perl CGI Script to Modify User Passwords:&lt;br /&gt;
&lt;br /&gt;
This allows users to manage / change their own passwords.&lt;br /&gt;
&lt;br /&gt;
Use the Perl CGI script [http://home.xnet.com/%7Eefflandt/pub/htpasswd.pl htpasswd.pl] [[http://www.yolinux.com/TUTORIALS/src/htpasswd_pl.txt cache]]&lt;br /&gt;
&lt;br /&gt;
* Edit location of Perl .i.e.: /usr/bin/perl&lt;br /&gt;
** Not /usr/local/bin/perl&lt;br /&gt;
* Edit the script to specify location of the password file i.e. /var/www/PasswordDir/.htpasswd&lt;br /&gt;
* SELinux users must add the correct attribute i.e. chcon -R -h -t httpd_sys_content_t /var/www/PasswordDir&lt;br /&gt;
* The password file must be located in a directory where CGI is allowed to modify files.&lt;br /&gt;
&lt;br /&gt;
File: httpd.conf (portion):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
..&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;Directory &amp;quot;/var/www/PasswordDir&amp;quot;&amp;gt;&lt;br /&gt;
    Options -Indexes&lt;br /&gt;
    AllowOverride None&lt;br /&gt;
    Options None&lt;br /&gt;
    Order allow,deny&lt;br /&gt;
    Allow from all&lt;br /&gt;
&amp;lt;/Directory&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
..&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Directory Browsing==&lt;br /&gt;
 DocumentRoot /www/files&lt;br /&gt;
 &amp;lt;Directory /&amp;gt;&lt;br /&gt;
     Options FollowSymLinks &#039;&#039;&#039;+Indexes&#039;&#039;&#039;&lt;br /&gt;
     AllowOverride None&lt;br /&gt;
 &amp;lt;/Directory&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: The &#039;+&#039; may not be needed.&lt;br /&gt;
&lt;br /&gt;
In a .htaccess:&lt;br /&gt;
 Options +indexes&lt;br /&gt;
&lt;br /&gt;
Long file names: [http://www.networkworld.com/article/2311687/software/showing-long-file-names-in-apache-directory-listings.html]&lt;br /&gt;
 IndexOptions NameWidth=*&lt;br /&gt;
&lt;br /&gt;
For root indexes, the welcome.conf may be overriding with the welcome screen.  Make the following change: [http://www.linuxquestions.org/questions/linux-general-1/apache-2-root-directory-listing-201356/]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;LocationMatch &amp;quot;^/$&amp;gt;&lt;br /&gt;
    #Options -Indexes&lt;br /&gt;
    Options Indexes&lt;br /&gt;
    ErrorDocument 403 /error/noindex.html&lt;br /&gt;
&amp;lt;/LocationMatch&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== cgi ==&lt;br /&gt;
&lt;br /&gt;
Script Alias folder:&lt;br /&gt;
 ScriptAlias /cgi-bin/ &amp;quot;C:/Program Files/Apache Group/Apache/cgi-bin/&amp;quot; &lt;br /&gt;
 ScriptAlias /cgi-bin/ &amp;quot;/var/www/cgi-bin/&amp;quot;&lt;br /&gt;
&lt;br /&gt;
My favorite option, make all .cgi files executable: (This will need to be surrounded with &#039;&amp;lt;Location /&amp;gt;&#039; or &#039;&amp;lt;Directory /&amp;gt;&#039; tags)&lt;br /&gt;
 AddHandler cgi-script .cgi &lt;br /&gt;
 Options +ExecCGI &lt;br /&gt;
&lt;br /&gt;
Note: Make sure to &#039;chmod +x&#039; the files.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;VirtualHost *:80&amp;gt;&lt;br /&gt;
    ServerName hg.t0e.org&lt;br /&gt;
&lt;br /&gt;
    DirectoryIndex hgweb.cgi&lt;br /&gt;
    DocumentRoot /www/hg&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;Location /&amp;gt;&lt;br /&gt;
        AddHandler cgi-script .cgi&lt;br /&gt;
        Options +ExecCGI&lt;br /&gt;
    &amp;lt;/Location&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    ServerAdmin admin@hg.t0e.org&lt;br /&gt;
    ErrorLog logs/hg.t0e.org-error_log&lt;br /&gt;
    CustomLog logs/hg.t0e.org-access_log common&lt;br /&gt;
&amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Source: [http://www.thesitewizard.com/archive/addcgitoapache.shtml How to Add CGI Script Support (Perl, Python, etc) to Your Apache Server on Windows (thesitewizard.com)]&lt;br /&gt;
&lt;br /&gt;
--&lt;br /&gt;
&lt;br /&gt;
Only files without an extension:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;VirtualHost *:80&amp;gt;&lt;br /&gt;
    ServerName pi.t0e.org&lt;br /&gt;
    DocumentRoot /www/pi&lt;br /&gt;
    &amp;lt;Directory /&amp;gt;&lt;br /&gt;
        AllowOverride All&lt;br /&gt;
    &amp;lt;/Directory&amp;gt;&lt;br /&gt;
    DirectoryIndex index index.php index.html index.htm&lt;br /&gt;
    &amp;lt;Files ~ &amp;quot;^[a-zA-Z]*$&amp;quot;&amp;gt;&lt;br /&gt;
        SetHandler cgi-script&lt;br /&gt;
        Options +ExecCGI&lt;br /&gt;
    &amp;lt;/Files&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
=== CentOS Default ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#&lt;br /&gt;
# ScriptAliases are essentially the same as Aliases, except that&lt;br /&gt;
# documents in the realname directory are treated as applications and&lt;br /&gt;
# run by the server when requested rather than as documents sent to the client.&lt;br /&gt;
# The same rules about trailing &amp;quot;/&amp;quot; apply to ScriptAlias directives as to&lt;br /&gt;
# Alias.&lt;br /&gt;
#&lt;br /&gt;
ScriptAlias /cgi-bin/ &amp;quot;/var/www/cgi-bin/&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
# &amp;quot;/var/www/cgi-bin&amp;quot; should be changed to whatever your ScriptAliased&lt;br /&gt;
# CGI directory exists, if you have that configured.&lt;br /&gt;
#&lt;br /&gt;
&amp;lt;Directory &amp;quot;/var/www/cgi-bin&amp;quot;&amp;gt;&lt;br /&gt;
    AllowOverride None&lt;br /&gt;
    Options None&lt;br /&gt;
    Order allow,deny&lt;br /&gt;
    Allow from all&lt;br /&gt;
&amp;lt;/Directory&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Python CGI ==&lt;br /&gt;
&lt;br /&gt;
See [[Python#Apache_CGI]]&lt;br /&gt;
&lt;br /&gt;
==mod_proxy==&lt;br /&gt;
*http://www.apachetutor.org/admin/reverseproxies&lt;br /&gt;
*http://www.linuxfocus.org/English/March2000/article147.html&lt;br /&gt;
*http://www.linuxhelp.net/guides/apacheproxy/&lt;br /&gt;
*http://webauth.stanford.edu/manual/mod/mod_proxy.html&lt;br /&gt;
*http://www.apachetutor.org/admin/reverseproxies&lt;br /&gt;
*http://confluence.atlassian.com/display/DOC/Using+Apache+with+mod_proxy&lt;br /&gt;
*http://www.serverwatch.com/tutorials/article.php/3290851&lt;br /&gt;
*http://apache.webthing.com/mod_proxy_html/&lt;br /&gt;
*http://www.ibm.com/developerworks/linux/library/wa-lampsec/index.html&lt;br /&gt;
&lt;br /&gt;
== prefork vs worker ==&lt;br /&gt;
&lt;br /&gt;
Prefork performs better.  Worker uses less memory.  Prefork is most commonly used, and is the better choice for a web server.&lt;br /&gt;
&lt;br /&gt;
To see which is compiled, and look for prefork.c or worker.c:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# httpd -l&lt;br /&gt;
 &lt;br /&gt;
Compiled in modules:&lt;br /&gt;
  core.c&lt;br /&gt;
  prefork.c&lt;br /&gt;
  http_core.c&lt;br /&gt;
  mod_so.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Statistics ==&lt;br /&gt;
&lt;br /&gt;
=== Connections ===&lt;br /&gt;
&lt;br /&gt;
Count active connections:&lt;br /&gt;
 netstat -ant | grep ESTABLISHED | grep :80 | wc -l&lt;br /&gt;
&lt;br /&gt;
From PHP:&lt;br /&gt;
 &amp;lt;?php&lt;br /&gt;
 $number_of_users = shell_exec(&#039;netstat -ant | grep ESTABLISHED | grep :80 | wc -l&#039;);&lt;br /&gt;
 echo $number_of_users;&lt;br /&gt;
 ?&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* [http://www.experts-exchange.com/OS/Linux/Q_22825240.html Find out how many connections are on an apache server : apache, connections, many, find, server]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== [http://httpd.apache.org/docs/2.0/mod/mod_status.html mod_status] ===&lt;br /&gt;
&lt;br /&gt;
[http://httpd.apache.org/docs/2.0/mod/mod_status.html mod_status - Apache HTTP Server]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Summary&lt;br /&gt;
&lt;br /&gt;
The Status module allows a server administrator to find out how well their server is performing. A HTML page is presented that gives the current server statistics in an easily readable form. If required this page can be made to automatically refresh (given a compatible browser). Another page gives a simple machine-readable list of the current server state.&lt;br /&gt;
&lt;br /&gt;
The details given are:&lt;br /&gt;
&lt;br /&gt;
* The number of worker serving requests&lt;br /&gt;
* The number of idle worker&lt;br /&gt;
* The status of each worker, the number of requests that worker has performed and the total number of bytes served by the worker (*)&lt;br /&gt;
* A total number of accesses and byte count served (*)&lt;br /&gt;
* The time the server was started/restarted and the time it has been running for&lt;br /&gt;
* Averages giving the number of requests per second, the number of bytes served per second and the average number of bytes per request (*)&lt;br /&gt;
* The current percentage CPU used by each worker and in total by Apache (*)&lt;br /&gt;
* The current hosts and requests being processed (*)&lt;br /&gt;
&lt;br /&gt;
The lines marked &amp;quot;(*)&amp;quot; are only available if ExtendedStatus is On.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LoadModule status_module modules/mod_status.so&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
# ExtendedStatus controls whether Apache will generate &amp;quot;full&amp;quot; status&lt;br /&gt;
# information (ExtendedStatus On) or just basic information (ExtendedStatus&lt;br /&gt;
# Off) when the &amp;quot;server-status&amp;quot; handler is called. The default is Off.&lt;br /&gt;
#&lt;br /&gt;
#ExtendedStatus On&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
# Allow server status reports generated by mod_status,&lt;br /&gt;
# with the URL of http://servername/server-status&lt;br /&gt;
# Change the &amp;quot;.example.com&amp;quot; to match your domain to enable.&lt;br /&gt;
#&lt;br /&gt;
#&amp;lt;Location /server-status&amp;gt;&lt;br /&gt;
#    SetHandler server-status&lt;br /&gt;
#    Order deny,allow&lt;br /&gt;
#    Deny from all&lt;br /&gt;
#    Allow from .example.com&lt;br /&gt;
#&amp;lt;/Location&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* [http://httpd.apache.org/docs/2.0/mod/mod_status.html mod_status - Apache HTTP Server]&lt;br /&gt;
* [http://www.experts-exchange.com/OS/Linux/Q_22825240.html Find out how many connections are on an apache server : apache, connections, many, find, server]&lt;br /&gt;
&lt;br /&gt;
== TRACE and TRACK ==&lt;br /&gt;
&lt;br /&gt;
ISO Audit may result in this &amp;quot;Medium&amp;quot; risk detected:&lt;br /&gt;
&lt;br /&gt;
:&amp;quot;HTTP Methods Allowed.  It is observed that HTTP methods GET HEAD TRACE OPTIONS are allowed on this host.  Disable all unnecessary methods.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
:&amp;quot;HTTP TRACE / TRACK Methods Allowed.  The remote webserver supports the TRACE and/or TRACK methods.  TRACE and TRACK are HTTP methods that are used to debug web server connections.  Disable these methods.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Disabling TRACE ===&lt;br /&gt;
&lt;br /&gt;
[http://rackerhacker.com/2007/08/28/apache-disable-trace-and-track-methods/ Apache: Disable TRACE and TRACK methods | Racker Hacker]:&lt;br /&gt;
&lt;br /&gt;
Lots of PCI Compliance and vulnerability scan vendors will complain about TRACE and TRACK methods being enabled on your server. Since most providers run Nessus, you&#039;ll see this fairly often. Here&#039;s the rewrite rules to add:&lt;br /&gt;
&lt;br /&gt;
 RewriteEngine on&lt;br /&gt;
 RewriteCond %{REQUEST_METHOD} ^(TRACE|TRACK)&lt;br /&gt;
 RewriteRule .* - [F]&lt;br /&gt;
&lt;br /&gt;
These directives will need to be added to each VirtualHost.&lt;br /&gt;
&lt;br /&gt;
For apache version 1.3.34 (or later 1.3.x versions), or apache 2.0.55 (or later), this has been made easy. Just add the line TraceEnable off&lt;br /&gt;
&lt;br /&gt;
 TraceEnable off&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[http://publib.boulder.ibm.com/httpserv/ihsdiag/http_trace.html Disabling the HTTP TRACE method]:&lt;br /&gt;
&lt;br /&gt;
The HTTP TRACE request method causes the data received by IBM HTTP Server from the client to be sent back to the client, as in the following example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ telnet 127.0.0.1 8080&lt;br /&gt;
Trying...&lt;br /&gt;
Connected to 127.0.0.1.&lt;br /&gt;
Escape character is &#039;^]&#039;.&lt;br /&gt;
TRACE / HTTP/1.0&lt;br /&gt;
Host: foo&lt;br /&gt;
A: b&lt;br /&gt;
C: d&lt;br /&gt;
&lt;br /&gt;
HTTP/1.1 200 OK&lt;br /&gt;
Date: Mon, 04 Oct 2004 14:07:59 GMT&lt;br /&gt;
Server: IBM_HTTP_SERVER&lt;br /&gt;
Connection: close&lt;br /&gt;
Content-Type: message/http&lt;br /&gt;
&lt;br /&gt;
TRACE / HTTP/1.0&lt;br /&gt;
A: b&lt;br /&gt;
C: d&lt;br /&gt;
Host: foo&lt;br /&gt;
&lt;br /&gt;
Connection closed.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The TRACE capability could be used by vulnerable or malicious applications to trick a web browser into issuing a TRACE request against an arbitrary site and then send the response to the TRACE to a third party using web browser features.&lt;br /&gt;
&lt;br /&gt;
Making the required configuration changes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;VirtualHost www.example.com&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
# disable TRACE in the www.example.com virtual host&lt;br /&gt;
RewriteEngine On &lt;br /&gt;
RewriteCond %{REQUEST_METHOD} ^TRACE &lt;br /&gt;
RewriteRule .* - [F] &lt;br /&gt;
&amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Using SSL:&lt;br /&gt;
 $ /usr/linux/bin/openssl s_client -connect 127.0.0.1:8444&lt;br /&gt;
&lt;br /&gt;
For more information...&lt;br /&gt;
&lt;br /&gt;
More background information on the concerns with TRACE is provided at http://www.apacheweek.com/issues/03-01-24#news.&lt;br /&gt;
&lt;br /&gt;
Other:&lt;br /&gt;
* Apache Tips: Disable the HTTP TRACE method | MDLog:/sysadmin - http://www.ducea.com/2007/10/22/apache-tips-disable-the-http-trace-method/&lt;br /&gt;
&lt;br /&gt;
=== TraceEnable ===&lt;br /&gt;
&lt;br /&gt;
Apache Core Features - http://httpd.apache.org/docs/1.3/mod/core.html#traceenable&lt;br /&gt;
&lt;br /&gt;
TraceEnable:&lt;br /&gt;
 Syntax: TraceEnable [on|off|extended]&lt;br /&gt;
 Default: TraceEnable on&lt;br /&gt;
 Context: server config&lt;br /&gt;
 Status: core (Windows, NetWare)&lt;br /&gt;
 Compatibility: Available only in Apache 1.3.34, 2.0.55 and later&lt;br /&gt;
&lt;br /&gt;
This directive overrides the behavior of TRACE for both the core server and mod_proxy. The default TraceEnable on permits TRACE requests per RFC 2616, which disallows any request body to accompany the request. TraceEnable off causes the core server and mod_proxy to return a 405 FORBIDDEN error to the client.&lt;br /&gt;
&lt;br /&gt;
Finally, for testing and diagnostic purposes only, request bodies may be allowed using the non-compliant TraceEnable extended directive. The core (as an origin server) will restrict the request body to 64k (plus 8k for chunk headers if Transfer-Encoding: chunked is used). The core will reflect the full headers and all chunk headers with the request body. As a proxy server, the request body is not restricted to 64k. At this time the Apache 1.3 mod_proxy does not permit chunked request bodies for any request, including the extended TRACE request.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Disabling TRACK ===&lt;br /&gt;
&lt;br /&gt;
The HTTP TRACK method&lt;br /&gt;
&lt;br /&gt;
The TRACK method is a type of request supported by Microsoft web servers. It is not RFC compliant and is not supported directly by IBM HTTP Server. The method may be utilized as part of a cross-site scripting attack. See Vulnerability Note VU#288308 for more information.&lt;br /&gt;
&lt;br /&gt;
Even though IBM HTTP Server does not support the TRACK method natively, it is possible for plug-in modules to provide support for it. To disable this capability for plug-in modules, in addition to disabling the TRACE method, add these two additional directives after the existing RewriteCond and RewriteRule directives which are used to disable TRACE:&lt;br /&gt;
&lt;br /&gt;
RewriteCond %{REQUEST_METHOD} ^TRACK&lt;br /&gt;
RewriteRule .* - [F]&lt;br /&gt;
&lt;br /&gt;
Here is a full example showing the directives to disable both TRACE and TRACK:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;VirtualHost www.example.com&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
# disable TRACE and TRACK in the www.example.com virtual host&lt;br /&gt;
RewriteEngine On &lt;br /&gt;
RewriteCond %{REQUEST_METHOD} ^TRACE &lt;br /&gt;
RewriteRule .* - [F] &lt;br /&gt;
RewriteCond %{REQUEST_METHOD} ^TRACK&lt;br /&gt;
RewriteRule .* - [F] &lt;br /&gt;
&amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Attack ===&lt;br /&gt;
&lt;br /&gt;
Cross-Site Tracing issues&lt;br /&gt;
&lt;br /&gt;
Earlier this week a paper was published, [http://www.cgisecurity.com/whitehat-mirror/WH-WhitePaper_XST_ebook.pdf &amp;quot;Cross-Site Tracing&amp;quot;] which gave details of how the TRACE HTTP request could be used in Cross-Site Scripting attacks. Unfortunately this issue has not been very well understood by the media and has received a unwarranted amount of attention.&lt;br /&gt;
&lt;br /&gt;
When an HTTP TRACE request is sent to a web server that supports it, that server will respond echoing the data that is passed to it, including any HTTP headers. The paper explains that some browsers can be scripted to perform a TRACE request. A browser with this functionality could be made to issue a TRACE request against an arbitrary site and pass the results on elsewhere. Since browsers will only send authentication details and cookies to the sites that issue them this means a user having a browser with this functionality could be tricked into sending their cookies or authentication details for arbitrary sites to an attacker.&lt;br /&gt;
&lt;br /&gt;
For example, if you visited a page that an attacker has carefully crafted, the page could cause your browser to bounce a TRACE request against some site for which you have authentication cookies. The result of the TRACE will be a copy of what was sent to the site, which will therefore include those cookies or authentication data. The carefully crafted page can then pass that information on to the attacker.&lt;br /&gt;
&lt;br /&gt;
TRACE requests can be disabled by making a change to the Apache server configuration. Unfortunately it is not possible to do this using the Limit directive since the processing for the TRACE request skips this authorisation checking. Instead the following lines can be added which make use of the mod_rewrite module.&lt;br /&gt;
&lt;br /&gt;
    RewriteEngine On &lt;br /&gt;
    RewriteCond %{REQUEST_METHOD} ^TRACE &lt;br /&gt;
    RewriteRule .* - [F] &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Although the particular attack highlighted made use of the TRACE functionality to grab authentication details, this isn&#039;t a vulnerability in TRACE, or in the Apache web server.&#039;&#039;&#039; The same browser functionality that permits the published attack can be used for different attacks even if TRACE is disabled on the remote web server. For example an attacker could create a carefully crafted page that when visited submits a hidden request to some arbitrary site through your browser, grabs the result and passes it to the attacker.&lt;br /&gt;
&lt;br /&gt;
== Performance Tuning ==&lt;br /&gt;
&lt;br /&gt;
See [[Linux Performance Tuning]]&lt;br /&gt;
&lt;br /&gt;
[http://www.linuxjournal.com/article/6041 Apache and Firewall Performance Tips from the Xenu.net Masters]&lt;br /&gt;
&lt;br /&gt;
=== CentOS January 2009 Thread ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
-------- Original Message --------&lt;br /&gt;
Subject: 	[CentOS] Apache Server Tuning for Performance&lt;br /&gt;
Date: 	Wed, 21 Jan 2009 00:09:38 +0530&lt;br /&gt;
From: 	linux-crazy &amp;lt;hicheerup@gmail.com&amp;gt;&lt;br /&gt;
Reply-To: 	CentOS mailing list &amp;lt;centos@centos.org&amp;gt;&lt;br /&gt;
To: 	CentOS mailing list &amp;lt;centos@centos.org&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Hi all,&lt;br /&gt;
&lt;br /&gt;
I am facing  facing performance issues with our web servers which is&lt;br /&gt;
working for concurrent  250 requests properly and then stops&lt;br /&gt;
responding when the requests are more than 250 .&lt;br /&gt;
&lt;br /&gt;
The current configuration parameters are as follows :&lt;br /&gt;
&lt;br /&gt;
apachectl -version&lt;br /&gt;
Server version: Apache/2.0.52&lt;br /&gt;
Server built:   Jan 30 2007 09:56:16&lt;br /&gt;
&lt;br /&gt;
Kernel : 2.6.9-55.ELsmp #1 SMP Fri Apr 20 16:36:54 EDT 2007 x86_64&lt;br /&gt;
x86_64 x86_64 GNU/Linux&lt;br /&gt;
&lt;br /&gt;
Server Hardware :&lt;br /&gt;
MAIN MEMORY&lt;br /&gt;
(i) Memory Size 4 GB  Dual-Core Intel 5160 processors.&lt;br /&gt;
&lt;br /&gt;
httpd.conf&lt;br /&gt;
&lt;br /&gt;
Timeout 300&lt;br /&gt;
KeepAlive On&lt;br /&gt;
MaxKeepAliveRequests 1000&lt;br /&gt;
KeepAliveTimeout 150&lt;br /&gt;
&lt;br /&gt;
## Server-Pool Size Regulation (MPM specific)&lt;br /&gt;
# prefork MPM&lt;br /&gt;
&lt;br /&gt;
# StartServers: number of server processes to start&lt;br /&gt;
# MinSpareServers: minimum number of server processes which are kept spare&lt;br /&gt;
# MaxSpareServers: maximum number of server processes which are kept spare&lt;br /&gt;
# ServerLimit: maximum value for MaxClients for the lifetime of the server&lt;br /&gt;
# MaxClients: maximum number of server processes allowed to start&lt;br /&gt;
# MaxRequestsPerChild: maximum number of requests a server process serves&lt;br /&gt;
&lt;br /&gt;
&amp;lt;IfModule prefork.c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
StartServers       8&lt;br /&gt;
MinSpareServers    5&lt;br /&gt;
MaxSpareServers   20&lt;br /&gt;
ServerLimit      251&lt;br /&gt;
MaxClients       251&lt;br /&gt;
MaxRequestsPerChild  4000&lt;br /&gt;
&amp;lt;/IfModule&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# worker MPM&lt;br /&gt;
# StartServers: initial number of server processes to start&lt;br /&gt;
# MaxClients: maximum number of simultaneous client connections&lt;br /&gt;
# MinSpareThreads: minimum number of worker threads which are kept spare&lt;br /&gt;
# MaxSpareThreads: maximum number of worker threads which are kept spare&lt;br /&gt;
# ThreadsPerChild: constant number of worker threads in each server process&lt;br /&gt;
# MaxRequestsPerChild: maximum number of requests a server process serves&lt;br /&gt;
&amp;lt;IfModule worker.c&amp;gt;&lt;br /&gt;
StartServers         2&lt;br /&gt;
MaxClients        150&lt;br /&gt;
MinSpareThreads     25&lt;br /&gt;
MaxSpareThreads     75&lt;br /&gt;
ThreadsPerChild     25&lt;br /&gt;
MaxRequestsPerChild  0&lt;br /&gt;
&amp;lt;/IfModule&amp;gt;&lt;br /&gt;
&lt;br /&gt;
     I want to  know about  the difference  between worker MPM and&lt;br /&gt;
Prefork MPM , how to find out which one will be used by my apache&lt;br /&gt;
server and  the recommended one   for highly loaded server.If some one&lt;br /&gt;
provide me the link that best explains above two comparison also  be&lt;br /&gt;
very use full.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 Can any one guide me tuning to be  done for the maximum utilization&lt;br /&gt;
of the Resources  and better performance of the Servers.&lt;br /&gt;
&lt;br /&gt;
 Regards,&lt;br /&gt;
lingu&lt;br /&gt;
_______________________________________________&lt;br /&gt;
CentOS mailing list&lt;br /&gt;
CentOS@centos.org&lt;br /&gt;
http://lists.centos.org/mailman/listinfo/centos&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Only use prefork MPM (worker is for Win32, AFAIK).&lt;br /&gt;
&lt;br /&gt;
If you set ServerLimit to 251, that&#039;s the limit.&lt;br /&gt;
Set ServerLimit and MaxClients to the same value.&lt;br /&gt;
(Larger than 250)&lt;br /&gt;
OK?&lt;br /&gt;
And take a couple of minutes to study the apache documentation. It&#039;s  &lt;br /&gt;
actually quite good and tranlated into many languages...&lt;br /&gt;
&lt;br /&gt;
BUT: what your server is being able to handle also depends on what you  &lt;br /&gt;
actually serve (PHP/JSP/Servelets/Perl/whatever!&lt;br /&gt;
&lt;br /&gt;
This is usually not a problem that is easily described and solved in  &lt;br /&gt;
two sentences.&lt;br /&gt;
&lt;br /&gt;
Rainer&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Increase your MaxClients configuration, also enable if you&lt;br /&gt;
haven&#039;t already the server-status module and monitor the&lt;br /&gt;
server via http://&amp;lt;your server name&amp;gt;/server-status it will&lt;br /&gt;
show how many workers are busy and what they are doing.&lt;br /&gt;
&lt;br /&gt;
As for which to use, prefork is the old forked method of&lt;br /&gt;
doing things, the other uses threads. Depending on what kind&lt;br /&gt;
of application your running on top of apache, if it is not&lt;br /&gt;
thread safe(at some point many PHP modules were not thread&lt;br /&gt;
safe), you may want to use prefork. Otherwise you can use&lt;br /&gt;
the threading model.&lt;br /&gt;
&lt;br /&gt;
If your not sure I&#039;d say stick to prefork to be safe until&lt;br /&gt;
you can determine for sure that threading is safe.&lt;br /&gt;
&lt;br /&gt;
nate&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Most list members would likely advise sticking with the prefork &lt;br /&gt;
configuration.  Without knowing what kind of applications you are &lt;br /&gt;
running on your webserver, I wouldn&#039;t suggest changing it.&lt;br /&gt;
&lt;br /&gt;
Merely increasing the number of workers might make performance worse.&lt;br /&gt;
&lt;br /&gt;
Use ps or top to figure out how much each apache worker is using. Then &lt;br /&gt;
decide how much ram you want to dedicate on your server to Apache, &lt;br /&gt;
without going into swap. (Over-allocating and then paging out memory &lt;br /&gt;
will only make performance much worse.) For example, if I have 2G or &lt;br /&gt;
ram, and I want 1.5 for apache workers, my average apache worker size &lt;br /&gt;
(resident memory) is 65MB, then I have room for 23 workers. (1024 * 1.5 &lt;br /&gt;
) / 65. (There are more accurate ways to calculate this usage, like &lt;br /&gt;
taking shared memory into account.)&lt;br /&gt;
&lt;br /&gt;
Upgrading the ram in your web server is a pretty fast interim solution.&lt;br /&gt;
&lt;br /&gt;
Consider your application performance, too. The longer a request in your &lt;br /&gt;
application takes, the more workers are in use on your web server, &lt;br /&gt;
taking up more memory. If you have long-running queries in your &lt;br /&gt;
database, take care of those first.&lt;br /&gt;
&lt;br /&gt;
Good luck&lt;br /&gt;
&lt;br /&gt;
Jed&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Jed Reynolds wrote:&lt;br /&gt;
&amp;gt; &lt;br /&gt;
&amp;gt; Merely increasing the number of workers might make performance worse.&lt;br /&gt;
&amp;gt; &lt;br /&gt;
&amp;gt; Use ps or top to figure out how much each apache worker is using. Then &lt;br /&gt;
&amp;gt; decide how much ram you want to dedicate on your server to Apache, &lt;br /&gt;
&amp;gt; without going into swap. (Over-allocating and then paging out memory &lt;br /&gt;
&amp;gt; will only make performance much worse.)  For example, if I have 2G or&lt;br /&gt;
&amp;gt; ram, and I want 1.5 for apache workers, my average apache worker size &lt;br /&gt;
&amp;gt; (resident memory) is 65MB, then I have room for 23 workers. (1024 * 1.5 &lt;br /&gt;
&amp;gt; ) / 65. (There are more accurate ways to calculate this usage, like &lt;br /&gt;
&amp;gt; taking shared memory into account.)&lt;br /&gt;
&lt;br /&gt;
Pay attention to shared memory when doing this.  A freshly-forked &lt;br /&gt;
process shares virtually all RAM with its parent.  How much and how &lt;br /&gt;
quickly this changes varies wildly with the application type and &lt;br /&gt;
activity that causes the child&#039;s data to become unique.  With some types &lt;br /&gt;
of applications (especially mod_perl) you may want to tune down the &lt;br /&gt;
number of hits each child services to increase memory sharing.  Also, if &lt;br /&gt;
you are running external cgi programs you must take them into account.&lt;br /&gt;
&lt;br /&gt;
&amp;gt; Upgrading the ram in your web server is a pretty fast interim solution.&lt;br /&gt;
&amp;gt; &lt;br /&gt;
&amp;gt; Consider your application performance, too. The longer a request in your &lt;br /&gt;
&amp;gt; application takes, the more workers are in use on your web server, &lt;br /&gt;
&amp;gt; taking up more memory. If you have long-running queries in your &lt;br /&gt;
&amp;gt; database, take care of those first.&lt;br /&gt;
&lt;br /&gt;
You may also have to turn off or tune down the HTTP 1.1 connection &lt;br /&gt;
keepalives, trading the time it takes to establish a new connection for &lt;br /&gt;
the RAM it takes to keep the associated process waiting for another &lt;br /&gt;
request from the same client.&lt;br /&gt;
&lt;br /&gt;
-- &lt;br /&gt;
   Les Mikesell&lt;br /&gt;
    lesmikesell@gmail.com&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Also take a look at apache alternatives like lighttpd and nginx. In certain&lt;br /&gt;
cases they do miracles.&lt;br /&gt;
&lt;br /&gt;
Jure Pečar&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
I don&#039;t know about lighttpd (our results were mixed) - but NGINX is  &lt;br /&gt;
really _very_ fast.&lt;br /&gt;
Last time I checked, it seems to be the fastest way to accelerate  &lt;br /&gt;
webpage-delivery on generic hardware and with OSS-software.&lt;br /&gt;
&lt;br /&gt;
But it&#039;s not a feature-monster like apache, so you still need that.&lt;br /&gt;
&lt;br /&gt;
Rainer&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Linux-crazy wrote on Wed, 21 Jan 2009 00:09:38 +0530:&lt;br /&gt;
&lt;br /&gt;
&amp;gt; KeepAliveTimeout 150&lt;br /&gt;
&lt;br /&gt;
My god, reduce this to 10 or 5.&lt;br /&gt;
&lt;br /&gt;
&amp;gt; ServerLimit      251&lt;br /&gt;
&amp;gt; MaxClients       251&lt;br /&gt;
&lt;br /&gt;
There&#039;s your limit. However, you should check with your hardware if upping &lt;br /&gt;
it is really desirable. With 4 GB I think you won&#039;t be able to handle much &lt;br /&gt;
more anyway.&lt;br /&gt;
&lt;br /&gt;
Kai&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Kai Schaetzl wrote:&lt;br /&gt;
&amp;gt; There&#039;s your limit. However, you should check with your hardware if upping &lt;br /&gt;
&amp;gt; it is really desirable. With 4 GB I think you won&#039;t be able to handle much &lt;br /&gt;
&amp;gt; more anyway.&lt;br /&gt;
&lt;br /&gt;
That really depends. If you only shove out static pages and have one or&lt;br /&gt;
two or three odd cgis on the machine, you can flatten down the httpd&lt;br /&gt;
binary quite a bit by throwing out unneeded modules.&lt;br /&gt;
&lt;br /&gt;
500 to 750 clients shouldn&#039;t be that much of a problem then ...&lt;br /&gt;
&lt;br /&gt;
Cheers,&lt;br /&gt;
&lt;br /&gt;
Ralph&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Ralph Angenendt wrote on Wed, 21 Jan 2009 10:52:59 +0100:&lt;br /&gt;
&lt;br /&gt;
&amp;gt; That really depends. If you only shove out static pages and have one or&lt;br /&gt;
&amp;gt; two or three odd cgis on the machine, you can flatten down the httpd&lt;br /&gt;
&amp;gt; binary quite a bit by throwing out unneeded modules.&lt;br /&gt;
&amp;gt; &lt;br /&gt;
&amp;gt; 500 to 750 clients shouldn&#039;t be that much of a problem then ...&lt;br /&gt;
&lt;br /&gt;
Sure it depends ;-) I do serve dynamic pages but by removing the really &lt;br /&gt;
unnecessary modules I made my httpds much faster (especially on pipelined &lt;br /&gt;
image downloads) and they only have some 10 MB (RES) per worker.&lt;br /&gt;
&lt;br /&gt;
But I would expect that they are running the default set of modules.&lt;br /&gt;
&lt;br /&gt;
Kai&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Kai Schaetzl schrieb:&lt;br /&gt;
&amp;gt; Ralph Angenendt wrote on Wed, 21 Jan 2009 10:52:59 +0100:&lt;br /&gt;
&amp;gt;&lt;br /&gt;
&amp;gt;   &lt;br /&gt;
&amp;gt;&amp;gt; That really depends. If you only shove out static pages and have one or&lt;br /&gt;
&amp;gt;&amp;gt; two or three odd cgis on the machine, you can flatten down the httpd&lt;br /&gt;
&amp;gt;&amp;gt; binary quite a bit by throwing out unneeded modules.&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt; 500 to 750 clients shouldn&#039;t be that much of a problem then ...&lt;br /&gt;
&amp;gt;&amp;gt;     &lt;br /&gt;
&amp;gt;&lt;br /&gt;
&amp;gt; Sure it depends ;-) I do serve dynamic pages but by removing the really &lt;br /&gt;
&amp;gt; unnecessary modules I made my httpds much faster (especially on pipelined &lt;br /&gt;
&amp;gt; image downloads) and they only have some 10 MB (RES) per worker.&lt;br /&gt;
&amp;gt;&lt;br /&gt;
&amp;gt; But I would expect that they are running the default set of modules.&lt;br /&gt;
&amp;gt;&lt;br /&gt;
&amp;gt; Kai&lt;br /&gt;
&amp;gt;&lt;br /&gt;
&amp;gt;   &lt;br /&gt;
&lt;br /&gt;
If you can separate-out the images to a specific URL (img.domain.com)&lt;br /&gt;
and put them all in the same directory, you can use NGINX to serve them.&lt;br /&gt;
Of course, the actual transfer-speed will not increase much - but&lt;br /&gt;
latency will go down to the absolute minimum.&lt;br /&gt;
And latency is what makes a page appear &amp;quot;fast&amp;quot; or &amp;quot;slow&amp;quot; to customers.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Ralph Angenendt wrote:&lt;br /&gt;
&amp;gt; Kai Schaetzl wrote:&lt;br /&gt;
&amp;gt;&amp;gt; There&#039;s your limit. However, you should check with your hardware if upping&lt;br /&gt;
&amp;gt;&amp;gt; it is really desirable. With 4 GB I think you won&#039;t be able to handle much&lt;br /&gt;
&amp;gt;&amp;gt; more anyway.&lt;br /&gt;
&amp;gt;&lt;br /&gt;
&amp;gt; That really depends. If you only shove out static pages and have one or&lt;br /&gt;
&amp;gt; two or three odd cgis on the machine, you can flatten down the httpd&lt;br /&gt;
&amp;gt; binary quite a bit by throwing out unneeded modules.&lt;br /&gt;
&amp;gt;&lt;br /&gt;
&amp;gt; 500 to 750 clients shouldn&#039;t be that much of a problem then ...&lt;br /&gt;
&lt;br /&gt;
Yeah gotta monitor it.. just checked in on some servers I ran at&lt;br /&gt;
my last company and the front end proxies (99% mod_proxy) seem to&lt;br /&gt;
peak out traffic wise at about 230 workers. For no other reason other&lt;br /&gt;
than because I could each proxy has 8 apache instances running(4 for&lt;br /&gt;
HTTP 4 for HTTPS). CPU usage peaks at around 3%(dual proc single core),&lt;br /&gt;
memory usage around 800MB. About 100 idle workers. Keepalive was set&lt;br /&gt;
to 300 seconds due to poor application design.&lt;br /&gt;
&lt;br /&gt;
One set of back end apache servers peaks traffic wise at around 100&lt;br /&gt;
active workers, though memory usage was higher, around 2GB because&lt;br /&gt;
of mod_fcgid running ruby on rails. CPU usage seems to be at around&lt;br /&gt;
25%(dual proc quad core) for that one application.&lt;br /&gt;
&lt;br /&gt;
Each back end application had it&#039;s own dedicated apache instance(11&lt;br /&gt;
apps) for maximum stability/best performance monitoring. The bulk&lt;br /&gt;
of them ran on the same physical hardware though.&lt;br /&gt;
&lt;br /&gt;
Traffic routing was handled by a combination of F5 load balancers&lt;br /&gt;
and the apache servers previously mentioned(F5 iRules were too slow&lt;br /&gt;
and F5&#039;s TMM was not scalable at the time).&lt;br /&gt;
&lt;br /&gt;
nate&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt; &lt;br /&gt;
&amp;gt; &amp;gt; KeepAliveTimeout 150&lt;br /&gt;
&amp;gt; &lt;br /&gt;
&amp;gt;reduce this to 10 or 5.&lt;br /&gt;
&amp;gt; &lt;br /&gt;
&amp;gt; &lt;br /&gt;
&amp;gt; Kai&lt;br /&gt;
&amp;gt; &lt;br /&gt;
&amp;gt; --&lt;br /&gt;
&amp;gt; Kai Schätzl, Berlin, Germany&lt;br /&gt;
&lt;br /&gt;
Kai,&lt;br /&gt;
&lt;br /&gt;
what do you think about the &amp;quot;general Timeout&lt;br /&gt;
&lt;br /&gt;
it is set to 300&lt;br /&gt;
&lt;br /&gt;
ive never much thought about it, yet should we be consider and possible&lt;br /&gt;
reduce that one too?&lt;br /&gt;
&lt;br /&gt;
 - rh&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RobertH wrote on Wed, 21 Jan 2009 11:26:41 -0800:&lt;br /&gt;
&lt;br /&gt;
&amp;gt; what do you think about the &amp;quot;general Timeout&lt;br /&gt;
&amp;gt; &lt;br /&gt;
&amp;gt; it is set to 300&lt;br /&gt;
&amp;gt; &lt;br /&gt;
&amp;gt; ive never much thought about it, yet should we be consider and possible&lt;br /&gt;
&amp;gt; reduce that one too?&lt;br /&gt;
&lt;br /&gt;
I&#039;m using 120, but I don&#039;t think reducing this value has much impact.&lt;br /&gt;
&lt;br /&gt;
Kai&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Load Balancer ==&lt;br /&gt;
&lt;br /&gt;
Apache Load Balancer&lt;br /&gt;
&lt;br /&gt;
mod_proxy_balancer - Apache HTTP Server - mod_proxy_balancer - http://httpd.apache.org/docs/2.2/mod/mod_proxy_balancer.html&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;Proxy balancer://mycluster&amp;gt;&lt;br /&gt;
BalancerMember http://192.168.1.50:80&lt;br /&gt;
BalancerMember http://192.168.1.51:80&lt;br /&gt;
&amp;lt;/Proxy&amp;gt;&lt;br /&gt;
ProxyPass /test balancer://mycluster &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== User Directories ==&lt;br /&gt;
&lt;br /&gt;
Default:&lt;br /&gt;
 UserDir public_html &lt;br /&gt;
&lt;br /&gt;
Results in:&lt;br /&gt;
 ~/public_html/&lt;br /&gt;
&lt;br /&gt;
To disable user directories:&lt;br /&gt;
 UserDir disabled&lt;br /&gt;
&lt;br /&gt;
Ubuntu user dir config:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        UserDir public_html&lt;br /&gt;
        UserDir disabled root&lt;br /&gt;
&lt;br /&gt;
        &amp;lt;Directory /home/*/public_html&amp;gt;&lt;br /&gt;
                AllowOverride FileInfo AuthConfig Limit Indexes&lt;br /&gt;
                Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec&lt;br /&gt;
                &amp;lt;Limit GET POST OPTIONS&amp;gt;&lt;br /&gt;
                        Order allow,deny&lt;br /&gt;
                        Allow from all&lt;br /&gt;
                &amp;lt;/Limit&amp;gt;&lt;br /&gt;
                &amp;lt;LimitExcept GET POST OPTIONS&amp;gt;&lt;br /&gt;
                        Order deny,allow&lt;br /&gt;
                        Deny from all&lt;br /&gt;
                &amp;lt;/LimitExcept&amp;gt;&lt;br /&gt;
        &amp;lt;/Directory&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* Per-user web directories - Apache HTTP Server - http://httpd.apache.org/docs/2.2/howto/public_html.html&lt;br /&gt;
* mod_userdir - Apache HTTP Server - http://httpd.apache.org/docs/2.2/mod/mod_userdir.html#userdir&lt;br /&gt;
&lt;br /&gt;
== Minimal Memory Instance ==&lt;br /&gt;
&lt;br /&gt;
Assuming running prefork module (check with &#039;apache -l&#039;):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
KeepAlive off&lt;br /&gt;
&lt;br /&gt;
&amp;lt;IfModule mpm_prefork_module&amp;gt;&lt;br /&gt;
StartServers          2&lt;br /&gt;
MinSpareServers       2&lt;br /&gt;
MaxSpareServers      5&lt;br /&gt;
ServerLimit          20&lt;br /&gt;
MaxClients           20&lt;br /&gt;
MaxRequestsPerChild  10000&lt;br /&gt;
&amp;lt;/IfModule&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* Running Apache On A Memory-Constrained VPS | Kalzumeus Software - http://www.kalzumeus.com/2010/06/19/running-apache-on-a-memory-constrained-vps/&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
TODO See:&lt;br /&gt;
*  http://wiki.vpslink.com/Low_memory_MySQL_/_Apache_configurations&lt;br /&gt;
* http://www.narga.net/optimizing-apachephpmysql-low-memory-server/&lt;br /&gt;
&lt;br /&gt;
== LDAP Authentication ==&lt;br /&gt;
&lt;br /&gt;
 # Red Hat / RHEL&lt;br /&gt;
 sudo yum install mod_ldap&lt;br /&gt;
 # allow ldap to connect through selinux:&lt;br /&gt;
 sudo setsebool -P httpd_can_network_connect on&lt;br /&gt;
&lt;br /&gt;
 mod_ldap - Apache HTTP Server Version 2.4&lt;br /&gt;
 https://httpd.apache.org/docs/2.4/mod/mod_ldap.html&lt;br /&gt;
&lt;br /&gt;
== Issues ==&lt;br /&gt;
&lt;br /&gt;
=== Could not reliably determine domain name ===&lt;br /&gt;
&lt;br /&gt;
Warning:&lt;br /&gt;
 Could not reliably determine the server&#039;s fully qualified domain name&lt;br /&gt;
&lt;br /&gt;
Solution:&lt;br /&gt;
* Force ServerName in apache configs [http://askubuntu.com/questions/256013/could-not-reliably-determine-the-servers-fully-qualified-domain-name]&lt;br /&gt;
 ServerName localhost&lt;br /&gt;
&lt;br /&gt;
=== client denied by server configuration ===&lt;br /&gt;
&lt;br /&gt;
browser:&lt;br /&gt;
 403 Forbidden - You don&#039;t have permission to access / on this server.&lt;br /&gt;
&lt;br /&gt;
Error:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
==&amp;gt; httpd/default-error_log &amp;lt;==&lt;br /&gt;
[Mon Sep 01 21:42:02.273169 2014] [authz_core:error] [pid 11221] [client 174.52.47.54:50675] AH01630: client denied by server configuration: /www/&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add Directory allow permissions: [http://stackoverflow.com/questions/19445686/ubuntu-server-apache-2-4-6-client-denied-by-server-configuration-php-fpm]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
DocumentRoot /www&lt;br /&gt;
&amp;lt;Directory /www&amp;gt;&lt;br /&gt;
  Order allow,deny&lt;br /&gt;
  Allow from all&lt;br /&gt;
&amp;lt;/Directory&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or this worked better for me: [http://stackoverflow.com/questions/19445686/ubuntu-server-apache-2-4-6-client-denied-by-server-configuration-php-fpm] [https://mikegriffin.ie/blog/20140130-authz-core-error-client-denied-by-server-configuration/]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
DocumentRoot /www&lt;br /&gt;
&amp;lt;Directory /www&amp;gt;&lt;br /&gt;
  Require all granted&lt;br /&gt;
&amp;lt;/Directory&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Actually this just worked on the latest Ubuntu system:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;Directory /www/&amp;gt;&lt;br /&gt;
        Options Indexes FollowSymLinks&lt;br /&gt;
        AllowOverride None&lt;br /&gt;
        Require all granted&lt;br /&gt;
&amp;lt;/Directory&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* ClientDeniedByServerConfiguration - Httpd Wiki - https://wiki.apache.org/httpd/ClientDeniedByServerConfiguration&lt;br /&gt;
&lt;br /&gt;
=== permissions missing component path ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
==&amp;gt; httpd/default-error_log &amp;lt;==&lt;br /&gt;
[Mon Sep 01 21:50:09.256120 2014] [core:error] [pid 11511] (13)Permission denied: [client 174.52.47.54:50744] AH00035: access to \&lt;br /&gt;
/index.html denied (filesystem path &#039;/www/index.html&#039;) because search permissions are missing on a component of the path&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== keywords ==&lt;br /&gt;
&lt;br /&gt;
[[Category:Linux]]&lt;br /&gt;
[[Category:Web Development ‎]]&lt;br /&gt;
[[Category:Web]]&lt;br /&gt;
[[Category:HTML]]&lt;br /&gt;
[[Category:Internet]]&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=Python&amp;diff=9861</id>
		<title>Python</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=Python&amp;diff=9861"/>
		<updated>2026-04-27T19:11:56Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: /* Apache CGI */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{subtop}}&lt;br /&gt;
&lt;br /&gt;
== Python ==&lt;br /&gt;
&lt;br /&gt;
Python (programming language) - Wikipedia - http://en.wikipedia.org/wiki/Python_(programming_language)&lt;br /&gt;
: Python is an interpreted, general-purpose high-level programming language whose design philosophy emphasizes code readability. Python aims to combine &amp;quot;remarkable power with very clear syntax&amp;quot;, and its standard library is large and comprehensive. Its use of indentation for block delimiters is unique among popular programming languages.&lt;br /&gt;
: Python supports multiple programming paradigms, primarily but not limited to object-oriented, imperative and, to a lesser extent, functional programming styles. It features a fully dynamic type system and automatic memory management, similar to that of Scheme, Ruby, Perl, and Tcl. Like other dynamic languages, Python is often used as a scripting language, but is also used in a wide range of non-scripting contexts.&lt;br /&gt;
: The reference implementation of Python ([http://en.wikipedia.org/wiki/CPython CPython]) is free and open source software and has a community-based development model, as do all or nearly all of its alternative implementations. CPython is managed by the non-profit Python Software Foundation.&lt;br /&gt;
: Python interpreters are available for many operating systems, and Python programs can be packaged into stand-alone executable code for many systems using various tools.&lt;br /&gt;
&lt;br /&gt;
Author:&lt;br /&gt;
:&amp;quot;Python was conceived in the late 1980s and its implementation was started in December 1989 by &#039;&#039;&#039;[http://www.python.org/~guido/ Guido van Rossum]&#039;&#039;&#039; at CWI in the Netherlands as a successor to the ABC programming language (itself inspired by SETL) capable of exception handling and interfacing with the Amoeba operating system. Van Rossum is Python&#039;s principal author, and his continuing central role in deciding the direction of Python is reflected in the title given to him by the Python community, Benevolent Dictator for Life (BDFL).&amp;quot; [http://en.wikipedia.org/wiki/Python_(programming_language)]&lt;br /&gt;
&lt;br /&gt;
Name:&lt;br /&gt;
:&amp;quot;The language is named after the BBC show “Monty Python’s Flying Circus” and has nothing to do with reptiles. Making references to Monty Python skits in documentation is not only allowed, it is encouraged!&amp;quot; [http://docs.python.org/py3k/tutorial/appetite.html]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
We as people are &amp;quot;Pythonites&amp;quot; [http://raspi.tv/2013/how-to-use-interrupts-with-python-on-the-raspberry-pi-and-rpi-gpio-part-2]&lt;br /&gt;
&lt;br /&gt;
== [http://www.python.org/dev/peps/pep-0020/ The Zen of Python] ==&lt;br /&gt;
&lt;br /&gt;
&amp;quot;The core philosophy of the language is summarized by the document &#039;PEP 20 (The Zen of Python)&#039;&amp;quot; [http://en.wikipedia.org/wiki/Python_%28programming_language%29]&lt;br /&gt;
* PEP 20 -- The Zen of Python - http://www.python.org/dev/peps/pep-0020/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Abstract&lt;br /&gt;
&lt;br /&gt;
    Long time Pythoneer Tim Peters succinctly channels the BDFL&#039;s&lt;br /&gt;
    guiding principles for Python&#039;s design into 20 aphorisms, only 19&lt;br /&gt;
    of which have been written down.&lt;br /&gt;
&lt;br /&gt;
The Zen of Python&lt;br /&gt;
&lt;br /&gt;
    Beautiful is better than ugly.&lt;br /&gt;
    Explicit is better than implicit.&lt;br /&gt;
    Simple is better than complex.&lt;br /&gt;
    Complex is better than complicated.&lt;br /&gt;
    Flat is better than nested.&lt;br /&gt;
    Sparse is better than dense.&lt;br /&gt;
    Readability counts.&lt;br /&gt;
    Special cases aren&#039;t special enough to break the rules.&lt;br /&gt;
    Although practicality beats purity.&lt;br /&gt;
    Errors should never pass silently.&lt;br /&gt;
    Unless explicitly silenced.&lt;br /&gt;
    In the face of ambiguity, refuse the temptation to guess.&lt;br /&gt;
    There should be one-- and preferably only one --obvious way to do it.&lt;br /&gt;
    Although that way may not be obvious at first unless you&#039;re Dutch.&lt;br /&gt;
    Now is better than never.&lt;br /&gt;
    Although never is often better than *right* now.&lt;br /&gt;
    If the implementation is hard to explain, it&#039;s a bad idea.&lt;br /&gt;
    If the implementation is easy to explain, it may be a good idea.&lt;br /&gt;
    Namespaces are one honking great idea -- let&#039;s do more of those!&lt;br /&gt;
&lt;br /&gt;
Easter Egg&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import this&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Other Sources:&lt;br /&gt;
* http://www.python.org/doc/humor/&lt;br /&gt;
* The Zen of Python – as a Poster « CODE POETRY - http://codepoetry.wordpress.com/2010/03/23/the-zen-of-python-as-a-poster/&lt;br /&gt;
** Zen of Python (PDF) http://codepoetry.files.wordpress.com/2010/03/zen-of-python.pdf&lt;br /&gt;
&lt;br /&gt;
== Documentation ==&lt;br /&gt;
&lt;br /&gt;
* Overview — Python v2.7.1 documentation - http://docs.python.org/index.html&lt;br /&gt;
** Download — Python v2.7.1 documentation - http://docs.python.org/download.html&lt;br /&gt;
&lt;br /&gt;
* Overview — Python v3.2 documentation - http://docs.python.org/py3k/&lt;br /&gt;
**  Download — Python v3.2 documentation - http://docs.python.org/py3k/download.html&lt;br /&gt;
&lt;br /&gt;
* PEP 8 -- Style Guide for Python Code - http://www.python.org/dev/peps/pep-0008/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Tutorials ==&lt;br /&gt;
&lt;br /&gt;
* The Python Tutorial — Python v2.7.1 documentation - http://docs.python.org/tutorial/&lt;br /&gt;
&lt;br /&gt;
* Python 101 -- Introduction to Python - http://www.rexx.com/~dkuhlman/python_101/python_101.html&lt;br /&gt;
&lt;br /&gt;
* 4. More Control Flow Tools — Python v2.7.1 documentation - http://docs.python.org/tutorial/controlflow.html&lt;br /&gt;
&lt;br /&gt;
== Linux Installation ==&lt;br /&gt;
&lt;br /&gt;
RHEL Distribution installation:&lt;br /&gt;
 yum -y install python python-setuptools&lt;br /&gt;
&lt;br /&gt;
Ubuntu Distribution installation: [https://help.ubuntu.com/community/Mercurial]&lt;br /&gt;
 # enable &#039;universe&#039; in the sources.list&lt;br /&gt;
 # &amp;quot;Mercurial is included in the Universe repository - activate this repo first&amp;quot;&lt;br /&gt;
 sudo apt-get install mercurial&lt;br /&gt;
&lt;br /&gt;
CentOS 5 Option Recommended Dependencies:&lt;br /&gt;
 yum -y install gcc make sudo readline-devel openssl-devel ncurses-devel zlib-devel gdbm-devel sqlite-devel bzip2-devel tk-devel tcl-devel&lt;br /&gt;
&lt;br /&gt;
 # this leaves: 2.6.6: _bsddb, bsddb185, dl, imageop, sunaudiodev&lt;br /&gt;
 # this leaves: 2.7.1: _bsddb, bsddb185, dl, imageop, sunaudiodev&lt;br /&gt;
 # this leaves: 3.2: none&lt;br /&gt;
&lt;br /&gt;
CentOS 9 Option Recommended Dependencies:&lt;br /&gt;
 # gdbm-devel not found in centos9?&lt;br /&gt;
 yum -y install gcc make sudo readline-devel openssl-devel ncurses-devel zlib-devel sqlite-devel bzip2-devel tk-devel tcl-devel&lt;br /&gt;
&lt;br /&gt;
Ubuntu 12.04 LTS 64bit dependencies:&lt;br /&gt;
 apt-get install gcc make sudo lib64bz2-dev tcl-dev lib64ncurses5-dev libssl-dev libreadline-dev tk-dev libsqlite3-dev libgdbm-dev&lt;br /&gt;
&lt;br /&gt;
 # maybe: lib64readline-dev libsqlite3-dev tk-dev&lt;br /&gt;
&lt;br /&gt;
 # this leaves: 2.7: _bsddb, bsddb185, dl, imageop, sunaudiodev&lt;br /&gt;
&lt;br /&gt;
=== 2.x ===&lt;br /&gt;
&lt;br /&gt;
CentOS dependencies:&lt;br /&gt;
 sudo yum -y install gcc make sudo readline-devel openssl-devel ncurses-devel zlib-devel gdbm-devel sqlite-devel bzip2-devel tk-devel tcl-devel&lt;br /&gt;
&lt;br /&gt;
Ubuntu 12.04 LTS 64bit dependencies:&lt;br /&gt;
 sudo apt-get update&lt;br /&gt;
 sudo apt-get install gcc make sudo lib64bz2-dev tcl-dev lib64ncurses5-dev libssl-dev libreadline-dev tk-dev libsqlite3-dev libgdbm-dev&lt;br /&gt;
&lt;br /&gt;
Ubuntu 24.04 LTS 64bit dependencies:&lt;br /&gt;
 sudo apt-get update&lt;br /&gt;
 sudo apt-get install gcc make sudo libbz2-dev tcl-dev libncurses-dev libssl-dev libreadline-dev tk-dev libsqlite3-dev libgdbm-dev libffi-dev&lt;br /&gt;
 # optional install&lt;br /&gt;
 sudo apt-get install checkinstall&lt;br /&gt;
&lt;br /&gt;
2.7.15:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#  PYVER=2.6.6&lt;br /&gt;
#  PYVER=2.7.5&lt;br /&gt;
#  PYVER=2.7.6&lt;br /&gt;
#  PYVER=2.7.9&lt;br /&gt;
#  PYVER=2.7.10&lt;br /&gt;
#  PYVER=2.7.15&lt;br /&gt;
PYVER=2.7.18&lt;br /&gt;
mkdir -p ~/.src ; cd ~/.src&lt;br /&gt;
wget --no-check-certificate http://www.python.org/ftp/python/$PYVER/Python-$PYVER.tgz&lt;br /&gt;
tar -zvxf Python-$PYVER.tgz&lt;br /&gt;
cd Python-$PYVER&lt;br /&gt;
#  ./configure --prefix=/opt/python-$PYVER&lt;br /&gt;
#  make clean &amp;amp;&amp;amp; make&lt;br /&gt;
./configure --prefix=/opt/python-$PYVER &amp;amp;&amp;amp; make clean &amp;amp;&amp;amp; make&lt;br /&gt;
sudo make install&lt;br /&gt;
&lt;br /&gt;
sudo /opt/python-$PYVER/bin/python -m ensurepip --upgrade&lt;br /&gt;
sudo /opt/python-$PYVER/bin/pip install --upgrade pip&lt;br /&gt;
sudo /opt/python-$PYVER/bin/pip install requests&lt;br /&gt;
&lt;br /&gt;
export PATH=/opt/python-$PYVER/bin:$PATH&lt;br /&gt;
echo -e &amp;quot;\n\nexport PATH=/opt/python-$PYVER/bin:\$PATH\n&amp;quot; &amp;gt;&amp;gt; ~/.bash_profile&lt;br /&gt;
#  echo -e &amp;quot;\n\nexport PATH=/opt/python27/bin:\$PATH\n&amp;quot; &amp;gt;&amp;gt; ~/.bashrc&lt;br /&gt;
&lt;br /&gt;
#  NOTE: remove any old versions from your .bash_profile&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Bootstrapping the pip installer - https://docs.python.org/2/library/ensurepip.html&lt;br /&gt;
&lt;br /&gt;
=== 3.x ===&lt;br /&gt;
&lt;br /&gt;
3.8.16:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#VER=3.7.0&lt;br /&gt;
#VER=3.8.15&lt;br /&gt;
#VER=3.10.9&lt;br /&gt;
VER=3.8.16&lt;br /&gt;
mkdir -p ~/.src ; cd ~/.src&lt;br /&gt;
wget http://www.python.org/ftp/python/${VER}/Python-${VER}.tgz&lt;br /&gt;
tar -zvxf Python-${VER}.tgz&lt;br /&gt;
cd Python-${VER}&lt;br /&gt;
./configure --prefix=/opt/python${VER}&lt;br /&gt;
make&lt;br /&gt;
&lt;br /&gt;
sudo make install&lt;br /&gt;
&lt;br /&gt;
## OPTIONAL alternative install path:&lt;br /&gt;
sudo checkinstall&lt;br /&gt;
## note: &#039;checkinstall&#039; makes a .deb, which you can uninstall with easier, but if you are using --prefix, you do need to&lt;br /&gt;
##       premake the folders&lt;br /&gt;
sudo mkdir -p /opt/python${VER}/bin&lt;br /&gt;
sudo mkdir -p /opt/python${VER}/lib&lt;br /&gt;
shortVER=`echo $VER | cut -d &#039;.&#039; -f 1-2`  # get short version eg. 3.10 from 3.10.9&lt;br /&gt;
sudo mkdir -p /opt/python${VER}/lib/python${shortVER}&lt;br /&gt;
sudo mkdir -p /opt/python${VER}/lib/python${shortVER}/test&lt;br /&gt;
# sudo checkinstall    # hit Y, and enter twice&lt;br /&gt;
## note: older versions have problems with the virtualization of the file system, so do FS Translation = no&lt;br /&gt;
checkinstall --fstrans=no&lt;br /&gt;
&lt;br /&gt;
export PATH=/opt/python${VER}/bin:$PATH&lt;br /&gt;
echo -e &amp;quot;\n\nexport PATH=/opt/python${VER}/bin:\$PATH\n&amp;quot; &amp;gt;&amp;gt; ~/.bash_profile&lt;br /&gt;
&lt;br /&gt;
# have to manually update version&lt;br /&gt;
rm /opt/python${VER}/bin/python&lt;br /&gt;
ln -sfn python3.8 /opt/python${VER}/bin/python&lt;br /&gt;
#cp /opt/python${VER}/bin/python3.8 /opt/python${VER}/bin/python&lt;br /&gt;
&lt;br /&gt;
# DEPENDENCIES&lt;br /&gt;
sudo apt install ...&lt;br /&gt;
yum install libffi-devel openssl-devel&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note, if you want the libraries to be shared (like python-dev):&lt;br /&gt;
 ./configure --enable-shared&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
 VER=3.6.9&lt;br /&gt;
&lt;br /&gt;
 VER=3.6.8&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
3.2.0:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir -p ~/src ; cd ~/src&lt;br /&gt;
wget http://www.python.org/ftp/python/3.2/Python-3.2.tgz&lt;br /&gt;
tar -zvxf Python-3.2.tgz&lt;br /&gt;
cd Python-3.2&lt;br /&gt;
./configure --prefix=/opt/python32&lt;br /&gt;
make&lt;br /&gt;
sudo make install&lt;br /&gt;
&lt;br /&gt;
export PATH=/opt/python32/bin:$PATH&lt;br /&gt;
echo -e &amp;quot;\n\nexport PATH=/opt/python32/bin:\$PATH\n&amp;quot; &amp;gt;&amp;gt; ~/.bash_profile&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3.3.0:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir -p ~/src ; cd ~/src&lt;br /&gt;
wget http://www.python.org/ftp/python/3.3.0/Python-3.3.0.tgz&lt;br /&gt;
tar -zvxf Python-3.3.0.tgz&lt;br /&gt;
cd Python-3.3.0&lt;br /&gt;
./configure --prefix=/opt/python3.3.0&lt;br /&gt;
make&lt;br /&gt;
sudo make install&lt;br /&gt;
&lt;br /&gt;
export PATH=/opt/python3.3.0/bin:$PATH&lt;br /&gt;
echo -e &amp;quot;\n\nexport PATH=/opt/python3.3.0/bin:\$PATH\n&amp;quot; &amp;gt;&amp;gt; ~/.bash_profile&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3.3.4:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir -p ~/.src ; cd ~/.src&lt;br /&gt;
wget http://www.python.org/ftp/python/3.3.4/Python-3.3.4.tgz&lt;br /&gt;
tar -zvxf Python-3.3.4.tgz&lt;br /&gt;
cd Python-3.3.4&lt;br /&gt;
./configure --prefix=/opt/python3.3.4&lt;br /&gt;
make clean&lt;br /&gt;
make&lt;br /&gt;
sudo make install&lt;br /&gt;
&lt;br /&gt;
export PATH=/opt/python3.3.4/bin:$PATH&lt;br /&gt;
echo -e &amp;quot;\n\nexport PATH=/opt/python3.3.4/bin:\$PATH\n&amp;quot; &amp;gt;&amp;gt; ~/.bash_profile&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3.4.0:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir -p ~/.src ; cd ~/.src&lt;br /&gt;
wget http://www.python.org/ftp/python/3.4.0/Python-3.4.0.tgz&lt;br /&gt;
tar -zvxf Python-3.4.0.tgz&lt;br /&gt;
cd Python-3.4.0&lt;br /&gt;
./configure --prefix=/opt/python3.4.0&lt;br /&gt;
make&lt;br /&gt;
sudo make install&lt;br /&gt;
&lt;br /&gt;
export PATH=/opt/python3.4.0/bin:$PATH&lt;br /&gt;
echo -e &amp;quot;\n\nexport PATH=/opt/python3.4.0/bin:\$PATH\n&amp;quot; &amp;gt;&amp;gt; ~/.bash_profile&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== setuptools ===&lt;br /&gt;
&lt;br /&gt;
Purpose: to install pip&lt;br /&gt;
&lt;br /&gt;
Note: required for several &#039;python setup.py install&#039; installations.&lt;br /&gt;
&lt;br /&gt;
Python Package Index : setuptools 0.6c11 - http://pypi.python.org/pypi/setuptools&lt;br /&gt;
&lt;br /&gt;
By Package Manager:&lt;br /&gt;
 yum install python-setuptools&lt;br /&gt;
&lt;br /&gt;
By Source:&lt;br /&gt;
 #VER=2.0.1&lt;br /&gt;
 #VER=2.2&lt;br /&gt;
 VER=3.4.4&lt;br /&gt;
 mkdir -p ~/.src ; cd ~/.src&lt;br /&gt;
 wget --no-check-certificate http://pypi.python.org/packages/source/s/setuptools/setuptools-$VER.tar.gz&lt;br /&gt;
 tar -zvxf setuptools-$VER.tar.gz&lt;br /&gt;
 cd setuptools-$VER&lt;br /&gt;
 # sudo python setup.py install&lt;br /&gt;
 sudo /opt/python-2.7.9/bin/python setup.py install&lt;br /&gt;
&lt;br /&gt;
Fix header:&lt;br /&gt;
 # Only needed on older versions&lt;br /&gt;
 sed -i &#039;s#!/usr/bin/python#!/usr/bin/env python#g&#039; /opt/python279/bin/easy_install&lt;br /&gt;
&lt;br /&gt;
Install pip:&lt;br /&gt;
 sudo /opt/python-2.7.9/bin/easy_install pip&lt;br /&gt;
&lt;br /&gt;
Sample pip usage:&lt;br /&gt;
 sudo /opt/python-2.7.9/bin/pip install paramiko&lt;br /&gt;
&lt;br /&gt;
== IDLE and Interactive Mode ==&lt;br /&gt;
&lt;br /&gt;
Interactive Mode - &amp;quot;When commands are read from a tty, the interpreter is said to be in interactive mode. In this mode it prompts for the next command with the primary prompt, usually three greater-than signs (&amp;gt;&amp;gt;&amp;gt;); for continuation lines it prompts with the secondary prompt, by default three dots (...).&amp;quot; [http://docs.python.org/2/tutorial/interpreter.html#invoking-the-interpreter]&lt;br /&gt;
&lt;br /&gt;
Can use &#039;_&#039; to reference last output:&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; 5 + 6&lt;br /&gt;
 11&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; print _&lt;br /&gt;
 11&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* 2. Using the Python Interpreter — Python v2.7.3 documentation - http://docs.python.org/2/tutorial/interpreter.html&lt;br /&gt;
&lt;br /&gt;
== Python 2.7 EOL ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
DEPRECATION: Python 2.7 will reach the end of its life on January 1st, 2020. Please upgrade your Python as Python 2.7 won&#039;t be maintained after that date. A future version of pip will drop support for Python 2.7.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Show All Python in Path ==&lt;br /&gt;
&lt;br /&gt;
 compgen -c | grep -i &amp;quot;python&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
&lt;br /&gt;
=== Hello World ===&lt;br /&gt;
&lt;br /&gt;
[http://en.wikipedia.org/wiki/Shebang_%28Unix%29 shebang] (also called a hashbang) of Python:&lt;br /&gt;
 #!/usr/bin/env python&lt;br /&gt;
 print &amp;quot;Hello World&amp;quot;&lt;br /&gt;
&lt;br /&gt;
NOTE: can also just use &amp;quot;#!/usr/bin/python&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Standard Script ===&lt;br /&gt;
&lt;br /&gt;
Standard Script:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def main(args):&lt;br /&gt;
  # do logic&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
  sys.exit(main(sys.argv))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Needed for things like pylint&lt;br /&gt;
&lt;br /&gt;
=== White Space ===&lt;br /&gt;
&lt;br /&gt;
Python uses white space to indicate code blocks.  Instead of &#039;&#039;{&#039;&#039; use a &#039;&#039;:&#039;&#039; and indent consistently (4 spaces).&lt;br /&gt;
&lt;br /&gt;
 if a == b:&lt;br /&gt;
     print &#039;equal&#039;&lt;br /&gt;
&lt;br /&gt;
Convert tabs to spaces:&lt;br /&gt;
 sed -i &#039;s/\t/    /g&#039; *.py&lt;br /&gt;
&lt;br /&gt;
Remove trailing whitespace:&lt;br /&gt;
 sed -i &#039;s/\s*$//&#039; *.py&lt;br /&gt;
 sed --in-place &#039;s/[[:space:]]\+$//&#039; fileName&lt;br /&gt;
&lt;br /&gt;
Clean project:&lt;br /&gt;
 # find . -name &amp;quot;*py&amp;quot; -exec dos2unix {} \;&lt;br /&gt;
 # find . -name &amp;quot;*py&amp;quot; -exec sed -i &#039;s/\t/    /g&#039; {} \;&lt;br /&gt;
 # find . -name &amp;quot;*py&amp;quot; -exec sed -i &#039;s/\s*$//&#039; {} \;&lt;br /&gt;
 find . -name &amp;quot;*py&amp;quot; -exec dos2unix {} \; -exec sed -i &#039;s/\t/    /g&#039; {} \; -exec sed -i &#039;s/\s*$//&#039; {} \;&lt;br /&gt;
&lt;br /&gt;
==== Trim Tailing White Space ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sed -e &#039;s/[[:space:]]*$//&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
find . -name &amp;quot;*.py&amp;quot; -exec sed -i -e &#039;s/[[:space:]]*$//&#039; {} \;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ref: [https://stackoverflow.com/questions/369758/how-to-trim-whitespace-from-a-bash-variable]&lt;br /&gt;
&lt;br /&gt;
=== Print ===&lt;br /&gt;
&lt;br /&gt;
print - http://docs.python.org/tutorial/inputoutput.html&lt;br /&gt;
&lt;br /&gt;
Print:  # include new line&lt;br /&gt;
 print(&amp;quot;Hello World&amp;quot;)&lt;br /&gt;
 print &amp;quot;Hello World&amp;quot;   # python 2 only&lt;br /&gt;
&lt;br /&gt;
Suppress new line: [http://stackoverflow.com/questions/493386/how-to-print-in-python-without-newline-or-space]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
print(&#039;#&#039;, end=&#039;&#039;)    # python 3&lt;br /&gt;
print &amp;quot;Hello World&amp;quot;,  # python 2 only (does produce a single separating white space though)&lt;br /&gt;
&lt;br /&gt;
import sys&lt;br /&gt;
sys.stdout.write(&#039;.&#039;)  # no separating white space&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 # flush output&lt;br /&gt;
 # optional, if new line won&#039;t come for some time&lt;br /&gt;
 import sys&lt;br /&gt;
 sys.stdout.flush()&lt;br /&gt;
&lt;br /&gt;
Multiple with separator:&lt;br /&gt;
 print(&amp;quot;hello&amp;quot;, &amp;quot;world&amp;quot;)  # separated by spaces&lt;br /&gt;
 print(&amp;quot;hello&amp;quot;, &amp;quot;world&amp;quot;, sep = &#039;.&#039;)  # separated by period&lt;br /&gt;
&lt;br /&gt;
Formatting:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mystr = &amp;quot;abc&amp;quot;&lt;br /&gt;
myint = 5&lt;br /&gt;
myflt = 3.141592&lt;br /&gt;
print( &amp;quot;%s %d %.3f&amp;quot; % (mystr, myint, myflt) )&lt;br /&gt;
print( &amp;quot;{0} {1} {2}&amp;quot;.format(mystr, myint, myflt) )  # string&#039;s format function (python &amp;gt; 2.7)&lt;br /&gt;
print( &amp;quot;{a} {b} {c}&amp;quot;.format( b = myint, a = mystr, c = myflt) )  # by name&lt;br /&gt;
print( &amp;quot;={a:4s}={b:3d}={c:10.3f}=&amp;quot;.format( b = myint, a = mystr, c = myflt) )  # type and padding&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Padded floating point decimal number: (rounds)&lt;br /&gt;
 print &amp;quot;%06.2f&amp;quot; % 2.319         # &amp;quot;002.32&amp;quot;&lt;br /&gt;
 print &amp;quot;%6.2f&amp;quot; % 2.311          # &amp;quot;  2.31&amp;quot;&lt;br /&gt;
 print &amp;quot;{:06.2f}&amp;quot;.format(2.319) # &amp;quot;002.32&amp;quot;&lt;br /&gt;
 print &amp;quot;{:6.2f}&amp;quot;.format(2.319)  # &amp;quot;  2.32&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 # Python 3 version where var=2.321234&lt;br /&gt;
 print(f&amp;quot;{var:.2f}&amp;quot;)  # &amp;quot;2.32&amp;quot;&lt;br /&gt;
 print(f&amp;quot;{var:6.2f}&amp;quot;)  # &amp;quot;  2.32&amp;quot;&lt;br /&gt;
 print(f&amp;quot;{var:06.2f}&amp;quot;)  # &amp;quot;002.32&amp;quot;&lt;br /&gt;
 print(f&amp;quot;{var:08.2f}&amp;quot;)  # &amp;quot;00002.32&amp;quot;&lt;br /&gt;
 print(f&amp;quot;{var:08.4f}&amp;quot;)  # &amp;quot;002.3212&amp;quot;&lt;br /&gt;
 # Python 3 version where var=2.329 - rounding&lt;br /&gt;
 print(f&amp;quot;{var:06.2f}&amp;quot;)  # &amp;quot;002.33&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Comments ===&lt;br /&gt;
&lt;br /&gt;
 # this is a comment&lt;br /&gt;
 # this is a comment&lt;br /&gt;
 x = y  # this is a comment&lt;br /&gt;
&lt;br /&gt;
Using a non assigned string constant as a comment: (also used for doc strings, not generally recommended)&lt;br /&gt;
 &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
 multi line comment&lt;br /&gt;
 &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;&#039;&lt;br /&gt;
 multi line comment can comment out &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
 &#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This can be used like a C &amp;quot;#if 0&amp;quot; concept to comment out whole sections of code.&lt;br /&gt;
&lt;br /&gt;
Using false block to comment out a block code: (does not ignore bad syntax though)&lt;br /&gt;
 if False:&lt;br /&gt;
    # code in this block is ignored&lt;br /&gt;
&lt;br /&gt;
=== doc strings ===&lt;br /&gt;
&lt;br /&gt;
Using a non assigned string constant as a comment: (also used for doc strings, not generally recommended)&lt;br /&gt;
 &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
 multi line comment&lt;br /&gt;
 &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Help ===&lt;br /&gt;
&lt;br /&gt;
dir - list functions and properties of objects:&lt;br /&gt;
 import math&lt;br /&gt;
 dir(math)  # module&lt;br /&gt;
 dir(dir)   # function&lt;br /&gt;
 dir(&amp;quot;&amp;quot;)    # object  - &amp;quot;&amp;quot;, [], {}, etc...&lt;br /&gt;
 dir(__builtins__)  # built in functions&lt;br /&gt;
 dir()      # list imported objects, and dunder methods&lt;br /&gt;
&lt;br /&gt;
Note: dunder (double under) methods determine special functionality (eg. __add__ for +)&lt;br /&gt;
&lt;br /&gt;
help - manual printout: (class doc string, function doc string, data, etc)&lt;br /&gt;
 import math&lt;br /&gt;
 help(math)    # full module info&lt;br /&gt;
 help(len)     # full function info&lt;br /&gt;
 help([&amp;quot;foo&amp;quot;]) # full object info&lt;br /&gt;
&lt;br /&gt;
Pydoc: (command line, same as &#039;import math, help(math)&#039;&lt;br /&gt;
 $ pydoc math&lt;br /&gt;
&lt;br /&gt;
Documentation String: (aka docstring, doc string)&lt;br /&gt;
 print(math.pow.__doc__)  # module doc string&lt;br /&gt;
 print(len.__doc__)       # function doc string&lt;br /&gt;
&lt;br /&gt;
Object or function type:&lt;br /&gt;
 type(x)&lt;br /&gt;
&lt;br /&gt;
 mylist = []&lt;br /&gt;
 isinstance(mylist, list)  # True&lt;br /&gt;
 type(s) is list           # True&lt;br /&gt;
&lt;br /&gt;
Note: isinstance() and type() not equivalent when objects and subclass get involved&lt;br /&gt;
&lt;br /&gt;
IDLE interactive help:&lt;br /&gt;
 help()&lt;br /&gt;
&lt;br /&gt;
=== Variables ===&lt;br /&gt;
&lt;br /&gt;
Basic Data Types&lt;br /&gt;
 str = &amp;quot;string&amp;quot;  # string&lt;br /&gt;
 num = 5         # integer&lt;br /&gt;
 flt = 5.0       # float&lt;br /&gt;
 nothing = None  # None  (not the same as undefined)&lt;br /&gt;
&lt;br /&gt;
Undefined.  Variables start off in an &#039;undefined&#039; state.  It is always better to initially set the variable to None to avoid this state.  To check if undefined: [http://code.activestate.com/recipes/59892-testing-if-a-variable-is-defined/] [http://code.activestate.com/recipes/59892/]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 try:&lt;br /&gt;
   x&lt;br /&gt;
 except NameError:&lt;br /&gt;
   x = None&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Rules: [http://www.python.org/dev/peps/pep-0008/ PEP8 - Method Names and Instance Variables]&lt;br /&gt;
* any length&lt;br /&gt;
* letters, numbers, underscore&lt;br /&gt;
* first character can&#039;t be number&lt;br /&gt;
* case sensitive&lt;br /&gt;
* cannot use keywords&lt;br /&gt;
&lt;br /&gt;
Multiple assignment:&lt;br /&gt;
 x = y = z = 0              # Zero x, y and z&lt;br /&gt;
 x, y, z = 1, &amp;quot;two&amp;quot;, 3.0    # x = 1, y = &amp;quot;two&amp;quot;, z = 3.0&lt;br /&gt;
&lt;br /&gt;
Swap variables: (done in parallel)&lt;br /&gt;
 a, b = b, a&lt;br /&gt;
&lt;br /&gt;
Unpack variables: (requires equal items on each side)&lt;br /&gt;
 a, b, c = [1, 2, 3]&lt;br /&gt;
&lt;br /&gt;
Other Data Types:&lt;br /&gt;
* tuple&lt;br /&gt;
* list&lt;br /&gt;
* dictionary&lt;br /&gt;
* set&lt;br /&gt;
* objects&lt;br /&gt;
&lt;br /&gt;
Everything in Python is an object that has:&lt;br /&gt;
* identity:  id(obj)&lt;br /&gt;
* type:  type(obj)&lt;br /&gt;
* value:  obj&lt;br /&gt;
** mutable - id() stays the same on modification (dictionary, lists, objects)&lt;br /&gt;
** immutable - id() changes on modification as new object is created (string, integer, tuple)&lt;br /&gt;
&lt;br /&gt;
==== Check if Variable Exists ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
try:&lt;br /&gt;
    a # does a exist in the current namespace&lt;br /&gt;
except NameError:&lt;br /&gt;
    a = 10 # nope&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &#039;a&#039; in vars() or &#039;a&#039; in globals()&lt;br /&gt;
 &#039;a&#039; in vars(__builtins__)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if hasattr(a, &#039;property&#039;):&lt;br /&gt;
    doStuff(a.property)&lt;br /&gt;
else:&lt;br /&gt;
    otherStuff()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ref: [https://stackoverflow.com/questions/1592565/determine-if-variable-is-defined-in-python] [https://stackoverflow.com/questions/610883/how-to-know-if-an-object-has-an-attribute-in-python]&lt;br /&gt;
&lt;br /&gt;
=== Numbers ===&lt;br /&gt;
&lt;br /&gt;
 num = 5&lt;br /&gt;
 print &amp;quot;num: %d&amp;quot; % num&lt;br /&gt;
&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; print &amp;quot;Today&#039;s stock price: %f&amp;quot; % 50.4625   1&lt;br /&gt;
 50.462500&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; print &amp;quot;Today&#039;s stock price: %.2f&amp;quot; % 50.4625 2&lt;br /&gt;
 50.46&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; print &amp;quot;Change since yesterday: %+.2f&amp;quot; % 1.5 3&lt;br /&gt;
 +1.50&lt;br /&gt;
&lt;br /&gt;
Arithmetic:&lt;br /&gt;
 + - * /&lt;br /&gt;
 //  # integer division&lt;br /&gt;
 %   # modulus&lt;br /&gt;
 **  # exponent&lt;br /&gt;
&lt;br /&gt;
Compact Arithmetic:&lt;br /&gt;
 i+=1  # Increment - Note, there is no &#039;i++&#039;&lt;br /&gt;
 i*=2  # Multiply&lt;br /&gt;
 i%=2  # modulus&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
Math Functions:&lt;br /&gt;
 import math&lt;br /&gt;
 math.ceil(x)&lt;br /&gt;
 math.floor(x)&lt;br /&gt;
 math.trunc(x)&lt;br /&gt;
 math.pow(x,y)&lt;br /&gt;
&lt;br /&gt;
 abs(x)  # built in&lt;br /&gt;
&lt;br /&gt;
String interpolation:&lt;br /&gt;
 %% % character&lt;br /&gt;
 %d integer&lt;br /&gt;
 %x hex&lt;br /&gt;
 %X hex (upper)&lt;br /&gt;
 %f float&lt;br /&gt;
 %s string&lt;br /&gt;
&lt;br /&gt;
 x = 1/81&lt;br /&gt;
 print(&#039;value: %.2f&#039; % x)  # 0.01&lt;br /&gt;
 print(&#039;value: %.5f&#039; % x)  # 0.012345&lt;br /&gt;
 print(&#039;%d %d %d&#039; % (1, 2, 3))&lt;br /&gt;
&lt;br /&gt;
Type check:&lt;br /&gt;
 if not isinstance(myvar, (int, float)): ...&lt;br /&gt;
&lt;br /&gt;
=== Strings ===&lt;br /&gt;
&lt;br /&gt;
STRINGS ARE IMMUTABLE!  (to modify convert to a list)&lt;br /&gt;
&lt;br /&gt;
Strings: (String Constants)&lt;br /&gt;
 str = &amp;quot;Hello&amp;quot;&lt;br /&gt;
 str = &#039;Hello&#039;&lt;br /&gt;
 str = &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
   Hello&lt;br /&gt;
   World&lt;br /&gt;
 &amp;quot;&amp;quot;&amp;quot;      # can also use &#039;&#039;&#039;...&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
String literals can span multiple lines: (no wrapping when \ used)&lt;br /&gt;
 hello = &amp;quot;hello\&lt;br /&gt;
 world&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Length:&lt;br /&gt;
 len(&amp;quot;str&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Raw string: (back slashes are not escaped)&lt;br /&gt;
 myrawstr = r&amp;quot;hello\nworld\&lt;br /&gt;
 how are you&amp;quot;&lt;br /&gt;
 myrawstr = r&amp;quot;C:\&amp;quot;  # ERROR - limitation of what won&#039;t be escaped&lt;br /&gt;
&lt;br /&gt;
Concatenation:&lt;br /&gt;
 str = &#039;hot&#039; + &#039;dog&#039;&lt;br /&gt;
 print &amp;quot;Hello&amp;quot; &amp;quot;World&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Can&#039;t concat numbers&lt;br /&gt;
 str = 5 + &#039;test&#039;  # error&lt;br /&gt;
 num = 5&lt;br /&gt;
 str = num + &#039;test&#039;  # error&lt;br /&gt;
 str = str(5) + str(num) + &#039;test&#039;  # ok&lt;br /&gt;
&lt;br /&gt;
Repeated Concatenation:&lt;br /&gt;
 str = 10 * &#039;ha&#039;&lt;br /&gt;
 str = &#039;ha&#039; * 10  # same&lt;br /&gt;
 print &#039;-&#039;*60  # --------------------&lt;br /&gt;
&lt;br /&gt;
String Indexing:&lt;br /&gt;
 s = &#039;hello&#039;&lt;br /&gt;
 print( s[0] )    # is &#039;h&#039;&lt;br /&gt;
 print( s[-1] )   # is &#039;o&#039;&lt;br /&gt;
 print( s[len(s) - 1 ] )  # is also &#039;o&#039;&lt;br /&gt;
&lt;br /&gt;
Modify Strings: [http://stackoverflow.com/questions/1228299/change-one-character-in-a-string-in-python]&lt;br /&gt;
 s[1] = &#039;x&#039;  # ERROR!&lt;br /&gt;
 ERROR: can&#039;t modify string by index&lt;br /&gt;
 &lt;br /&gt;
 # solution:&lt;br /&gt;
 s = list(&amp;quot;Hello World&amp;quot;)&lt;br /&gt;
 s[0] = &#039;C&#039;&lt;br /&gt;
 print( &amp;quot;&amp;quot;.join(s) )&lt;br /&gt;
&lt;br /&gt;
String Slicing:&lt;br /&gt;
 s = &#039;hello&#039;&lt;br /&gt;
 print( s[0:3] )  # &#039;hel&#039;&lt;br /&gt;
 i = 1&lt;br /&gt;
 print( s[i:i+1] )  # &#039;e&#039;&lt;br /&gt;
 print( s[:3] )  # 0:3 &#039;hel&#039;&lt;br /&gt;
 print( s[4:] )  # 4:end &#039;o&#039;&lt;br /&gt;
 print( s[:] )  # start:end &#039;hello&#039;&lt;br /&gt;
 print( s[-2:] )  # -2:end &#039;lo&#039;&lt;br /&gt;
&lt;br /&gt;
For loop:&lt;br /&gt;
 s = &#039;hello&#039;&lt;br /&gt;
 for c in s:&lt;br /&gt;
   print c  # c = &#039;h&#039; first time&lt;br /&gt;
&lt;br /&gt;
Escape characters:&lt;br /&gt;
 \\  \&#039;  \&amp;quot;  \n  \r  \t&lt;br /&gt;
&lt;br /&gt;
Alternate loop:&lt;br /&gt;
 s = &#039;hello&#039;&lt;br /&gt;
 for i in range( len(s) ):&lt;br /&gt;
   print s[i]&lt;br /&gt;
&lt;br /&gt;
Ord and Char (ASCII):&lt;br /&gt;
 ord(&#039;a&#039;)  # 97&lt;br /&gt;
 chr(97)   # &#039;a&#039;&lt;br /&gt;
&lt;br /&gt;
 0-9 : 48-57&lt;br /&gt;
 A-Z : 65-90&lt;br /&gt;
 a-z : 97-122&lt;br /&gt;
&lt;br /&gt;
List Functions:  (dir on any string)&lt;br /&gt;
 dir(&#039;&#039;)&lt;br /&gt;
 dir(str)&lt;br /&gt;
&lt;br /&gt;
Help:&lt;br /&gt;
 help(&#039;&#039;)&lt;br /&gt;
 help(str)&lt;br /&gt;
&lt;br /&gt;
Padding:&lt;br /&gt;
 &amp;quot;a&amp;quot;.rjust(2, &#039;0&#039;)  # &#039;0a&#039;&lt;br /&gt;
 &amp;quot;1&amp;quot;.ljust(4, &#039;0&#039;)  # &#039;1000&#039;&lt;br /&gt;
&lt;br /&gt;
String Test Functions:&lt;br /&gt;
 &amp;quot;HELLO&amp;quot;.isupper()   # True&lt;br /&gt;
 &amp;quot;hello&amp;quot;.islower()   # True&lt;br /&gt;
 &amp;quot;hello&amp;quot;.isalpha()   # True&lt;br /&gt;
 &amp;quot;12.22&amp;quot;.isdigit()   # False (because of &#039;.&#039;)&lt;br /&gt;
 &amp;quot;12.22&amp;quot;.isnumeric() # False (because of &#039;.&#039;)&lt;br /&gt;
 &amp;quot;hel2&amp;quot;.isalnum()    # True&lt;br /&gt;
 &amp;quot;e&amp;quot; in &amp;quot;hello&amp;quot;      # True&lt;br /&gt;
 &amp;quot;hello&amp;quot;.startswith(&#039;he&#039;)  # True&lt;br /&gt;
 &amp;quot;hello&amp;quot;.endswith(&#039;lo&#039;)    # True&lt;br /&gt;
&lt;br /&gt;
Note: To check for floats: [http://stackoverflow.com/questions/354038/how-do-i-check-if-a-string-is-a-number-in-python]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def is_number(s):&lt;br /&gt;
    try:&lt;br /&gt;
        float(s)&lt;br /&gt;
        return True&lt;br /&gt;
    except ValueError:&lt;br /&gt;
        return False&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
String Modify Functions: (sort of... Strings are immutable)&lt;br /&gt;
 &amp;quot;HELLO&amp;quot;.lower()           # &#039;hello&#039;&lt;br /&gt;
 &amp;quot;hello&amp;quot;.upper()           # &#039;HELLO&#039;&lt;br /&gt;
 &amp;quot; hello &amp;quot;.strip()         # &#039;hello&#039; remove leading/tailing whitespace&lt;br /&gt;
 &amp;quot; hello &amp;quot;.lstrip()        # &#039;hello &#039; remove left whitespace&lt;br /&gt;
 &amp;quot; hello &amp;quot;.rstrip()        # &#039; hello&#039; remove right whitespace&lt;br /&gt;
 &amp;quot;www.com&amp;quot;.split(&#039;.&#039;)      # [&#039;www&#039;, &#039;com&#039;]   &amp;lt;- list&lt;br /&gt;
 &amp;quot;www.com&amp;quot;.partition(&#039;.&#039;)  # (&#039;www&#039;, &#039;.&#039;, &#039;com&#039;)  &amp;lt;- tuple&lt;br /&gt;
 &amp;quot;&amp;quot;.join( (&#039;a&#039;,&#039;b&#039;,&#039;c&#039;) )  # &amp;quot;abc&amp;quot;  join strings, list or tuple&lt;br /&gt;
 &amp;quot;-&amp;quot;.join( (&#039;a&#039;,&#039;b&#039;,&#039;c&#039;) ) # &amp;quot;a-b-c&amp;quot;  join with separator&lt;br /&gt;
 &amp;quot;23&amp;quot;.zfill(4)             # &amp;quot;0023&amp;quot;&lt;br /&gt;
&lt;br /&gt;
String Search Functions:&lt;br /&gt;
 &amp;quot;hello&amp;quot;.find(&#039;lo&#039;)   # 3  (-1 on fail)&lt;br /&gt;
 &amp;quot;hello&amp;quot;.index(&#039;lo&#039;)  # 3 (exception on fail)&lt;br /&gt;
 &amp;quot;hello&amp;quot;.rfind(&#039;lo&#039;)  # 3 right to left (-1 on fail)&lt;br /&gt;
 &amp;quot;hello&amp;quot;.rindex(&#039;lo&#039;) # 3 right to left (exception on fail)&lt;br /&gt;
&lt;br /&gt;
Formatting: (form of concatenation)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mystr = &amp;quot;abc&amp;quot;&lt;br /&gt;
myint = 5&lt;br /&gt;
myflt = 3.141592&lt;br /&gt;
print( &amp;quot;%s %d %.3f&amp;quot; % (mystr, myint, myflt) )&lt;br /&gt;
print( &amp;quot;{0} {1} {2}&amp;quot;.format(mystr, myint, myflt) )  # pep 3101 style - string&#039;s format function (python &amp;gt; 2.7)&lt;br /&gt;
print( &amp;quot;{a} {b} {c}&amp;quot;.format( b = myint, a = mystr, c = myflt) )  # by name&lt;br /&gt;
print( &amp;quot;={a:4s}={b:3d}={c:10.3f}=&amp;quot;.format( b = myint, a = mystr, c = myflt) )  # type and padding&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Split multi line string:&lt;br /&gt;
 for line in str.split(&#039;\n&#039;):  print(line)&lt;br /&gt;
 lines = str.splitlines()      # returns list&lt;br /&gt;
 lines = str.splitlines(True)  # returns list (each includes new line characters)&lt;br /&gt;
&lt;br /&gt;
Input a string:&lt;br /&gt;
 name = input(&#039;What is your name: &#039;).strip()  # python 3&lt;br /&gt;
 name = raw_input(&#039;What is your name: &#039;).strip()  # python 2&lt;br /&gt;
&lt;br /&gt;
Leet Speak:&lt;br /&gt;
 leet_table = &#039;&#039;.maketrans(&#039;EIOBT&#039;, &#039;31087&#039;)&lt;br /&gt;
 &#039;BE COOL. SPEAK LEET!&#039;.translate(leet_table)&lt;br /&gt;
&lt;br /&gt;
String Functions:&lt;br /&gt;
 newstr = mystr.strip()             # remove white space on both sides&lt;br /&gt;
 newstr = mystr.rstrip()            # remove white space on right side&lt;br /&gt;
 newstr = mystr.lstrip()            # remove white space on left side&lt;br /&gt;
 newstr = mystr.replace(&#039;\n&#039;, &#039; &#039;)  # replace string with another&lt;br /&gt;
 newstr = mystr.replace(&#039;jello&#039;, &#039;hello&#039;)  # replace string with another&lt;br /&gt;
&lt;br /&gt;
==== String Formatting ====&lt;br /&gt;
&lt;br /&gt;
PyFormat: Using % and .format() for great good! - https://pyformat.info/&lt;br /&gt;
&lt;br /&gt;
===== Zero Padding =====&lt;br /&gt;
&lt;br /&gt;
3 zero padding:&lt;br /&gt;
 &amp;quot;{:03}&amp;quot;.format(1)  # 003&lt;br /&gt;
&lt;br /&gt;
3 zero padding, specify position:&lt;br /&gt;
 &amp;quot;{1:03}&amp;quot;.format(1, 2)  # 002&lt;br /&gt;
&lt;br /&gt;
Old method:&lt;br /&gt;
 &amp;quot;%03d&amp;quot; % 2  # 002&lt;br /&gt;
&lt;br /&gt;
=== chr and ord ===&lt;br /&gt;
&lt;br /&gt;
Ord and Char (ASCII):&lt;br /&gt;
 ord(&#039;a&#039;)  # 97&lt;br /&gt;
 chr(97)   # &#039;a&#039;&lt;br /&gt;
&lt;br /&gt;
=== Range ===&lt;br /&gt;
&lt;br /&gt;
Creates a list of numbers.  Remember: range always ends one less than you want!&lt;br /&gt;
&lt;br /&gt;
Count:&lt;br /&gt;
 ten = 10&lt;br /&gt;
 one = 1&lt;br /&gt;
 range(ten)               # [0,1,...,9]   starts with zero by default&lt;br /&gt;
 range(one, ten + 1)      # [1,...,10]    actually get 1 to 10&lt;br /&gt;
 range(ten, one - 1, -1)  # [10,9,...,1]  count down&lt;br /&gt;
 range(2, 10 + 1, 2)      # [2,4,...,10]  even numbers&lt;br /&gt;
&lt;br /&gt;
=== drange ===&lt;br /&gt;
&lt;br /&gt;
Solution for decimal range() step value:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def drange(start, stop, step):&lt;br /&gt;
    r = start&lt;br /&gt;
    while r &amp;lt; stop:&lt;br /&gt;
        yield r&lt;br /&gt;
    r += step&lt;br /&gt;
&lt;br /&gt;
sub_ten = drange(0.0, 1.0, 0.1)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* floating point - Python decimal range() step value - Stack Overflow - http://stackoverflow.com/questions/477486/python-decimal-range-step-value&lt;br /&gt;
&lt;br /&gt;
=== Casting ===&lt;br /&gt;
&lt;br /&gt;
Convert:&lt;br /&gt;
 float(3)&lt;br /&gt;
 str(85)&lt;br /&gt;
 int(8.6)&lt;br /&gt;
 round(5.5)&lt;br /&gt;
&lt;br /&gt;
Check Type:&lt;br /&gt;
 type(5)     # &amp;lt;class &#039;int&#039;&amp;gt;&lt;br /&gt;
 type(5.0)   # &amp;lt;class &#039;float&#039;&amp;gt;&lt;br /&gt;
 type(&#039;5&#039;)   # &amp;lt;class &#039;str&#039;&amp;gt;&lt;br /&gt;
 type(None)  # &amp;lt;class &#039;NoneType&#039;&amp;gt;&lt;br /&gt;
 type(print) # &amp;lt;class &#039;builtin_function_or_method&#039;&amp;gt;&lt;br /&gt;
 type(())    # &amp;lt;class &#039;tuple&#039;&amp;gt;&lt;br /&gt;
 type([])    # &amp;lt;class &#039;list&#039;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 mytype = int&lt;br /&gt;
 if type(1) is mytype: ...&lt;br /&gt;
&lt;br /&gt;
=== Boolean Logic ===&lt;br /&gt;
&lt;br /&gt;
True and False:&lt;br /&gt;
 bol = True&lt;br /&gt;
 bol = False&lt;br /&gt;
&lt;br /&gt;
Boolean Operators: (in order precedence)&lt;br /&gt;
 a == b&lt;br /&gt;
 a != b&lt;br /&gt;
 not a&lt;br /&gt;
 a and b&lt;br /&gt;
 a or b&lt;br /&gt;
&lt;br /&gt;
Note: Short-circuit evaluated - &#039;and&#039; and &#039;or&#039;&lt;br /&gt;
&lt;br /&gt;
Return Boolean:&lt;br /&gt;
 return myint &amp;gt;= 16&lt;br /&gt;
&lt;br /&gt;
Get Boolean from string: [http://stackoverflow.com/questions/715417/converting-from-a-string-to-boolean-in-python]&lt;br /&gt;
 # Note: no built in way to do this&lt;br /&gt;
&lt;br /&gt;
 myString = &amp;quot;false&amp;quot;&lt;br /&gt;
 val = (myString == &amp;quot;true&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
 True if myString==&amp;quot;True&amp;quot; else False&lt;br /&gt;
&lt;br /&gt;
 s in [&#039;true&#039;, &#039;1&#039;, &#039;t&#039;, &#039;y&#039;, &#039;yes&#039;, &#039;yeah&#039;, &#039;yup&#039;, &#039;certainly&#039;, &#039;uh-huh&#039;]&lt;br /&gt;
&lt;br /&gt;
 def str2bool(v):&lt;br /&gt;
   return v.lower() in (&amp;quot;yes&amp;quot;, &amp;quot;true&amp;quot;, &amp;quot;t&amp;quot;, &amp;quot;1&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
=== None ===&lt;br /&gt;
&lt;br /&gt;
None is Python&#039;s version of NULL or NIL.&lt;br /&gt;
&lt;br /&gt;
None is a singleton (Python only has one copy of None in the interpreter).&lt;br /&gt;
&lt;br /&gt;
 if myvar is None:&lt;br /&gt;
     ...&lt;br /&gt;
&lt;br /&gt;
=== If Conditionals ===&lt;br /&gt;
&lt;br /&gt;
Operators:&lt;br /&gt;
 ==, !=, not, and, or, &amp;lt;, &amp;gt;, &amp;lt;&amp;gt;, &amp;lt;=, &amp;gt;=, in, not in, is, is not&lt;br /&gt;
&lt;br /&gt;
If statement:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if a == b:&lt;br /&gt;
  ...&lt;br /&gt;
elif c &amp;lt; age &amp;lt; d:&lt;br /&gt;
  ...&lt;br /&gt;
else:&lt;br /&gt;
  ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Shorthand conditional: (ternary operator)&lt;br /&gt;
 val = True if a == b else False&lt;br /&gt;
&lt;br /&gt;
is - checks for identical objects - same id()&lt;br /&gt;
 # None is a singleton, so this works great for None&lt;br /&gt;
 if myvar is None:&lt;br /&gt;
     ...&lt;br /&gt;
&lt;br /&gt;
Other shorthand:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def mycmp(x, y):&lt;br /&gt;
  if x &amp;gt; y: return True&lt;br /&gt;
  else: return False&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Switch/Case statement:&lt;br /&gt;
* there is no built in switch/case statement, use &amp;quot;if ... elif ... elif ...&amp;quot; sequence instead&lt;br /&gt;
&lt;br /&gt;
=== For Loop ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;for&#039;&#039; is used for iterating over an iterable sequence (eg. lists, dictionaries, tuples). (for each)&lt;br /&gt;
&lt;br /&gt;
# range(start, end + 1, skip)&lt;br /&gt;
&lt;br /&gt;
 for i in range(10):&lt;br /&gt;
   print(i)  # 0 .. 9&lt;br /&gt;
&lt;br /&gt;
 for i in range(5, 10):&lt;br /&gt;
   print(i)  # 5 .. 9&lt;br /&gt;
&lt;br /&gt;
 for i in range(10, 0, -1):&lt;br /&gt;
   print(i)  # 10 .. 1&lt;br /&gt;
&lt;br /&gt;
 for i in [1, 2, 3]:  # iterate over list&lt;br /&gt;
   print(i)  # 1 2 3&lt;br /&gt;
&lt;br /&gt;
Discard variable: [http://bytes.com/topic/python/answers/757444-loop-without-variable]&lt;br /&gt;
 for _ in range(10):  # repeat and discard variable (good for pep8 check)&lt;br /&gt;
   print &amp;quot;hello world&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 for key in my_dict.keys(): ...&lt;br /&gt;
 for value in my_dict.values(): ...&lt;br /&gt;
 for key, value in my_dict.items(): ...&lt;br /&gt;
&lt;br /&gt;
Compact version:&lt;br /&gt;
 for i in range(10): print(i)    # 0 .. 9&lt;br /&gt;
&lt;br /&gt;
Access index: [http://stackoverflow.com/questions/522563/accessing-the-index-in-python-for-loops]&lt;br /&gt;
 # using enumeration&lt;br /&gt;
 for idx, val in enumerate(mylist):&lt;br /&gt;
   print idx, val&lt;br /&gt;
&lt;br /&gt;
 # using range&lt;br /&gt;
 for ix in range(len(mylist)):&lt;br /&gt;
   print mylist[ix]&lt;br /&gt;
&lt;br /&gt;
 # list comprehension&lt;br /&gt;
 [ (ix, mylist[ix]) for ix in range(len(mylist))]&lt;br /&gt;
&lt;br /&gt;
=== While Loop ===&lt;br /&gt;
&lt;br /&gt;
 i = 0&lt;br /&gt;
 while i &amp;lt; 10:&lt;br /&gt;
   i = i + 1&lt;br /&gt;
&lt;br /&gt;
 while True:&lt;br /&gt;
   ...  # infinite loop&lt;br /&gt;
&lt;br /&gt;
=== Breaking Loops ===&lt;br /&gt;
&lt;br /&gt;
break statement:&lt;br /&gt;
 while True:&lt;br /&gt;
   if s == &#039;done&#039;:&lt;br /&gt;
     break  # jump out of the loop&lt;br /&gt;
   ...&lt;br /&gt;
&lt;br /&gt;
continue statement: (works with while too)&lt;br /&gt;
  for i in range(10):&lt;br /&gt;
    if i == 2:&lt;br /&gt;
      continue  # skip 2&lt;br /&gt;
    ...&lt;br /&gt;
&lt;br /&gt;
=== Functions ===&lt;br /&gt;
&lt;br /&gt;
No return value:  (None)&lt;br /&gt;
 x = print(&#039;&#039;)&lt;br /&gt;
 # x is &#039;None&#039;&lt;br /&gt;
&lt;br /&gt;
Note: specifying no return value is the same as this:&lt;br /&gt;
 return None&lt;br /&gt;
&lt;br /&gt;
No Operation - &#039;pass&#039;:&lt;br /&gt;
 def noop():&lt;br /&gt;
   pass&lt;br /&gt;
&lt;br /&gt;
Function:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def area(radius):&lt;br /&gt;
  &amp;quot;&amp;quot;&amp;quot; This is a doc string &amp;quot;&amp;quot;&amp;quot;   # can be &amp;quot; ... &amp;quot; also...&lt;br /&gt;
  import math&lt;br /&gt;
  return math.pi * radius ** 2&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Function Doc string:&lt;br /&gt;
 print(area.__doc__)&lt;br /&gt;
 foo.func_doc&lt;br /&gt;
&lt;br /&gt;
Function name:&lt;br /&gt;
  foo.func_name&lt;br /&gt;
&lt;br /&gt;
Local variable:&lt;br /&gt;
 name = &amp;quot;old&amp;quot;&lt;br /&gt;
 def cname():&lt;br /&gt;
   name = &amp;quot;new&amp;quot;&lt;br /&gt;
 print(name)  # is still &#039;old&#039;&lt;br /&gt;
&lt;br /&gt;
Global variable:&lt;br /&gt;
 name = &amp;quot;old&amp;quot;&lt;br /&gt;
 def cname():&lt;br /&gt;
   global name&lt;br /&gt;
   name = &amp;quot;new&amp;quot;&lt;br /&gt;
 cname()&lt;br /&gt;
 print(name)  # is now &#039;new&#039;&lt;br /&gt;
&lt;br /&gt;
By convention starting point is: (not required)&lt;br /&gt;
 def main():&lt;br /&gt;
&lt;br /&gt;
Parameters: (with default)&lt;br /&gt;
 def foo(x, y, z = &amp;quot;default&amp;quot;):&lt;br /&gt;
&lt;br /&gt;
Note: don&#039;t use mutable for defaults, as the object is remembered across runs! (unless that is what you want)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# each call to t() will increase list&lt;br /&gt;
def t(foo=[]):&lt;br /&gt;
   foo.append(&#039;1&#039;)&lt;br /&gt;
   print(foo)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# fix mutable issue&lt;br /&gt;
def named_param(a, foo=None):&lt;br /&gt;
  foo = foo or []&lt;br /&gt;
  if not foo:&lt;br /&gt;
    foo.append(a)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Parameters by keyword:&lt;br /&gt;
 def foo(x = &#039;1&#039;, y = &#039;2&#039;, z = &#039;3&#039;):&lt;br /&gt;
   ...&lt;br /&gt;
 foo(y = &#039;a&#039;, x = &#039;b&#039;)   # order is not important with keywords&lt;br /&gt;
&lt;br /&gt;
Trick for optional parameter:&lt;br /&gt;
 def do(x = None):&lt;br /&gt;
   if x == None:&lt;br /&gt;
&lt;br /&gt;
Function tests - functions are callable&lt;br /&gt;
 callable(myfunc)&lt;br /&gt;
&lt;br /&gt;
=== Type Hints ===&lt;br /&gt;
&lt;br /&gt;
: &amp;quot;Note The Python runtime does not enforce function and variable type annotations. They can be used by third party tools such as type checkers, IDEs, linters, etc.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 def surface_area_of_cube(edge_length: float) -&amp;gt; str:&lt;br /&gt;
     return f&amp;quot;The surface area of the cube is {6 * edge_length ** 2}.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Without the hints:&lt;br /&gt;
 def surface_area_of_cube(edge_length):&lt;br /&gt;
     ...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ref: https://docs.python.org/3/library/typing.html&lt;br /&gt;
&lt;br /&gt;
=== Pass ===&lt;br /&gt;
&lt;br /&gt;
Pass is a null operation (noop):&lt;br /&gt;
&lt;br /&gt;
Do nothing, noop, take no action:&lt;br /&gt;
 pass&lt;br /&gt;
&lt;br /&gt;
Great for creating minimal classes:&lt;br /&gt;
 class MyEmptyClass:&lt;br /&gt;
   pass&lt;br /&gt;
&lt;br /&gt;
Greate for making stub functions/methods:&lt;br /&gt;
 def initlog(*args):&lt;br /&gt;
   pass  # remember to implement this!&lt;br /&gt;
&lt;br /&gt;
=== Slice ===&lt;br /&gt;
&lt;br /&gt;
Take take a slice of strings, lists, tuples, etc...&lt;br /&gt;
 a = [0,1,2,3,4,5]&lt;br /&gt;
 a[0]    # 0 - not a slice&lt;br /&gt;
 a[-1]   # 5 - not a slice&lt;br /&gt;
 a[0:1]  # [0]&lt;br /&gt;
 a[1:3]  # [1, 2]&lt;br /&gt;
 a[:2]   # [0, 1]&lt;br /&gt;
 a[:-1]  # [0, 1, 2, 3, 4] - all but last&lt;br /&gt;
 a[2:]   # [2, 3, 4, 5]&lt;br /&gt;
 a[::2]  # [0, 2, 4] - stride&lt;br /&gt;
 a[::-1] # [5, 4, 3, 2, 1, 0] - reverse&lt;br /&gt;
 range(0,10)[::2]  # [0, 2, 4, 6, 8] - stride&lt;br /&gt;
&lt;br /&gt;
 a = &#039;012345&#039;&lt;br /&gt;
 a[1:3]  # &#039;12&#039;&lt;br /&gt;
 a[::2]  # &#039;024&#039;&lt;br /&gt;
&lt;br /&gt;
=== [http://docs.python.org/reference/compound_stmts.html Compound Statements] ===&lt;br /&gt;
&lt;br /&gt;
Compound statements: (generally discouraged)&lt;br /&gt;
 fun1(); fun2(); fun3()&lt;br /&gt;
&lt;br /&gt;
Compound with statements: [http://docs.python.org/reference/compound_stmts.html#the-with-statement]&lt;br /&gt;
 with A() as a, B() as b: ...&lt;br /&gt;
&lt;br /&gt;
 #is equivalent to&lt;br /&gt;
 with A() as a:&lt;br /&gt;
     with B() as b:&lt;br /&gt;
         ...&lt;br /&gt;
&lt;br /&gt;
[http://www.python.org/dev/peps/pep-0343 PEP 0343] - The “with” statement&lt;br /&gt;
&lt;br /&gt;
 f = open(&#039;file&#039;)&lt;br /&gt;
 with f: ...&lt;br /&gt;
&lt;br /&gt;
Try: (quick ignore all exceptions, very dangerous)&lt;br /&gt;
 try: my_broken_function()&lt;br /&gt;
 except: pass&lt;br /&gt;
&lt;br /&gt;
=== Passing Command Line Arguments ===&lt;br /&gt;
&lt;br /&gt;
Parameters are stored in the &#039;sys.argv&#039; variable:&lt;br /&gt;
 import sys&lt;br /&gt;
 print( sys.argv[0] )  # name of script&lt;br /&gt;
 print( sys.argv[1] )  # first argument&lt;br /&gt;
 for arg in sys.argv: print( arg )  # list all arguments&lt;br /&gt;
&lt;br /&gt;
Print script name:&lt;br /&gt;
 os.path.basename(sys.argv[0])&lt;br /&gt;
&lt;br /&gt;
Print path to script:&lt;br /&gt;
 print sys.path[0]&lt;br /&gt;
&lt;br /&gt;
Paths: [http://code.activestate.com/recipes/474083-get-the-path-of-the-currently-executing-python-scr/]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import os,sys&lt;br /&gt;
print &amp;quot;CWD: &amp;quot;,os.getcwd()&lt;br /&gt;
print &amp;quot;Script: &amp;quot;,sys.argv[0]&lt;br /&gt;
print &amp;quot;.EXE: &amp;quot;,os.path.dirname(sys.executable)&lt;br /&gt;
print &amp;quot;Script dir: &amp;quot;, os.path.realpath(os.path.dirname(sys.argv[0]))&lt;br /&gt;
pathname, scriptname = os.path.split(sys.argv[0])&lt;br /&gt;
print &amp;quot;Relative script dir: &amp;quot;,pathname&lt;br /&gt;
print &amp;quot;Script dir: &amp;quot;, os.path.abspath(pathname)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 os.path.realpath(__file__)&lt;br /&gt;
&lt;br /&gt;
 print &#039;sys.argv[0] =&#039;, sys.argv[0]             &lt;br /&gt;
 pathname = os.path.dirname(sys.argv[0])        &lt;br /&gt;
 print &#039;path =&#039;, pathname&lt;br /&gt;
 print &#039;full path =&#039;, os.path.abspath(pathname)&lt;br /&gt;
&lt;br /&gt;
=== Environment Variables ===&lt;br /&gt;
&lt;br /&gt;
 import os&lt;br /&gt;
 a = os.environ.get(&#039;MYVAR&#039;)               # get environment var&lt;br /&gt;
 a = os.environ.get(&#039;MYVAR&#039;,&#039;default&#039;)     # get environment var&lt;br /&gt;
 a = os.environ[&#039;MYVAR&#039;]                   # get environment var&lt;br /&gt;
 os.environ[&#039;MYVAR&#039;] = &#039;something&#039;         # set environment var&lt;br /&gt;
 os.environ.update({&#039;MYVAR&#039;:&#039;something&#039;})  # set environment var&lt;br /&gt;
&lt;br /&gt;
 for env in os.environ:&lt;br /&gt;
   print &amp;quot;%s = %s&amp;quot; % (env, os.environ[env])&lt;br /&gt;
&lt;br /&gt;
 with open(&amp;quot;environment.txt&amp;quot;, &amp;quot;w&amp;quot;) as f:&lt;br /&gt;
   for env in os.environ:&lt;br /&gt;
      f.write(&amp;quot;%s = %s\n&amp;quot; % (env, os.environ[env]))&lt;br /&gt;
&lt;br /&gt;
=== PYTHONPATH ===&lt;br /&gt;
&lt;br /&gt;
Environment Search path:&lt;br /&gt;
 PYTHONPATH=...&lt;br /&gt;
&lt;br /&gt;
From Code:&lt;br /&gt;
 sys.path.append(&#039;...&#039;)&lt;br /&gt;
&lt;br /&gt;
Get site-package directory from shell: [http://stackoverflow.com/questions/122327/how-do-i-find-the-location-of-my-python-site-packages-directory]&lt;br /&gt;
 python -c &amp;quot;from distutils.sysconfig import get_python_lib; print(get_python_lib())&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Import and Modules ===&lt;br /&gt;
&lt;br /&gt;
Import and Modules - http://docs.python.org/tutorial/modules.html&lt;br /&gt;
&lt;br /&gt;
Import module:&lt;br /&gt;
 import package            # standard import&lt;br /&gt;
 import package.code       # nested name space&lt;br /&gt;
 from package import code  # import specifics from module&lt;br /&gt;
 import module             # standard import&lt;br /&gt;
 from math import sin      # import specifics from module&lt;br /&gt;
 from module import myfunc as fun1  # alias function/object&lt;br /&gt;
 import math as other_math # alias module&lt;br /&gt;
 import longname as ln     # alias module&lt;br /&gt;
 from module import *      # BAD BAD BAD!&lt;br /&gt;
&lt;br /&gt;
 import math&lt;br /&gt;
 math.pow(x,y)&lt;br /&gt;
&lt;br /&gt;
Group and organize by:&lt;br /&gt;
* stdlib libraries&lt;br /&gt;
* local libraries&lt;br /&gt;
* 3rd party libraries&lt;br /&gt;
&lt;br /&gt;
Remove import:&lt;br /&gt;
 del math&lt;br /&gt;
&lt;br /&gt;
 from math import *&lt;br /&gt;
 pow(x,y)&lt;br /&gt;
&lt;br /&gt;
 from math import pow&lt;br /&gt;
 pow(x,y)&lt;br /&gt;
&lt;br /&gt;
 import math as math_lib   # rename&lt;br /&gt;
 math_lib.pow(x,y)&lt;br /&gt;
&lt;br /&gt;
List functions in module:&lt;br /&gt;
 import math&lt;br /&gt;
 dir(math)&lt;br /&gt;
&lt;br /&gt;
List all built in functions:&lt;br /&gt;
 dir(__builtins__)&lt;br /&gt;
&lt;br /&gt;
Note: Modules have the extension .py&lt;br /&gt;
&lt;br /&gt;
Simply module Example:&lt;br /&gt;
&lt;br /&gt;
 # mymod.py:&lt;br /&gt;
 def hello():&lt;br /&gt;
   &amp;quot;&amp;quot;&amp;quot; this is a doc string &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
   print &amp;quot;Hello World&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 # Use the module:&lt;br /&gt;
 import mymod&lt;br /&gt;
 mymod.hello():&lt;br /&gt;
&lt;br /&gt;
 # Use everything in the the module, except for names beginning with &#039;_&#039;:  (bad practice!)&lt;br /&gt;
 from mymod import *&lt;br /&gt;
 hello()&lt;br /&gt;
&lt;br /&gt;
 # Use specific functions in the module:&lt;br /&gt;
 from mymod import hello, hi&lt;br /&gt;
 hello()&lt;br /&gt;
&lt;br /&gt;
 # Function assignment:&lt;br /&gt;
 h = mymod.hello&lt;br /&gt;
 h()&lt;br /&gt;
&lt;br /&gt;
 # module name&lt;br /&gt;
 mymod.__name__   # mymod&lt;br /&gt;
 __name__         # used inside of module will print current module or &amp;quot;__main__&amp;quot; if directly called&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Note: careful when building own modules, as the import literally imports and executes the code, so any code not in functions is executed!&lt;br /&gt;
&lt;br /&gt;
Check if being called directly or indirectly:&lt;br /&gt;
 if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
   # execute tests...&lt;br /&gt;
&lt;br /&gt;
Standard Script Setup:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def main(args):&lt;br /&gt;
  # do logic&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
  sys.exit(main(sys.argv))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Easter egg:&lt;br /&gt;
 # The Zen of Python&lt;br /&gt;
 import this&lt;br /&gt;
&lt;br /&gt;
Search path:&lt;br /&gt;
* environment variable &#039;PYTHONPATH&#039;   (on Unix, this is usually .:/usr/local/lib/python)&lt;br /&gt;
* sys.path  (list of paths, initialized to PYTHONPATH)&lt;br /&gt;
** sys.path.append(&#039;path&#039;)&lt;br /&gt;
&lt;br /&gt;
Module folder: [http://stackoverflow.com/questions/391879/organising-my-python-project] [http://stackoverflow.com/questions/279237/python-import-a-module-from-a-folder] [http://stackoverflow.com/questions/72852/how-to-do-relative-imports-in-python]&lt;br /&gt;
 /kenlib/kenmod.py&lt;br /&gt;
 # so you can do &amp;quot;import kenlib.kenmod&amp;quot;&lt;br /&gt;
 # create file &#039;__init__.py&#039; in kenlib/&lt;br /&gt;
&lt;br /&gt;
Check if package exists:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
try:&lt;br /&gt;
    import argparse&lt;br /&gt;
except ImportError:&lt;br /&gt;
    print &amp;gt;&amp;gt; sys.stderr, &amp;quot;Please install argparse from http://code.google.com/p/&lt;br /&gt;
argparse.&amp;quot;&lt;br /&gt;
    exit(1)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== ifmain ===&lt;br /&gt;
&lt;br /&gt;
 if __name__ == &#039;__main__&#039;:&lt;br /&gt;
     sys.exit(main(sys.argv))&lt;br /&gt;
&lt;br /&gt;
 if __name__ == &#039;__main__&#039;:&lt;br /&gt;
     sys.exit(main(sys.argv[1:]) or 0)&lt;br /&gt;
&lt;br /&gt;
=== Lists ===&lt;br /&gt;
&lt;br /&gt;
* Lists can be modified (mutable)&lt;br /&gt;
* Tuples are constant (immutable)&lt;br /&gt;
&lt;br /&gt;
List: (mutable or modifiable)&lt;br /&gt;
 x = []  # empty list&lt;br /&gt;
 x = [5] # singleton list&lt;br /&gt;
&lt;br /&gt;
 s = list(&amp;quot;Hello World&amp;quot;)&lt;br /&gt;
 print(s)  # s = [&#039;H&#039;, &#039;e&#039;, &#039;l&#039;, &#039;l&#039;, &#039;o&#039;, &#039; &#039;, &#039;W&#039;, &#039;o&#039;, &#039;r&#039;, &#039;l&#039;, &#039;d&#039;]&lt;br /&gt;
 s[0] = &#039;X&#039;&lt;br /&gt;
&lt;br /&gt;
 s.append(x)     # append x&lt;br /&gt;
 s.insert(i, x)  # insert x at i&lt;br /&gt;
 del(s[i])       # delete item at i&lt;br /&gt;
 s.sort()        # sort (modify in place!)&lt;br /&gt;
 s.reverse()     # reverse&lt;br /&gt;
 s.index(x)      # index of x in s&lt;br /&gt;
 new = old[:]    # create copy of list&lt;br /&gt;
 new = list(old) # create copy of list&lt;br /&gt;
&lt;br /&gt;
Check if item in list:&lt;br /&gt;
 if x in s: ...&lt;br /&gt;
&lt;br /&gt;
Filter list of strings based on contents: [https://stackoverflow.com/questions/2152898/filtering-a-list-of-strings-based-on-contents]&lt;br /&gt;
 res = [k for k in lst if &#039;ab&#039; in k]&lt;br /&gt;
&lt;br /&gt;
List comprehension&lt;br /&gt;
 [n * n for n in range(1, 11)]   # squares of numbers 1 to 10&lt;br /&gt;
 [c for c in &#039;pizza&#039;]            # list of string &#039;pizza&#039;&lt;br /&gt;
 [c.upper() for c in &#039;pizza&#039;]    # list of string &#039;pizza&#039; uppercase&lt;br /&gt;
 [n for n in nums if n &amp;gt; 0]      # filters out only positive numbers in nums list&lt;br /&gt;
 [fname for fname in os.listdir(path)  # on multiple lines&lt;br /&gt;
    if os.path.isfile(fname)&lt;br /&gt;
    if fname.endswith(&#039;.py&#039;)]&lt;br /&gt;
&lt;br /&gt;
Enumeration&lt;br /&gt;
 for index, value in enumerate(mylist):  print index, value&lt;br /&gt;
&lt;br /&gt;
Length:&lt;br /&gt;
 len(x)&lt;br /&gt;
&lt;br /&gt;
Concatenation:&lt;br /&gt;
 x + s&lt;br /&gt;
 x * 2&lt;br /&gt;
&lt;br /&gt;
Convert list to string:&lt;br /&gt;
 &amp;quot;&amp;quot;.join(mylist)  # no separator&lt;br /&gt;
 &amp;quot; &amp;quot;.join(mylist) # space separator&lt;br /&gt;
 &amp;quot;,&amp;quot;.join(mylist) # comma separator&lt;br /&gt;
&lt;br /&gt;
Test Membership&lt;br /&gt;
 x in s&lt;br /&gt;
&lt;br /&gt;
Multi dimensional list:&lt;br /&gt;
 mylist = [ [0,&amp;quot;hi&amp;quot;], [1,&amp;quot;bye&amp;quot;] ]&lt;br /&gt;
 print( mylist[0][1] )&lt;br /&gt;
&lt;br /&gt;
Sorting: (see lambda)&lt;br /&gt;
 data.sort()  # alpha numerica sort&lt;br /&gt;
 data.reverse()  # alpha numerica sort&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# custom sort&lt;br /&gt;
data = [1, 5, 3, 9]&lt;br /&gt;
def mylistcmp(x, y):&lt;br /&gt;
  if x == y: return 0&lt;br /&gt;
  if x &amp;lt; y:&lt;br /&gt;
    return -1&lt;br /&gt;
  else:  # swap 1 and -1 here to reverse&lt;br /&gt;
    return 1&lt;br /&gt;
&lt;br /&gt;
data.sort(cmp=mylistcmp)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Slices:&lt;br /&gt;
 lst = [&#039;1a&#039;, &#039;2b&#039;, &#039;3c&#039;, &#039;4d&#039;, &#039;5e&#039;, &#039;6f&#039;]&lt;br /&gt;
 lst[0]     # &#039;1a&#039;&lt;br /&gt;
 lst[-1]    # &#039;6f&#039; last item&lt;br /&gt;
 lst[0:2]   # [&#039;1a&#039;, &#039;2b&#039;]&lt;br /&gt;
 lst[0:2] = [&#039;11&#039;, &#039;22&#039;]   # lst = [&#039;11&#039;, &#039;22&#039;, &#039;3c&#039;, &#039;4d&#039;, &#039;5e&#039;, &#039;6f&#039;] - assignment to slice&lt;br /&gt;
 lst[0:2] = []   # remove items&lt;br /&gt;
 lst[0:0] = [&#039;1a&#039;, &#039;2b&#039;]   # insert items (at beginning)&lt;br /&gt;
 lst[-1:-1] = [&#039;7g&#039;, &#039;8h&#039;]   # insert items (at item BEFORE last), not really what you want, use append()&lt;br /&gt;
 lst[-1:] = [&#039;7g&#039;, &#039;8h&#039;]   # replace last item&lt;br /&gt;
 lst[:] = []   # clear entire list&lt;br /&gt;
 del(lst[0:2])  # delete slice items&lt;br /&gt;
&lt;br /&gt;
Note: it is not safe to modify a sequence while being iterated over.  Create a copy first:&lt;br /&gt;
 for x in mylst[:]:  # make a slice copy of the entire list&lt;br /&gt;
   if len(x) &amp;gt; 6: a.insert(0,x)&lt;br /&gt;
&lt;br /&gt;
Make list from tuple:&lt;br /&gt;
 list( range(10) )&lt;br /&gt;
&lt;br /&gt;
Merge multiple lists: [http://www.testingreflections.com/node/view/4930]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def merge(seq):&lt;br /&gt;
    merged = []&lt;br /&gt;
    for s in seq:&lt;br /&gt;
        for x in s:&lt;br /&gt;
            merged.append(x)&lt;br /&gt;
    return merged&lt;br /&gt;
&lt;br /&gt;
# sample usage:&lt;br /&gt;
foo = [[&#039;a&#039;, &#039;b&#039;],[&#039;c&#039;],[&#039;d&#039;, &#039;e&#039;, &#039;f&#039;]]&lt;br /&gt;
print merge(foo)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt;[&#039;a&#039;, &#039;b&#039;, &#039;c&#039;, &#039;d&#039;, &#039;e&#039;, &#039;f&#039;]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Tuple ===&lt;br /&gt;
&lt;br /&gt;
Tuple: (immutable or constant)&lt;br /&gt;
 x = ()    # empty tuple&lt;br /&gt;
 x = (5,)  # singleton tuple&lt;br /&gt;
 x = (5)   # NOTE: integer with parenthesis, not tuple&lt;br /&gt;
 &lt;br /&gt;
 s = tuple(&amp;quot;Hello World&amp;quot;)&lt;br /&gt;
 print(s)  # s = (&#039;H&#039;, &#039;e&#039;, &#039;l&#039;, &#039;l&#039;, &#039;o&#039;, &#039; &#039;, &#039;W&#039;, &#039;o&#039;, &#039;r&#039;, &#039;l&#039;, &#039;d&#039;)&lt;br /&gt;
 # ERROR: s[0] = &#039;X&#039;&lt;br /&gt;
&lt;br /&gt;
Make list from tuple:&lt;br /&gt;
 list( range(10) )&lt;br /&gt;
&lt;br /&gt;
Use in conditionals:&lt;br /&gt;
 if answer in (&#039;y&#039;, &#039;ye&#039;, &#039;yes&#039;): ...&lt;br /&gt;
&lt;br /&gt;
Convert tuple string to tuple: [http://stackoverflow.com/questions/3945856/converting-string-to-tuple-and-adding-to-tuple]&lt;br /&gt;
 x = &amp;quot;(1,2,3)&amp;quot;&lt;br /&gt;
 t = tuple(int(v) for v in re.findall(&amp;quot;[0-9]+&amp;quot;, x))&lt;br /&gt;
&lt;br /&gt;
Another Convert tuple string to tuple: [http://stackoverflow.com/questions/3945856/converting-string-to-tuple-and-adding-to-tuple]&lt;br /&gt;
 import ast&lt;br /&gt;
 ast.literal_eval(&amp;quot;(1,2,3,4)&amp;quot;) # (1,2,3,4)&lt;br /&gt;
&lt;br /&gt;
=== Named Tuple ===&lt;br /&gt;
&lt;br /&gt;
What are &amp;quot;named tuples&amp;quot; in Python? - Stack Overflow - http://stackoverflow.com/questions/2970608/what-are-named-tuples-in-python&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from collections import namedtuple&lt;br /&gt;
Point = namedtuple(&#039;Point&#039;, &#039;x y&#039;)&lt;br /&gt;
pt1 = Point(1.0, 5.0)&lt;br /&gt;
pt2 = Point(2.5, 1.5)&lt;br /&gt;
print p1     # point(x=1, y=5)&lt;br /&gt;
print p1.x   # 1.0&lt;br /&gt;
print p1[0]  # 1.0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Dictionary ===&lt;br /&gt;
&lt;br /&gt;
NOTE: Dictionaries are also known as associative arrays, maps or hash tables.&lt;br /&gt;
&lt;br /&gt;
Dictionary: (mutable or modifiable)&lt;br /&gt;
&lt;br /&gt;
 color = {}                      # empty dictionary&lt;br /&gt;
 color = {&#039;red&#039; : 1, &#039;blue&#039;, 2}&lt;br /&gt;
 print( color[&#039;red&#039;] )           # 1&lt;br /&gt;
 print( color.get(&#039;red&#039;) )       # 1&lt;br /&gt;
 print( color.get(&#039;red&#039;, &#039;default&#039;) )       # red if found, or return &#039;default&#039;&lt;br /&gt;
 color[&#039;green&#039;] = 3              # able to add new item on the fly!&lt;br /&gt;
 &#039;red&#039; in color                  # True - check if index exists&lt;br /&gt;
 del(color[&amp;quot;red&amp;quot;])               # delete item&lt;br /&gt;
 len(color)                      # 2 - count of items&lt;br /&gt;
&lt;br /&gt;
List in dictionary&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
d.setdefault(key,[]).append(member)  # tricky!&lt;br /&gt;
&lt;br /&gt;
# more tricky: set default type as list&lt;br /&gt;
from from collections import defaultdict&lt;br /&gt;
d = defaultdict(list)&lt;br /&gt;
d[key].append(member)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Enumeration:&lt;br /&gt;
 for index, key in enumerate(mylist):  print index, key&lt;br /&gt;
&lt;br /&gt;
functions:&lt;br /&gt;
 d.clear()&lt;br /&gt;
 d.copy()&lt;br /&gt;
 d.get(key)&lt;br /&gt;
 d.get(key, default_val)&lt;br /&gt;
 d.update(e)   # update with (key, value) pairs in e&lt;br /&gt;
 d.setdefault(key, value)  # only update if not exist, and return set value&lt;br /&gt;
&lt;br /&gt;
Views: (adjust on the fly as dictionary changes)&lt;br /&gt;
 d.items()  (key, values)&lt;br /&gt;
 for k, v in d.items(): print(k, v)&lt;br /&gt;
 &lt;br /&gt;
 d.keys()&lt;br /&gt;
 for k in d.keys(): print(k)&lt;br /&gt;
 &lt;br /&gt;
 d.values()&lt;br /&gt;
 for v in d.values(): print(v)&lt;br /&gt;
&lt;br /&gt;
Sorting: (see also lambda)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# custom sort of dictionaries in list&lt;br /&gt;
data = [dict(number=x) for x in &#039;036149&#039;]  # create list of dictionaries&lt;br /&gt;
def mydictcmp(x, y):&lt;br /&gt;
  if x[&#039;number&#039;] == y[&#039;number&#039;]: return 0&lt;br /&gt;
  if x[&#039;number&#039;] &amp;lt; y[&#039;number&#039;]:&lt;br /&gt;
    return -1&lt;br /&gt;
  else:  # swap 1 and -1 here to reverse&lt;br /&gt;
    return 1&lt;br /&gt;
&lt;br /&gt;
# data.sort(cmp=mydictcmp)  # modifies data&lt;br /&gt;
&lt;br /&gt;
new_data = sorted(data, cmp=mydictcmp)  # better solution&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sorting:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
my_dict = {&#039;a&#039;:1, &#039;b&#039;:4, &#039;c&#039;:3, &#039;d&#039;:9}&lt;br /&gt;
my_dict_keys = my_dict.keys()&lt;br /&gt;
&lt;br /&gt;
def my_dict_sort(x, y):&lt;br /&gt;
    if my_dict[x] == my_dict[y]: return 0&lt;br /&gt;
    if my_dict[x] &amp;lt; my_dict[y]: return -1&lt;br /&gt;
    if my_dict[x] &amp;gt; my_dict[y]: return 1&lt;br /&gt;
&lt;br /&gt;
#sorted_my_dict = sorted(my_dict_keys, cmp=my_dict_sort, reverse=True)&lt;br /&gt;
sorted_tuple = sorted(my_dict_keys, cmp=my_dict_sort)&lt;br /&gt;
print &amp;quot;Sorted Dictionary:&amp;quot;&lt;br /&gt;
for key in sorted_tuple:&lt;br /&gt;
    print &amp;quot;%s: %d&amp;quot; % (key, my_dict[key])&lt;br /&gt;
&lt;br /&gt;
# a: 1, c: 3, b: 4, d: 9,&lt;br /&gt;
# reverse: d: 9, b: 4, c: 3, a: 1,&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sort and keys:&lt;br /&gt;
 keys = sorted(mydict.keys())&lt;br /&gt;
&lt;br /&gt;
Sort by value: [http://stackoverflow.com/questions/613183/python-sort-a-dictionary-by-value]&lt;br /&gt;
 import operator&lt;br /&gt;
 x = {1: 2, 3: 4, 4:3, 2:1, 0:0}&lt;br /&gt;
 sorted_x = sorted(x.iteritems(), key=operator.itemgetter(1))&lt;br /&gt;
&lt;br /&gt;
Sort options:&lt;br /&gt;
 # LIST.sort(cmp=None, key=None, reverse=False) -- stable sort *IN PLACE*;&lt;br /&gt;
 # sorted(iterable, cmp=None, key=None, reverse=False)&lt;br /&gt;
&lt;br /&gt;
Another: (works well!)&lt;br /&gt;
 sorted(my_dict.items(), key=lambda x: x[1])&lt;br /&gt;
&lt;br /&gt;
See: http://wiki.python.org/moin/HowTo/Sorting/&lt;br /&gt;
&lt;br /&gt;
=== Sets ===&lt;br /&gt;
&lt;br /&gt;
Sets are special lists with unique values (good for removing duplicates)&lt;br /&gt;
 lst = [1, 1, 6, 8, 1, 5]&lt;br /&gt;
 s = set(lst)&lt;br /&gt;
 print(s)  # set([8, 1, 5, 6])&lt;br /&gt;
 s.add(item)&lt;br /&gt;
 item in s  # true&lt;br /&gt;
 s.remove(item)&lt;br /&gt;
&lt;br /&gt;
Union (return combination of all):&lt;br /&gt;
 s.union(t)&lt;br /&gt;
&lt;br /&gt;
Intersection (return matching):&lt;br /&gt;
 s.intersection(t)&lt;br /&gt;
&lt;br /&gt;
Symmetric Difference (return only items not matching either, inverse of intersection):&lt;br /&gt;
 s.symmetric_difference(t)&lt;br /&gt;
 list( set(mylist).symmetric_difference(set(mylist2)) )&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Operation		   Equivalent	Result&lt;br /&gt;
len(s) 	  				cardinality of set s&lt;br /&gt;
x in s 	  				test x for membership in s&lt;br /&gt;
x not in s 	  			test x for non-membership in s&lt;br /&gt;
s.issubset(t) 		   s &amp;lt;= t       test whether every element in s is in t&lt;br /&gt;
s.issuperset(t) 	   s &amp;gt;= t 	test whether every element in t is in s&lt;br /&gt;
s.union(t) 		   s | t 	new set with elements from both s and t&lt;br /&gt;
s.intersection(t)	   s &amp;amp; t 	new set with elements common to s and t&lt;br /&gt;
s.difference(t) 	   s - t	new set with elements in s but not in t&lt;br /&gt;
s.symmetric_difference(t)  s ^ t 	new set with elements in either s or t but not both&lt;br /&gt;
s.copy() 	  			new set with a shallow copy of s&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* sets — Unordered collections of unique elements - http://docs.python.org/library/sets.html&lt;br /&gt;
&lt;br /&gt;
=== Files ===&lt;br /&gt;
&lt;br /&gt;
Open file, get file descriptor:&lt;br /&gt;
 fd = open(&#039;/dev/null&#039;)&lt;br /&gt;
&lt;br /&gt;
File Modes:&lt;br /&gt;
 &#039;r&#039; read (default)&lt;br /&gt;
 &#039;w&#039; write (truncate and create if needed)&lt;br /&gt;
 &#039;a&#039; append (create if needed)&lt;br /&gt;
 &lt;br /&gt;
 &#039;b&#039; binary&lt;br /&gt;
 &#039;t&#039; text (default)&lt;br /&gt;
 &lt;br /&gt;
 &#039;+&#039; read and write&lt;br /&gt;
&lt;br /&gt;
Common Functions: (fd)&lt;br /&gt;
&lt;br /&gt;
 f.read()       # read whole file to string&lt;br /&gt;
 f.read(n)      # read n bytes from file to string&lt;br /&gt;
 f.readline()   # read single line as string (while loop)&lt;br /&gt;
 f.readlines()  # read all lines to list&lt;br /&gt;
&lt;br /&gt;
 f.write(str)   # write string to file (does not auto include new line)&lt;br /&gt;
 f.writelines(list)  # write list to file (does not auto include new lines)&lt;br /&gt;
&lt;br /&gt;
 f.seek(0)      # seek to start of file&lt;br /&gt;
 f.seek(pos)    # seek to position&lt;br /&gt;
 f.truncate()   # truncate file&lt;br /&gt;
&lt;br /&gt;
 f.close()      # close file (fd)&lt;br /&gt;
 f.closed       # True/False flag that reports if file is closed&lt;br /&gt;
&lt;br /&gt;
Help:&lt;br /&gt;
 help(open(&#039;/dev/null&#039;))&lt;br /&gt;
 pydoc file&lt;br /&gt;
&lt;br /&gt;
Read Text File Line by Line&lt;br /&gt;
 f = open(fname, &#039;r&#039;)  # (&#039;r&#039; optional)&lt;br /&gt;
 for line in f:  # or f.readlines()&lt;br /&gt;
   print(line)&lt;br /&gt;
 f.close()  # optional&lt;br /&gt;
&lt;br /&gt;
Write list to file (with new lines):&lt;br /&gt;
 f.writelines(&#039;\n&#039;.join(mylist))&lt;br /&gt;
&lt;br /&gt;
One liner read whole file:&lt;br /&gt;
 print( open( fname, &#039;r&#039; ).read() )&lt;br /&gt;
&lt;br /&gt;
Write text file:&lt;br /&gt;
 # f = open(fname, &#039;a&#039;)  # append text file&lt;br /&gt;
 f = open(fname, &#039;w&#039;)&lt;br /&gt;
 f.write(&amp;quot;Hello\n&amp;quot;)&lt;br /&gt;
 f.write( str(10) )  # convert numbers to strings first&lt;br /&gt;
 f.writelines([&amp;quot;line one\n&amp;quot;, &amp;quot;line two\n&amp;quot;])&lt;br /&gt;
 f.close&lt;br /&gt;
&lt;br /&gt;
Read binary file:&lt;br /&gt;
 def is_gif(fname):&lt;br /&gt;
   f = open(fname, &#039;br&#039;)  # not sure &#039;b&#039; is correct&lt;br /&gt;
   first4 = tuple(f.read(4))&lt;br /&gt;
   return first4 == (0x47, 0x49, 0x46, 0x38)&lt;br /&gt;
&lt;br /&gt;
Read all characters of file:&lt;br /&gt;
 c = f.read(1)&lt;br /&gt;
 while c:&lt;br /&gt;
   # if c == ... logic&lt;br /&gt;
   c = f.read(1)&lt;br /&gt;
&lt;br /&gt;
Reading file in while loop: [http://ubuntuforums.org/showthread.php?t=1092300]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
f=open(&amp;quot;file&amp;quot;)&lt;br /&gt;
while True:&lt;br /&gt;
  line=f.readline()&lt;br /&gt;
  if not line: break&lt;br /&gt;
  print line  &lt;br /&gt;
f.close()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
with - implicit close - [http://www.python.org/dev/peps/pep-0343/ PEP 343 -- The &amp;quot;with&amp;quot; Statement]: [http://docs.python.org/reference/compound_stmts.html#the-with-statement] (python &amp;gt;= 2.5)&lt;br /&gt;
 with open(&amp;quot;/etc/passwd&amp;quot;) as f:&lt;br /&gt;
   # ..., f.read(), etc&lt;br /&gt;
&lt;br /&gt;
With statement: (promptly close open handle at end of block)&lt;br /&gt;
 with open(fname, &#039;r&#039;) as f:&lt;br /&gt;
   for ...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# eqivalent to:&lt;br /&gt;
f = open(&amp;quot;/etc/passwd&amp;quot;)&lt;br /&gt;
f.__enter__()&lt;br /&gt;
try:&lt;br /&gt;
  ...&lt;br /&gt;
finally:&lt;br /&gt;
  f.__exit__()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
cat: (for grabbing a configuration line)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def cat(filename):&lt;br /&gt;
    with open(filename) as f:&lt;br /&gt;
        return f.readline().strip()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== With ===&lt;br /&gt;
&lt;br /&gt;
PEP 343 -- The &amp;quot;with&amp;quot; Statement - http://www.python.org/dev/peps/pep-0343/&lt;br /&gt;
&lt;br /&gt;
&#039;with&#039; structure:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
with EXPR as VAR:&lt;br /&gt;
  BLOCK&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
translates to:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
VAR = EXPR&lt;br /&gt;
VAR.__enter__()&lt;br /&gt;
try:&lt;br /&gt;
  BLOCK&lt;br /&gt;
finally:&lt;br /&gt;
  VAR.__exit__()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: The &amp;quot;as VAR&amp;quot; part is optional.  Good for locking:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
with locking(myLock):&lt;br /&gt;
  BLOCK&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
with - implicit close - [http://www.python.org/dev/peps/pep-0343/ PEP 343 -- The &amp;quot;with&amp;quot; Statement]: [http://docs.python.org/reference/compound_stmts.html#the-with-statement] (python &amp;gt;= 2.5)&lt;br /&gt;
 with open(&amp;quot;/etc/passwd&amp;quot;) as f:&lt;br /&gt;
   ...&lt;br /&gt;
&lt;br /&gt;
With statement: (promptly close open handle at end of block)&lt;br /&gt;
 with open(fname, &#039;r&#039;) as f:&lt;br /&gt;
   for ...&lt;br /&gt;
&lt;br /&gt;
See also [[#Files]]&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* PEP 343 -- The &amp;quot;with&amp;quot; Statement - http://www.python.org/dev/peps/pep-0343/&lt;br /&gt;
* PEP 340 -- Anonymous Block Statements - http://www.python.org/dev/peps/pep-0340/&lt;br /&gt;
&lt;br /&gt;
=== Try Exception Handling ===&lt;br /&gt;
&lt;br /&gt;
Exception Handling - http://docs.python.org/release/2.6.6/tutorial/errors.html&lt;br /&gt;
&lt;br /&gt;
throw execption:&lt;br /&gt;
 raise [EXCEPTION]&lt;br /&gt;
 raise IOError(&amp;quot;This is a test!&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Catch exceptions:&lt;br /&gt;
 try:&lt;br /&gt;
 except ( [EXCEPTION], [EXCEPTION] ):&lt;br /&gt;
 except [EXCEPTION]:&lt;br /&gt;
 except [EXCEPTION] as err:  # use &amp;quot;[EXCEPTION], err&amp;quot; in python &amp;lt; 2.6&lt;br /&gt;
   print(&amp;quot;Error: {}&amp;quot;.format(err))&lt;br /&gt;
 except:&lt;br /&gt;
   raise   # reraise caught error that is not handled&lt;br /&gt;
 else:     # if no exception caught&lt;br /&gt;
 finally:  # always executed&lt;br /&gt;
&lt;br /&gt;
Note: Usually a good idea to re-raise exception if you don&#039;t handle it (just &#039;raise&#039;)&lt;br /&gt;
&lt;br /&gt;
General Exception: (all exceptions inherit from Exception)&lt;br /&gt;
 try:&lt;br /&gt;
   raise Exception(&#039;spam&#039;, &#039;eggs&#039;)&lt;br /&gt;
 except Exception as e:&lt;br /&gt;
   pass&lt;br /&gt;
&lt;br /&gt;
Custom Exception Class:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class MyError(Exception):&lt;br /&gt;
  &amp;quot;&amp;quot;&amp;quot;My Error Exception&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
class MyException(Exception):&lt;br /&gt;
    pass&lt;br /&gt;
&lt;br /&gt;
rasie MyError(&amp;quot;My Error&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class ValidationError(Exception):&lt;br /&gt;
    def __init__(self, message, Errors):&lt;br /&gt;
&lt;br /&gt;
        # Call the base class constructor with the parameters it needs&lt;br /&gt;
        Exception.__init__(self, message)&lt;br /&gt;
&lt;br /&gt;
        # Now for your custom code...&lt;br /&gt;
        self.Errors = Errors&lt;br /&gt;
    def __str__(self):&lt;br /&gt;
        return &amp;quot;MyErrors - %s&amp;quot; % self.Errors&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Rename standard exception:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Failure(StandardError):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;Exception for unexpected failures.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: a good place to hide the exception classes in the __init__.py file.&lt;br /&gt;
&lt;br /&gt;
==== exception line number ====&lt;br /&gt;
&lt;br /&gt;
Python When I catch an exception, how do I get the type, file, and line number? - Stack Overflow [http://stackoverflow.com/questions/1278705/python-when-i-catch-an-exception-how-do-i-get-the-type-file-and-line-number]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import sys, os&lt;br /&gt;
&lt;br /&gt;
try:&lt;br /&gt;
    raise NotImplementedError(&amp;quot;No error&amp;quot;)&lt;br /&gt;
except Exception as e:&lt;br /&gt;
    exc_type, exc_obj, exc_tb = sys.exc_info()&lt;br /&gt;
    fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]&lt;br /&gt;
    print(exc_type, fname, exc_tb.tb_lineno)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== traceback ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import traceback&lt;br /&gt;
    try:&lt;br /&gt;
    ...&lt;br /&gt;
    except Exception as E:&lt;br /&gt;
        ...&lt;br /&gt;
        print &#039;Traceback: %s&#039;, traceback.format_exc()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Catching multiple exceptions and getting properties from the exception:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import traceback&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
class MyError(Exception):&lt;br /&gt;
  &amp;quot;&amp;quot;&amp;quot;My Error Exception&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
try:&lt;br /&gt;
  #raise ValueError(&amp;quot;a value error&amp;quot;)  # &amp;lt;type &#039;exceptions.ValueError&#039;&amp;gt;&lt;br /&gt;
  raise MyError(&amp;quot;a my error&amp;quot;)         # &amp;lt;class &#039;__main__.MyError&#039;&amp;gt;&lt;br /&gt;
  raise Exception(&amp;quot;won&#039;t be caught&amp;quot;)  # &amp;lt;type &#039;exceptions.Exception&#039;&amp;gt;&lt;br /&gt;
except (ValueError, MyError) as e:&lt;br /&gt;
  print type(e)       # &amp;lt;class &#039;__main__.MyError&#039;&amp;gt;&lt;br /&gt;
  print e             # __str__() = a my error&lt;br /&gt;
  msg = str(e)        # msg = &#039;a my error&#039;&lt;br /&gt;
  print e.__doc__     # My Error Exception&lt;br /&gt;
  print e.__str__()   # a my error&lt;br /&gt;
  print e.__repr__()  # MyError(&#039;a my error&#039;,)&lt;br /&gt;
  print e.args        # (&#039;a my error&#039;,)&lt;br /&gt;
  x = e               # __getitem__() allows args to be unpacked directly&lt;br /&gt;
  # x, y = e          # if two args were passed, use len(e.args) to see count&lt;br /&gt;
&lt;br /&gt;
  # manually print stack trace (import traceback, sys)&lt;br /&gt;
  print &amp;quot;Exception in user code:&amp;quot;&lt;br /&gt;
  print &#039;-&#039;*60&lt;br /&gt;
  traceback.print_exc(file=sys.stdout)&lt;br /&gt;
  # stack_trace = traceback.format_exc()&lt;br /&gt;
  print &#039;-&#039;*60&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Object Oriented Programming ===&lt;br /&gt;
&lt;br /&gt;
Terms:&lt;br /&gt;
* encapsulates&lt;br /&gt;
* inheritance&lt;br /&gt;
* polymorphism&lt;br /&gt;
* method overriding&lt;br /&gt;
&lt;br /&gt;
==== class ====&lt;br /&gt;
&lt;br /&gt;
class animal.py:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Animal(object):  # default &amp;quot;(object)&amp;quot; not required&lt;br /&gt;
  &amp;quot; Animal class &amp;quot;&lt;br /&gt;
  def __init__(self, name):&lt;br /&gt;
    self.name = name       # name is private variable&lt;br /&gt;
    self.__iam = &amp;quot;animal&amp;quot;  # __iam is private variable&lt;br /&gt;
  def __str__(self):       # string representation&lt;br /&gt;
    return &amp;quot;name = &#039;%s&#039;&amp;quot; % (self.name)&lt;br /&gt;
  def __repr__(self):      # object representation (just typing instance in IDLE, or repr())&lt;br /&gt;
    return &#039;Animal(%s)&#039; % str(self)  # returns __str__&lt;br /&gt;
  def speak(self, msg=&#039;Nothing to say&#039;):&lt;br /&gt;
    print(msg)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: if no __str__ defined, but __repr__ is, then:  __str__ = __repr__&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from animal import Animal&lt;br /&gt;
a = Animal(&#039;good&#039;)&lt;br /&gt;
print(a.__doc__)  # Animal class&lt;br /&gt;
print(a)          # name = &#039;good&#039;&lt;br /&gt;
a                 # Animal(name = &#039;good&#039;)&lt;br /&gt;
print(a.name)     # good&lt;br /&gt;
a.speak(&#039;hi&#039;)     # hi&lt;br /&gt;
print(a._Animal__iam)  # animal - access to private variable (shouldn&#039;t do)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
subclass dog.py:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from animal import Animal&lt;br /&gt;
class Dog(Animal):&lt;br /&gt;
  &amp;quot; Dog class &amp;quot;&lt;br /&gt;
  def __init__(self, name):&lt;br /&gt;
    self.name = name      # name is private variable&lt;br /&gt;
    self.__iam = &amp;quot;dog&amp;quot;    # __iam is private variable&lt;br /&gt;
  # NOTICE: no __str__, inherited from super class&lt;br /&gt;
  def __repr__(self):     # override to reflect &amp;quot;dog&amp;quot;&lt;br /&gt;
    return &#039;Dog(%s)&#039; % str(self)  # returns __str__&lt;br /&gt;
  def speak(self, msg=&#039;Nothing to say&#039;):   # override method&lt;br /&gt;
    super(Dog, self).speak(&#039;Dog says: &#039; + msg)     # call super class method&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Subclass usage:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from dog import Dog&lt;br /&gt;
d = Dog(&#039;bad&#039;)&lt;br /&gt;
print(d.__doc__)    # Dog class&lt;br /&gt;
print(d)            # name = &#039;bad&#039;&lt;br /&gt;
d                   # Dog(name = &#039;bad&#039;)&lt;br /&gt;
print(d.name)       # bad&lt;br /&gt;
d.speak(&#039;hi&#039;)       # Dog says: hi&lt;br /&gt;
print(d._Dog__iam)  # dog - access to private variable (shouldn&#039;t do)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Super: [http://stackoverflow.com/questions/576169/understanding-python-super-with-init-methods]&lt;br /&gt;
 # python 3.0&lt;br /&gt;
 super().__init__()&lt;br /&gt;
&lt;br /&gt;
 # python 2.7&lt;br /&gt;
 super(self.__class__, self).__init__()&lt;br /&gt;
 super([CLASSNAME], self).__init__()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Rectangle(Polygon):&lt;br /&gt;
    def __init__(self, id, width, height):&lt;br /&gt;
        #  super(Rectangle, self).__init__(id)&lt;br /&gt;
        super(self.__class__, self).__init__(id)&lt;br /&gt;
        self.shape = (width, height)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Get class name:&lt;br /&gt;
 self.__class__.__name__&lt;br /&gt;
 obj.__class__.__name__&lt;br /&gt;
&lt;br /&gt;
Full name:&lt;br /&gt;
 obj.__module__ + &amp;quot;.&amp;quot; + obj.__class__.__name__&lt;br /&gt;
&lt;br /&gt;
Private variables: (uses name mangling)&lt;br /&gt;
  self.__age&lt;br /&gt;
  # direct access:  _classname__varname  (eg. p._Person__age = 44)&lt;br /&gt;
&lt;br /&gt;
Tests:&lt;br /&gt;
 isinstance(myobj, myclass)  # check if myobj is a class or subclass of myclass &lt;br /&gt;
 issubclass(A, B)  # check if A is subclass of B&lt;br /&gt;
 issubclass(Exception, BaseException)  # True&lt;br /&gt;
&lt;br /&gt;
Multiple Inheritance:  (methods searched in order)&lt;br /&gt;
 class DerviedClass(Base1, Base2, Base3):&lt;br /&gt;
   pass&lt;br /&gt;
&lt;br /&gt;
Standard startup script:&lt;br /&gt;
 class MyClass():&lt;br /&gt;
     ...&lt;br /&gt;
     @classmethod&lt;br /&gt;
     def main(cls, argv=None):&lt;br /&gt;
         ...&lt;br /&gt;
         # return cls() # creator&lt;br /&gt;
 if __name__ == &amp;quot;__main__&amp;quot;;&lt;br /&gt;
     sys.exit(MyClass.main(sys.argv))&lt;br /&gt;
&lt;br /&gt;
Raise an error if a method is not overridden (not implemented)&lt;br /&gt;
    def _get_dist(self):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Find linux disto. Implemented in subclasses.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        raise NotImplementedError&lt;br /&gt;
&lt;br /&gt;
==== Multiple Constructors ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Animal(object):&lt;br /&gt;
&lt;br /&gt;
  def __init__(self, name):&lt;br /&gt;
    self.name = name&lt;br /&gt;
&lt;br /&gt;
  @classmethod&lt;br /&gt;
  def create_fido(cls):&lt;br /&gt;
    return cls(&amp;quot;fido&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Descriptor Classes ====&lt;br /&gt;
&lt;br /&gt;
&amp;quot;In general, a descriptor is an object attribute with “binding behavior”, one whose attribute access has been overridden by methods in the descriptor protocol: __get__(), __set__(), and __delete__(). If any of those methods are defined for an object, it is said to be a descriptor.&amp;quot; [http://docs.python.org/2/reference/datamodel.html#implementing-descriptors]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
object.__get__(self, instance, owner)&lt;br /&gt;
&lt;br /&gt;
    Called to get the attribute of the owner class (class attribute access) or of an instance of that&lt;br /&gt;
    class (instance attribute access). owner is always the owner class, while instance is the instance&lt;br /&gt;
    that the attribute was accessed through, or None when the attribute is accessed through the owner.&lt;br /&gt;
    This method should return the (computed) attribute value or raise an AttributeError exception.&lt;br /&gt;
&lt;br /&gt;
object.__set__(self, instance, value)&lt;br /&gt;
&lt;br /&gt;
    Called to set the attribute on an instance instance of the owner class to a new value, value.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example: [http://stackoverflow.com/questions/3798835/understanding-get-and-set-and-python-descriptors]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Celsius(object):&lt;br /&gt;
    def __init__(self, value=0.0):&lt;br /&gt;
        self.value = float(value)&lt;br /&gt;
    def __get__(self, instance, owner):&lt;br /&gt;
        return self.value&lt;br /&gt;
    def __set__(self, instance, value):&lt;br /&gt;
        self.value = float(value)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
class Temperature(object):&lt;br /&gt;
    celsius = Celsius()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
t = Temperature()&lt;br /&gt;
t.celsius = 5    # calls Celsius.__set__&lt;br /&gt;
print t.celsius  # calls Celsius.__get__&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: Also appears in &#039;pydoc&#039; under &amp;quot;Data descriptors defined here&amp;quot; with object&#039;s docstring.  Trick: the __doc__ can be overridden in the __init__ method, which makes for dynamic docstrings!&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* Descriptor HowTo Guide — Python v2.7.5 documentation - http://docs.python.org/2/howto/descriptor.html&lt;br /&gt;
* 3.4.2.2. Implementing Descriptors¶ - 3. Data model — Python v2.7.5 documentation - http://docs.python.org/2/reference/datamodel.html#implementing-descriptors&lt;br /&gt;
&lt;br /&gt;
=== [http://docs.python.org/reference/simple_stmts.html#the-exec-statement exec code] ===&lt;br /&gt;
&lt;br /&gt;
DANGEROUS!&lt;br /&gt;
&lt;br /&gt;
Execute code in string:&lt;br /&gt;
 exec( &#039;print(&amp;quot;hi&amp;quot;)&#039; )&lt;br /&gt;
&lt;br /&gt;
Example of executing a startup script for IDLE:&lt;br /&gt;
 if os.path.isfile(&#039;.pythonrc.py&#039;): exec(open(&#039;.pythonrc.py&#039;).read())&lt;br /&gt;
&lt;br /&gt;
 import os&lt;br /&gt;
 filename = os.environ.get(&#039;PYTHONSTARTUP&#039;)&lt;br /&gt;
 if filename and os.path.isfile(filename):&lt;br /&gt;
   exec(open(filename).read())&lt;br /&gt;
&lt;br /&gt;
=== eval ===&lt;br /&gt;
&lt;br /&gt;
VERY DANGEROUS&lt;br /&gt;
&lt;br /&gt;
Will execute a string as though it were pure python code!&lt;br /&gt;
&lt;br /&gt;
 eval(&amp;quot;print &#039;hello&#039;&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
=== Common Header Format ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
__author__ = &amp;quot;software team&amp;quot;&lt;br /&gt;
__date__ =&amp;quot;$Feb 15, 2011 1:42:17 PM$&amp;quot;&lt;br /&gt;
__version__ = &amp;quot;1.1.0.441 bandelier@66d9fe1edf3e&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Next should be authorship information. This information should follow this format:&lt;br /&gt;
&lt;br /&gt;
__author__ = &amp;quot;Rob Knight, Gavin Huttley, and Peter Maxwell&amp;quot;&lt;br /&gt;
__copyright__ = &amp;quot;Copyright 2007, The Cogent Project&amp;quot;&lt;br /&gt;
__credits__ = [&amp;quot;Rob Knight&amp;quot;, &amp;quot;Peter Maxwell&amp;quot;, &amp;quot;Gavin Huttley&amp;quot;,&lt;br /&gt;
                    &amp;quot;Matthew Wakefield&amp;quot;]&lt;br /&gt;
__license__ = &amp;quot;GPL&amp;quot;&lt;br /&gt;
__version__ = &amp;quot;1.0.1&amp;quot;&lt;br /&gt;
__maintainer__ = &amp;quot;Rob Knight&amp;quot;&lt;br /&gt;
__email__ = &amp;quot;rob@spot.colorado.edu&amp;quot;&lt;br /&gt;
__status__ = &amp;quot;Production&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Source: Python Coding Guidelines - http://bayes.colorado.edu/PythonGuidelines.html&lt;br /&gt;
&lt;br /&gt;
These will show up in the help() like such:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Help on module test:&lt;br /&gt;
&lt;br /&gt;
NAME&lt;br /&gt;
    test&lt;br /&gt;
&lt;br /&gt;
FILE&lt;br /&gt;
    /home/kenneth/test.py&lt;br /&gt;
&lt;br /&gt;
FUNCTIONS&lt;br /&gt;
    test()&lt;br /&gt;
&lt;br /&gt;
DATA&lt;br /&gt;
    __author__ = &#039;test author&#039;&lt;br /&gt;
    __version__ = &#039;1.0&#039;&lt;br /&gt;
&lt;br /&gt;
VERSION&lt;br /&gt;
    1.0&lt;br /&gt;
&lt;br /&gt;
AUTHOR&lt;br /&gt;
    test author&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* Python: What is the common header format? - Stack Overflow - http://stackoverflow.com/questions/1523427/python-what-is-the-common-header-format&lt;br /&gt;
&lt;br /&gt;
=== Common Environment Variables ===&lt;br /&gt;
&lt;br /&gt;
 Command line and environment — Python v2.7.2 documentation - http://docs.python.org/using/cmdline.htm&lt;br /&gt;
&lt;br /&gt;
PYTHONUNBUFFERED&lt;br /&gt;
: If this is set to a non-empty string it is equivalent to specifying the -u option. [http://docs.python.org/using/cmdline.html#envvar-PYTHONUNBUFFERED]&lt;br /&gt;
: -u - Force stdin, stdout and stderr to be totally unbuffered. On systems where it matters, also put stdin, stdout and stderr in binary mode.&lt;br /&gt;
* See also stdout - Python output buffering - Stack Overflow - http://stackoverflow.com/questions/107705/python-output-buffering&lt;br /&gt;
 export PYTHONUNBUFFERED=1&lt;br /&gt;
 set PYTHONUNBUFFERED=1&lt;br /&gt;
&lt;br /&gt;
PYTHONVERBOSE&lt;br /&gt;
:If this is set to a non-empty string it is equivalent to specifying the -v option. If set to an integer, it is equivalent to specifying -v multiple times.&lt;br /&gt;
: -v - Print a message each time a module is initialized, showing the place (filename or built-in module) from which it is loaded.&lt;br /&gt;
 export PYTHONVERBOSE=1&lt;br /&gt;
 set PYTHONVERBOSE=1&lt;br /&gt;
&lt;br /&gt;
PYTHONPATH&lt;br /&gt;
: Augment the default search path for module files. The format is the same as the shell’s PATH: one or more directory pathnames separated by os.pathsep (e.g. colons on Unix or semicolons on Windows). Non-existent directories are silently ignored. [http://docs.python.org/using/cmdline.html#envvar-PYTHONPATH]&lt;br /&gt;
 export PYTHONPATH=/path1/:path2/&lt;br /&gt;
 set PYTHONPATH=C:\path1\;C:\path2\&lt;br /&gt;
&lt;br /&gt;
=== Queue ===&lt;br /&gt;
&lt;br /&gt;
Good for threading.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;The Queue module implements multi-producer, multi-consumer queues. It is especially useful in threaded programming when information must be exchanged safely between multiple threads. The Queue class in this module implements all the required locking semantics.&amp;quot; [http://docs.python.org/2/library/queue.html]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import Queue&lt;br /&gt;
&lt;br /&gt;
bucket = Queue.Queue()&lt;br /&gt;
bucket.put(&amp;quot;something&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
while True:&lt;br /&gt;
    try:&lt;br /&gt;
        item = bucket.get(block=False)&lt;br /&gt;
    except Queue.Empty:&lt;br /&gt;
        pass&lt;br /&gt;
    else:&lt;br /&gt;
        # do stuff with queue&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Important methods:&lt;br /&gt;
  Queue.qsize()&lt;br /&gt;
  Queue.empty()&lt;br /&gt;
  Queue.put(item[, block[, timeout]])&lt;br /&gt;
  Queue.get([block[, timeout]])&lt;br /&gt;
&lt;br /&gt;
-&lt;br /&gt;
&lt;br /&gt;
Example: http://docs.python.org/2/library/queue.html&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def worker():&lt;br /&gt;
    while True:&lt;br /&gt;
        item = q.get()&lt;br /&gt;
        do_work(item)&lt;br /&gt;
        q.task_done()&lt;br /&gt;
&lt;br /&gt;
q = Queue()&lt;br /&gt;
for i in range(num_worker_threads):&lt;br /&gt;
     t = Thread(target=worker)&lt;br /&gt;
     t.daemon = True&lt;br /&gt;
     t.start()&lt;br /&gt;
&lt;br /&gt;
for item in source():&lt;br /&gt;
    q.put(item)&lt;br /&gt;
&lt;br /&gt;
q.join()       # block until all tasks are done&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
-&lt;br /&gt;
&lt;br /&gt;
&amp;quot;The module implements three types of queue, which differ only in the order in which the entries are retrieved. In a FIFO queue, the first tasks added are the first retrieved. In a LIFO queue, the most recently added entry is the first retrieved (operating like a stack). With a priority queue, the entries are kept sorted (using the heapq module) and the lowest valued entry is retrieved first.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Queue Types:&lt;br /&gt;
  class Queue.Queue(maxsize=0)          # FIFO Queue&lt;br /&gt;
  class Queue.LifoQueue(maxsize=0)      # LIFO Queue&lt;br /&gt;
  class Queue.PriorityQueue(maxsize=0)  # Priority Queue&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* 8.10. Queue — A synchronized queue class — Python v2.7.5 documentation - http://docs.python.org/2/library/queue.html&lt;br /&gt;
&lt;br /&gt;
== Recipes ==&lt;br /&gt;
&lt;br /&gt;
=== Remove Numbers from String ===&lt;br /&gt;
&lt;br /&gt;
Using list comprehension: [http://stackoverflow.com/questions/12851791/removing-numbers-from-string]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
result = &#039;&#039;.join([i for i in s if not i.isdigit()])&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Using pattern matching:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; re.compile(r&#039;\D+&#039;).findall(&amp;quot;test 1234 test 1234&amp;quot;)&lt;br /&gt;
[&#039;test &#039;, &#039; test &#039;]&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; re.compile(r&amp;quot;\d&amp;quot;).sub(&amp;quot;&amp;quot;, &amp;quot;test 1234 test 1234&amp;quot;)&lt;br /&gt;
&#039;test  test &#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Retry Wrapper ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import functool&lt;br /&gt;
class SomethingRetry:&lt;br /&gt;
&lt;br /&gt;
    def retry_with_backoff(retries: int, base_delay: float, exceptions: tuple[type[Exception], ...] = (Exception,)) -&amp;gt; callable:&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Retries a function with exponential backoff, doubling on each attempt.&lt;br /&gt;
        Arguments:&lt;br /&gt;
            retries: Number of retry attempts.&lt;br /&gt;
            base_delay: Initial delay between retries in seconds.&lt;br /&gt;
            exceptions: Tuple of exceptions to catch and retry.&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
        def decorator(func):&lt;br /&gt;
            @functools.wraps(func)&lt;br /&gt;
            def wrapper(*args, **kwargs):&lt;br /&gt;
                for attempt in range(1, retries + 1):&lt;br /&gt;
                    try:&lt;br /&gt;
                        return func(*args, **kwargs)&lt;br /&gt;
                    except exceptions as e:&lt;br /&gt;
                        print(f&amp;quot;Warning: Attempt {attempt} failed with error: {e}&amp;quot;)&lt;br /&gt;
                        if attempt == retries:&lt;br /&gt;
                            print(&amp;quot;Error: All retry attempts failed.&amp;quot;)&lt;br /&gt;
                            raise&lt;br /&gt;
                        sleep_time = base_delay * (2 ** (attempt - 1))&lt;br /&gt;
                        print(f&amp;quot;Notice: Retrying in {sleep_time} seconds...&amp;quot;)&lt;br /&gt;
                        time.sleep(sleep_time)&lt;br /&gt;
            return wrapper&lt;br /&gt;
        return decorator&lt;br /&gt;
&lt;br /&gt;
    @retry_with_backoff(retries=6, base_delay=10, exceptions=(Exception,))&lt;br /&gt;
    def do_something(self, sample_param: str):&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Standard Libraries ==&lt;br /&gt;
&lt;br /&gt;
=== user input ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
line = raw_input()  # Python 2&lt;br /&gt;
# line = input()    # Python 2&lt;br /&gt;
line = input(&#039;What is your name: &#039;)&lt;br /&gt;
print(&amp;quot;: &amp;quot; + line.strip() + &amp;quot; :&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== sys - stdout stderr stdin ===&lt;br /&gt;
&lt;br /&gt;
STDOUT:&lt;br /&gt;
 import sys&lt;br /&gt;
 sys.stdout.write(&amp;quot;Hello &amp;quot;)  # does not write new line&lt;br /&gt;
 sys.stdout.write(&amp;quot;World\n&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
STDERR:&lt;br /&gt;
 import sys&lt;br /&gt;
 sys.stderr.write(&amp;quot;ERROR!\n&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
STDIN:&lt;br /&gt;
 import sys&lt;br /&gt;
 line = sys.stdin.readline()&lt;br /&gt;
&lt;br /&gt;
 line = input()   # use raw_input() in Python 2&lt;br /&gt;
 line = input(&#039;What is your name: &#039;)&lt;br /&gt;
 print(&amp;quot;: &amp;quot; + line.strip() + &amp;quot; :&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Read piped stdin line by line: [http://stackoverflow.com/questions/1450393/how-do-you-read-from-stdin-in-python]&lt;br /&gt;
 # cat /etc/passwd | ./readlines.py     # linux&lt;br /&gt;
 # type file.txt | python readlines.py  # windows&lt;br /&gt;
&lt;br /&gt;
 # fileinput.input() - returns fileinput object which is iterative&lt;br /&gt;
 import fileinput&lt;br /&gt;
 for line in fileinput.input():&lt;br /&gt;
     print(&amp;quot;: &amp;quot; + line + &amp;quot; :&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
 # sys.stdin.readlines() - returns list of strings&lt;br /&gt;
 import sys&lt;br /&gt;
 for line in sys.stdin.readlines():&lt;br /&gt;
     print(&amp;quot;: &amp;quot; + line + &amp;quot; :&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
 # sys.stdin - returns object which is iterative&lt;br /&gt;
 import sys&lt;br /&gt;
 for line in sys.stdin:&lt;br /&gt;
     print(&amp;quot;: &amp;quot; + line + &amp;quot; :&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
 # ugly while loop: [http://ubuntuforums.org/showthread.php?t=1092300]&lt;br /&gt;
 while True:&lt;br /&gt;
     try:&lt;br /&gt;
         s = raw_input(&amp;quot;Say something &amp;quot;)&lt;br /&gt;
     except EOFError:&lt;br /&gt;
         break&lt;br /&gt;
     print &amp;quot;: %s&amp;quot; % s&lt;br /&gt;
&lt;br /&gt;
Check if stdin has any waiting data: [http://stackoverflow.com/questions/3762881/how-do-i-check-if-stdin-has-some-data]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import sys&lt;br /&gt;
import select&lt;br /&gt;
&lt;br /&gt;
# if select.select([sys.stdin,],[],[],0.0)[0]:  # alternative old method&lt;br /&gt;
&lt;br /&gt;
if not sys.stdin.isatty():&lt;br /&gt;
    print &amp;quot;Have data!&amp;quot;&lt;br /&gt;
    print sys.stdin.readlines()&lt;br /&gt;
else:&lt;br /&gt;
    print &amp;quot;No data&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if len(sys.argv) &amp;gt; 1:&lt;br /&gt;
    message = &#039; &#039;.join(sys.argv[1:])&lt;br /&gt;
elif not sys.stdin.isatty():&lt;br /&gt;
    # read from pipe in&lt;br /&gt;
    message = sys.stdin.readline()&lt;br /&gt;
else:&lt;br /&gt;
    # read from user&lt;br /&gt;
    sys.stdout.write(&amp;quot;Message: &amp;quot;)&lt;br /&gt;
    message = raw_input().strip()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [http://docs.python.org/library/re.html Regular Expressions] ===&lt;br /&gt;
&lt;br /&gt;
Import:&lt;br /&gt;
 import re  # user regular expressions&lt;br /&gt;
&lt;br /&gt;
Match vs Search:&lt;br /&gt;
 re.match(&amp;quot;cde&amp;quot;, &amp;quot;abcdef&amp;quot;)  # no match (match searches beginning of string, first match)&lt;br /&gt;
 re.match(&amp;quot;abc&amp;quot;, &amp;quot;abcdef&amp;quot;)  # match (match searches beginning of string, first match)&lt;br /&gt;
 re.search(&amp;quot;cd&amp;quot;, &amp;quot;abcdef&amp;quot;)  # match (matches any location, first match)&lt;br /&gt;
&lt;br /&gt;
Both re.match() and re.search() return objects that are not intuitive to use.  You can check the object&#039;s group() method for what matched, but I prefer re.findall().&lt;br /&gt;
&lt;br /&gt;
Match:&lt;br /&gt;
 s = &#039;done&#039;&lt;br /&gt;
 if re.match(&#039;done|quit&#039;, s) != None  # True&lt;br /&gt;
&lt;br /&gt;
Search:&lt;br /&gt;
 s = &#039;done&#039;&lt;br /&gt;
 if re.search(&#039;do&#039;, s) != None  # True&lt;br /&gt;
&lt;br /&gt;
Replace:&lt;br /&gt;
 msg = &#039;jello world&#039;&lt;br /&gt;
 msg = re.sub(&#039;jello&#039;, &#039;hello&#039;, msg)&lt;br /&gt;
&lt;br /&gt;
For case intensive searches append 3rd parameter &amp;quot;re.I&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Find all:&lt;br /&gt;
 re.findall(&amp;quot;[a-z]+&amp;quot;, &amp;quot;aaa111bbb222&amp;quot;)       # [&#039;aaa&#039;, &#039;bbb&#039;]&lt;br /&gt;
 re.findall(&amp;quot;111([a-z]+)&amp;quot;, &amp;quot;aaa111bbb222&amp;quot;)  # [&#039;bbb&#039;]&lt;br /&gt;
 re.findall(&amp;quot;hello&amp;quot;, &amp;quot;HELLO&amp;quot;, re.I)         # [&#039;HELLO&#039;] - Case Insensitive&lt;br /&gt;
&lt;br /&gt;
Split:&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; re.split(&#039;[a-z]+&#039;,&#039;111aaa222bbb&#039;)&lt;br /&gt;
 [&#039;111&#039;, &#039;222&#039;, &#039;&#039;]&lt;br /&gt;
&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; re.split(&#039;([a-z]+)&#039;,&#039;111aaa222bbb&#039;)  # parenthesis cause return of all&lt;br /&gt;
 [&#039;111&#039;, &#039;aaa&#039;, &#039;222&#039;, &#039;bbb&#039;, &#039;&#039;]&lt;br /&gt;
&lt;br /&gt;
Replacement Substitution:&lt;br /&gt;
 # re.sub(pattern, repl, string[, count, flags])&lt;br /&gt;
 re.sub(r&#039;\\&#039;, r&#039;/&#039;, r&#039;\\data\files&#039;)&lt;br /&gt;
&lt;br /&gt;
Compiled regular express for repeated use: (performance)&lt;br /&gt;
 valid = re.compile(r&amp;quot;[0-9]+&amp;quot;)&lt;br /&gt;
 valid.match(&amp;quot;aaa111bbb&amp;quot;)               # not valid&lt;br /&gt;
 match = valid.search(&amp;quot;aaa111bbb222&amp;quot;)   # valid&lt;br /&gt;
 print(match.group())                   # what matched: &#039;111&#039;&lt;br /&gt;
&lt;br /&gt;
=== Date and Time ===&lt;br /&gt;
&lt;br /&gt;
Sleep in seconds:&lt;br /&gt;
 import time&lt;br /&gt;
 time.sleep(seconds)&lt;br /&gt;
&lt;br /&gt;
Use the following functions to convert between time representations:&lt;br /&gt;
&amp;lt;table border=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;From&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;To&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Use&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;seconds since the epoch&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;struct_time in UTC&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;gmtime()&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;seconds since the epoch&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;struct_time in local time&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;localtime()&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;struct_time in UTC&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;seconds since the epoch&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;calendar.timegm()&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;struct_time in local time&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;seconds since the epoch&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;mktime()&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Date formats:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; time.strftime(&amp;quot;%Y-%m-%d %H:%M:%S&amp;quot;, time.localtime())&lt;br /&gt;
&#039;2014-04-04 12:22:43&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; time.time()&lt;br /&gt;
1396635763.0581281&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; datetime.datetime.now()&lt;br /&gt;
datetime.datetime(2014, 4, 4, 12, 22, 43, 58456)&lt;br /&gt;
# datetime(year, month, day, hour, minute, second, microsecond)&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; time.localtime()&lt;br /&gt;
time.struct_time(tm_year=2014, tm_mon=4, tm_mday=4, tm_hour=12, tm_min=22, tm_sec=43, tm_wday=4, tm_yday=94, tm_isdst=1)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Current epoch time:&lt;br /&gt;
 int(time.time())&lt;br /&gt;
&lt;br /&gt;
Time zone offset:&lt;br /&gt;
 standard_tz_offset = - time.timezone / 3600  # 7&lt;br /&gt;
 daylight_tz_offset = - time.altzone / 3600  # 6&lt;br /&gt;
&lt;br /&gt;
Is daylight saving time: [http://stackoverflow.com/questions/2881025/python-daylight-savings-time]&lt;br /&gt;
 import time&lt;br /&gt;
 time.localtime()&lt;br /&gt;
 _.tm_isdst  # 0 or 1&lt;br /&gt;
&lt;br /&gt;
 mst_epoch_time = time.time()  # server in MST/MDT&lt;br /&gt;
 if time.localtime().tm_isdst:  # are we in daylight saving time?&lt;br /&gt;
   utc_epoch_time = mst_epoch_time + time.altzone&lt;br /&gt;
 else:&lt;br /&gt;
   utc_epoch_time = mst_epoch_time + time.timezone&lt;br /&gt;
&lt;br /&gt;
Format current time: [http://docs.python.org/2/library/time.html#time.strftime]&lt;br /&gt;
 time.strftime(&#039;%d%b%y&#039;)  # &#039;12May11&#039;&lt;br /&gt;
 time.strftime(&#039;%Y.%m.%d %H:%M:%S&#039;)  # &#039;2013.08.09 14:01:28&#039;&lt;br /&gt;
&lt;br /&gt;
Time conversions:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# epoch to str&lt;br /&gt;
epoch_time = time.time()    # 1375992088.7867229&lt;br /&gt;
dt = datetime.datetime.fromtimestamp( epoch_time )    # datetime.datetime(2013, 8, 8, 14, 1, 28, 786723)&lt;br /&gt;
date_str = dt.strftime(&amp;quot;%Y-%m-%d %H:%M:%S&amp;quot;)    # &#039;2013-08-08 14:01:28&#039;&lt;br /&gt;
tz_offset = - time.altzone / 3600&lt;br /&gt;
if tz_offset &amp;lt; 0:&lt;br /&gt;
  tz_offset_str = &amp;quot;-%02d00&amp;quot; % abs(tz_offset)&lt;br /&gt;
else:&lt;br /&gt;
  tz_offset_str = &amp;quot;+%02d00&amp;quot; % abs(tz_offset)&lt;br /&gt;
print date_str + &amp;quot; &amp;quot; + tz_offset_str  # &#039;2013-08-08 14:01:28 -0600&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# UTC epoch to str&lt;br /&gt;
gm_epoch_time = calendar.timegm(time.gmtime())    # 1375992114&lt;br /&gt;
dt = datetime.utcfromtimestamp( gm_epoch_time )    # datetime.datetime(2013, 8, 8, 20, 1, 54)&lt;br /&gt;
dt.strftime(&amp;quot;%Y-%m-%d %H:%M:%S +0000&amp;quot;)    # &#039;2013-08-08 20:01:54 +0000&#039;&lt;br /&gt;
dt.strftime(&amp;quot;%Y-%m-%dT%H:%M:%SZ&amp;quot;)    # &#039;2013-08-08 20:01:54 +0000&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Local time str to epoch&lt;br /&gt;
iso_string=&#039;2013-08-08T14:01:28&#039;&lt;br /&gt;
epoch_time = time.mktime( time.strptime( iso_string, &#039;%Y-%m-%dT%H:%M:%S&#039; ) )    # 1375992088.0&lt;br /&gt;
&lt;br /&gt;
iso_string=&#039;2013-08-08T14:01:28 MDT&#039;&lt;br /&gt;
epoch_time = time.mktime( time.strptime( iso_string, &#039;%Y-%m-%dT%H:%M:%S %Z&#039; ) )    # 1375992088.0&lt;br /&gt;
&lt;br /&gt;
# not sure how to specify numerical time zone and pull it in!&lt;br /&gt;
&lt;br /&gt;
# UTC (Zulu) str to epoch, and back again&lt;br /&gt;
iso_string = &#039;2013-08-08T20:01:54Z&#039;&lt;br /&gt;
epoch_time = calendar.timegm( time.strptime( iso_string.replace(&#039;Z&#039;, &#039;GMT&#039;), &#039;%Y-%m-%dT%H:%M:%S%Z&#039; ) )&lt;br /&gt;
print epoch_time    # 1375992114&lt;br /&gt;
print &amp;quot;%sZ&amp;quot; % datetime.utcfromtimestamp(timestamp).isoformat()  # 2013-08-08T20:01:54Z&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Convert epoch from Local to UTC&lt;br /&gt;
epoch_time = 1375992114&lt;br /&gt;
tz_offset = - time.altzone / 3600&lt;br /&gt;
gm_epoch_time = epoch_time - tz_offset * 3600    # 1376013714&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Convert epoch from UTC to Local&lt;br /&gt;
gm_epoch_time = 1376013714&lt;br /&gt;
tz_offset = - time.altzone / 3600&lt;br /&gt;
epoch_time = gm_epoch_time + tz_offset * 3600    # 1375992114&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
struct_time:&lt;br /&gt;
 time.localtime()  # local zime zone&lt;br /&gt;
 time.gmtime()     # UTC time&lt;br /&gt;
&lt;br /&gt;
 today = time.localtime()&lt;br /&gt;
 today_year = today.tm_year&lt;br /&gt;
 today_month = today.tm_mon&lt;br /&gt;
 today_day = today.tm_mday&lt;br /&gt;
&lt;br /&gt;
 time.strftime(&amp;quot;%a, %d %b %Y %H:%M:%S +0000&amp;quot;, time.gmtime())&lt;br /&gt;
&lt;br /&gt;
Zulu time to epoch time: [http://stackoverflow.com/questions/127803/how-to-parse-iso-formatted-date-in-python]&lt;br /&gt;
 s = &#039;2008-09-03T20:56:35.450686Z&#039;&lt;br /&gt;
 event_time_struct = time.strptime(s.split(&#039;.&#039;)[0]+ &amp;quot;UTC&amp;quot;, &amp;quot;%Y-%m-%dT%H:%M:%S%Z&amp;quot;)&lt;br /&gt;
 epoch_time = calendar.timegm(event_time_struct)&lt;br /&gt;
&lt;br /&gt;
Parse string to time.struct_time (like gmtime()): [http://docs.python.org/2/library/time.html#time.strptime]&lt;br /&gt;
 time.strptime(time.ctime())  # current time - default format is ctime format: &amp;quot;%a %b %d %H:%M:%S %Y&amp;quot;&lt;br /&gt;
 time.strptime(time.ctime(time.time()))  # default format is ctime format: &amp;quot;%a %b %d %H:%M:%S %Y&amp;quot;&lt;br /&gt;
 time.strptime(&amp;quot;30 Nov 00&amp;quot;, &amp;quot;%d %b %y&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Build from ticks: [http://www.tutorialspoint.com/python/python_date_time.htm]&lt;br /&gt;
 localtime = time.localtime( time.time() )  # build time.struct_time from ticks&lt;br /&gt;
 print time.asctime( localtime )  # Tue Jan 13 10:17:09 2009&lt;br /&gt;
&lt;br /&gt;
 dt = datetime.datetime.fromtimestamp( time.time() )  # build datetime.datetime struct from ticks&lt;br /&gt;
 dt.strftime(&amp;quot;%Y-%m-%d  %H:%M:%S&amp;quot;)  # &#039;2013-07-31  23:07:48&#039;&lt;br /&gt;
 time.strptime( time.time(), &amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from datetime import date&lt;br /&gt;
now = date.today()    # now = datetime.date(2003, 12,2)&lt;br /&gt;
now.strftime(&amp;quot;%m-%d-%y&amp;quot;)   # &#039;12-02-03&#039;&lt;br /&gt;
# dates support calendar arthimetic&lt;br /&gt;
birthday = date(1964, 7, 31)&lt;br /&gt;
age = now - birthday&lt;br /&gt;
age.days  # 14368&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 ts = (datetime.datetime.now().strftime(&amp;quot;%Y%m%d%H%M&amp;quot;))         # 201105191118&lt;br /&gt;
 tstxt = (datetime.datetime.now().strftime(&amp;quot;%m-%d-%Y %H:%M&amp;quot;))  # 05-19-2011 11:18&lt;br /&gt;
&lt;br /&gt;
Seconds since epoch:&lt;br /&gt;
 int(time.time())    # 1305842304&lt;br /&gt;
&lt;br /&gt;
Zulu and back again: ([http://aboutsimon.com/2013/06/05/datetime-hell-time-zone-aware-to-unix-timestamp/ Datetime hell])&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import time&lt;br /&gt;
from calendar import timegm&lt;br /&gt;
from datetime import datetime&lt;br /&gt;
 &lt;br /&gt;
if __name__ == &#039;__main__&#039;:&lt;br /&gt;
    iso_string = &#039;2013-06-05T15:19:10Z&#039;&lt;br /&gt;
 &lt;br /&gt;
    timestamp = timegm(&lt;br /&gt;
        time.strptime(&lt;br /&gt;
            iso_string.replace(&#039;Z&#039;, &#039;GMT&#039;),&lt;br /&gt;
            &#039;%Y-%m-%dT%H:%M:%S%Z&#039;&lt;br /&gt;
        )&lt;br /&gt;
    )&lt;br /&gt;
 &lt;br /&gt;
    print iso_string&lt;br /&gt;
    print timestamp&lt;br /&gt;
    print &#039;-&amp;gt; %sZ&#039; % datetime.utcfromtimestamp(timestamp).isoformat()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
http://wiki.python.org/moin/TimeTransitionsImage?action=AttachFile&amp;amp;do=get&amp;amp;target=v1.png  [http://wiki.python.org/moin/WorkingWithTime]&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* WorkingWithTime - PythonInfo Wiki - http://wiki.python.org/moin/WorkingWithTime&lt;br /&gt;
* Datetime hell. Time zone aware to UNIX timestamp. | About me and the things I do - http://aboutsimon.com/2013/06/05/datetime-hell-time-zone-aware-to-unix-timestamp/&lt;br /&gt;
* WorkingWithTime - Python Wiki - http://wiki.python.org/moin/WorkingWithTime&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
Something I cooked up...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def utc_time(self, years_offset=60):&lt;br /&gt;
        mst_epoch_time = time.time()  # server is in MST&lt;br /&gt;
        if time.localtime().tm_isdst: # are we daylight saving time?&lt;br /&gt;
            utc_epoch_time = mst_epoch_time + time.altzone&lt;br /&gt;
        else:&lt;br /&gt;
            utc_epoch_time = mst_epoch_time + time.timezone&lt;br /&gt;
        return utc_epoch_time&lt;br /&gt;
&lt;br /&gt;
    def tz_time(self, tz_offset, daylight_adjust=True):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot; return the future time based on timezone offset&lt;br /&gt;
            @tz_offset is timezone offset, eg -7 for MST&lt;br /&gt;
            @daylight_adjust is flag to auto adjust for daylight time&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        if daylight_adjust:&lt;br /&gt;
            if time.localtime().tm_isdst: # are we daylight saving time?&lt;br /&gt;
                _tz_offset = tz_offset - 1&lt;br /&gt;
            else:&lt;br /&gt;
                _tz_offset = tz_offset&lt;br /&gt;
            _utc_epoch_time = self.utc_time()&lt;br /&gt;
            _adj_time = _utc_epoch_time + _tz_offset * 60 * 60&lt;br /&gt;
            return _adj_time&lt;br /&gt;
&lt;br /&gt;
    def future_time(self, tz_offset=-7, daylight_adjust=True, years_offset=60):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot; Calculate some future year &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        _tz_time = self.tz_time(tz_offset)&lt;br /&gt;
        future_utc_epoch_time = _tz_time + years_offset * 365 * 24 * 60 * 60&lt;br /&gt;
        # account for leap years&lt;br /&gt;
        cur_year = datetime.datetime.now().year&lt;br /&gt;
        cur_year_leap = cur_year / 4&lt;br /&gt;
        future_year = cur_year + years_offset&lt;br /&gt;
        future_year_leap = future_year / 4&lt;br /&gt;
        leap_days = future_year_leap - cur_year_leap&lt;br /&gt;
        future_utc_epoch_time += leap_days * 24 * 60 * 60&lt;br /&gt;
        return future_utc_epoch_time&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Math ===&lt;br /&gt;
&lt;br /&gt;
Math Functions:&lt;br /&gt;
 import math&lt;br /&gt;
 math.ceil(x)&lt;br /&gt;
 math.floor(x)&lt;br /&gt;
 math.trunc(x)&lt;br /&gt;
 math.pow(x,y)&lt;br /&gt;
&lt;br /&gt;
 abs(x)  # built in&lt;br /&gt;
&lt;br /&gt;
=== Random ===&lt;br /&gt;
&lt;br /&gt;
 import random&lt;br /&gt;
 random.choice([&#039;a&#039;, &#039;b&#039;, &#039;c&#039;])&lt;br /&gt;
 random.sample(range(100), 10)&lt;br /&gt;
 random.random()  # random float 0 &amp;lt; x &amp;lt; 1&lt;br /&gt;
 random.randrange(3)     # integer in [0, 1, 2]&lt;br /&gt;
 random.randrange(1, 3)  # integer in [1, 2]&lt;br /&gt;
 random.randint(1, 3)    # integer in [1, 2, 3]&lt;br /&gt;
&lt;br /&gt;
=== Operating System Operations ===&lt;br /&gt;
&lt;br /&gt;
Import OS Library:&lt;br /&gt;
 import os&lt;br /&gt;
&lt;br /&gt;
Common Functions:&lt;br /&gt;
 # directory functions&lt;br /&gt;
 os.getcwd()       # get current directory&lt;br /&gt;
 os.listdir(p)     # get list of directory contents&lt;br /&gt;
 os.chdir(p)       # change directory&lt;br /&gt;
 os.mkdir(p)       # make directory&lt;br /&gt;
 os.makedirs(p)    # make directory and all intermediate&lt;br /&gt;
 os.rmdir(p)       # remove empty directory, see shutil.rmtree()&lt;br /&gt;
 os.removedirs(p)  # remove empty directories, see shutil.rmtree()&lt;br /&gt;
 os.path.exists(p) # does file/directory exist?&lt;br /&gt;
 os.path.isdir(p)  # does directory exist&lt;br /&gt;
 os.path.join(folder1, folder2, file, etc)  # portable path join&lt;br /&gt;
&lt;br /&gt;
 # file functions&lt;br /&gt;
 os.remove(p)      # remove file&lt;br /&gt;
 os.unlink(p)      # same as os.remove()&lt;br /&gt;
 os.path.exists(p) # does file/directory exist?&lt;br /&gt;
 os.path.isfile(p) # does file exist&lt;br /&gt;
 os.stat(fname)    # get file stats&lt;br /&gt;
 os.stat(fname).st_size  # file size&lt;br /&gt;
 os.link(src, dst) # create hard link&lt;br /&gt;
 os.readlink(p)    # read symbolic link&lt;br /&gt;
 os.rename(old, new) # rename/move file or directory&lt;br /&gt;
 os.tempnam(p)     # temporary unique name for target path&lt;br /&gt;
 os.tmpfile()      # create temporary file&lt;br /&gt;
 os.tmpnam()       # temporary file name&lt;br /&gt;
 os.path.getsize(filename)  # get file size&lt;br /&gt;
&lt;br /&gt;
 # system functions&lt;br /&gt;
 os.fork()         # fork process&lt;br /&gt;
 os.getpid()       # get process id&lt;br /&gt;
 os.getppid()      # get parent&#039;s process id&lt;br /&gt;
 os.kill(pid, sig) # kill a process&lt;br /&gt;
 os.getlogin()     # get user&#039;s login name&lt;br /&gt;
&lt;br /&gt;
 # execution&lt;br /&gt;
 os.system(cmd)    # output to stdout, return exit_status&lt;br /&gt;
 os.popen(cmd)     # returns a pipe to command&lt;br /&gt;
&lt;br /&gt;
Note: to get path to script:&lt;br /&gt;
 sys.path[0]&lt;br /&gt;
&lt;br /&gt;
Get directory and file names:&lt;br /&gt;
 os.path.dirname(path)  # &#039;/root/test.txt&#039; -&amp;gt; &#039;/root&#039;&lt;br /&gt;
 os.path.basename(path) # &#039;/root/test.txt&#039; -&amp;gt; &#039;test.txt&#039;&lt;br /&gt;
 os.path.splitext(path) # &#039;/root/test.test.txt&#039; -&amp;gt; (&#039;/root/test.test&#039;, &#039;.txt&#039;) - extract extention&lt;br /&gt;
 filename.split(&amp;quot;.&amp;quot;)[-1] # &#039;/root/test.test.txt&#039; -&amp;gt; &#039;txt&#039; - extract extention&lt;br /&gt;
&lt;br /&gt;
Normalize path, eliminating double slashes, etc.&lt;br /&gt;
 os.path.normpath(path)  # &#039;/root/..&#039; -&amp;gt; &#039;/&#039; or &#039;test/..&#039; -&amp;gt; &#039;.&#039;&lt;br /&gt;
 os.path.abspath(path)   # &#039;/root/..&#039; -&amp;gt; &#039;/&#039; or &#039;test/..&#039; -&amp;gt; &#039;/root/test&#039;&lt;br /&gt;
&lt;br /&gt;
List dir: (returns list)&lt;br /&gt;
 os.listdir( os.getcwd() )&lt;br /&gt;
&lt;br /&gt;
List of files:&lt;br /&gt;
 [p for p in os.listdir(os.getcwd())&lt;br /&gt;
    if os.path.isfile(p)]&lt;br /&gt;
&lt;br /&gt;
List of folders:&lt;br /&gt;
 [p for p in os.listdir(os.getcwd())&lt;br /&gt;
    if os.path.isdir(p)]&lt;br /&gt;
&lt;br /&gt;
Build path for local OS: (using appropriate slash)&lt;br /&gt;
 pathstr = os.path.join(&amp;quot;folder&amp;quot;, &amp;quot;folder&amp;quot;, &amp;quot;file_or_folder&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
File and directory management with shutil&lt;br /&gt;
 import shutil&lt;br /&gt;
 shutil.copyfile(&#039;file1&#039;, &#039;file2&#039;)&lt;br /&gt;
 shutil.move(&#039;file1&#039;, &#039;folder2/file1&#039;)&lt;br /&gt;
&lt;br /&gt;
File Wildcards:&lt;br /&gt;
 import glob&lt;br /&gt;
 glob.glob(&#039;*.py&#039;)  # return list of files&lt;br /&gt;
&lt;br /&gt;
Walk directory tree: [http://stackoverflow.com/questions/120656/directory-listing-in-python]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import os&lt;br /&gt;
for dirname, dirnames, filenames in os.walk(&#039;.&#039;):&lt;br /&gt;
    for subdirname in dirnames:&lt;br /&gt;
        print os.path.join(dirname, subdirname)&lt;br /&gt;
    for filename in filenames:&lt;br /&gt;
        print os.path.join(dirname, filename)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ugly &#039;deltree&#039; (by kenneth)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import os&lt;br /&gt;
def deltree(path):&lt;br /&gt;
    files = os.listdir(path)&lt;br /&gt;
    for file in files:&lt;br /&gt;
        file_path = os.path.join(path, file)&lt;br /&gt;
        if os.path.isdir(file_path):&lt;br /&gt;
            deltree(file_path)&lt;br /&gt;
            os.rmdir(file_path)&lt;br /&gt;
        else:&lt;br /&gt;
            os.remove(file_path)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cleaner &#039;deltree&#039; (by Kep)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import shutil&lt;br /&gt;
# Blow away (if needed), and reclone to proper version&lt;br /&gt;
if os.path.isdir(&amp;quot;xxx&amp;quot;):&lt;br /&gt;
    shutil.rmtree(&amp;quot;xxx&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== System Platform ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import platform&lt;br /&gt;
&lt;br /&gt;
if platform.system() == &amp;quot;Linux&amp;quot;:&lt;br /&gt;
 # ...&lt;br /&gt;
if platform.system() == &amp;quot;Windows&amp;quot;:&lt;br /&gt;
 # ...&lt;br /&gt;
else:&lt;br /&gt;
 # ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Temp Files ===&lt;br /&gt;
&lt;br /&gt;
 import tempfile&lt;br /&gt;
 filename = tempfile.mktemp()&lt;br /&gt;
 f = open(filename, &#039;w&#039;)&lt;br /&gt;
 ...&lt;br /&gt;
 f.close()&lt;br /&gt;
 &lt;br /&gt;
 import os&lt;br /&gt;
 os.remove(filename)  # delete temp file&lt;br /&gt;
&lt;br /&gt;
=== Pickling ===&lt;br /&gt;
&lt;br /&gt;
Pickling (serializing, making objects persistent):&lt;br /&gt;
 import pickle&lt;br /&gt;
 grades = {&#039;bob&#039; : [4, 5, 6],&lt;br /&gt;
           &#039;sue&#039; : [3, None, 7, 7]}&lt;br /&gt;
 outfile = open(fname, &#039;wb&#039;)&lt;br /&gt;
 pickle.dump(grades, outfile)&lt;br /&gt;
&lt;br /&gt;
 infile = open(fname, &#039;rb&#039;)&lt;br /&gt;
 grades = pickle.load(infile)&lt;br /&gt;
&lt;br /&gt;
=== [http://docs.python.org/library/logging.html Logging] ===&lt;br /&gt;
&lt;br /&gt;
* logging — Logging facility for Python — Python 3 documentation - https://docs.python.org/3/library/logging.html&lt;br /&gt;
* Logging HOWTO — Python Dev Version documentation - http://docs.python.org/dev/howto/logging.html&lt;br /&gt;
* Logging Cookbook — Python Dev Version documentation - http://docs.python.org/dev/howto/logging-cookbook.html&lt;br /&gt;
&lt;br /&gt;
Setup logger:&lt;br /&gt;
 import logging&lt;br /&gt;
 logging.basicConfig(level=logging.DEBUG,format=&#039;[%(asctime)s.%(msecs)03d] %(levelname)s %(filename)s(line:%(lineno)d): %(message)s&#039;)&lt;br /&gt;
&lt;br /&gt;
Log Levels:&lt;br /&gt;
 import logging&lt;br /&gt;
 msg = &amp;quot;i broke&amp;quot;&lt;br /&gt;
 logging.debug(msg)&lt;br /&gt;
 logging.info(msg)&lt;br /&gt;
 logging.warning(msg)   # WARNING:root:i broke&lt;br /&gt;
 logging.error(msg)     # ERROR:root:i broke&lt;br /&gt;
 logging.critical(msg)  # CRITICAL:root:i broke&lt;br /&gt;
&lt;br /&gt;
 log.setLevel(level)  # debug, info, warn/warning, error, critical&lt;br /&gt;
 log.setLevel(logging.DEBUG)&lt;br /&gt;
&lt;br /&gt;
A good convention to use when naming loggers is to use a module-level logger, in each module which uses logging, named as follows: [http://docs.python.org/dev/howto/logging.html]&lt;br /&gt;
 logger = logging.getLogger(__name__)&lt;br /&gt;
&lt;br /&gt;
Simple example: [http://stackoverflow.com/questions/345991/python-no-handlers-could-be-found-for-logger-opengl-error]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
log_format=&#039;%(asctime)s | %(levelname)s | %(message)s&#039;&lt;br /&gt;
log_date_format=&#039;%Y-%m-%d %H:%M:%S&#039;&lt;br /&gt;
logging.basicConfig(format=log_format, datefmt=log_date_format)&lt;br /&gt;
log = logging.getLogger(__name__)&lt;br /&gt;
log.setLevel(logging.INFO)&lt;br /&gt;
&lt;br /&gt;
log.info(&#039;hi&#039;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Formatter function:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def makeFormatter(format_str=&amp;quot;&amp;quot;, date_format=&amp;quot;%Y-%m-%d %H:%M:%S&amp;quot;):&lt;br /&gt;
    if not format_str:&lt;br /&gt;
        format_str = &amp;quot;%(asctime)s | %(levelname)s | %(filename)s:%(lineno)d:%(funcName)s | %(message)s&amp;quot;&lt;br /&gt;
    return logging.Formatter(fmt=format_str, datefmt=date_format)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Medium example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Create logger&lt;br /&gt;
log_format=&#039;%(asctime)s | %(levelname)s | %(message)s&#039;&lt;br /&gt;
log_date_format=&#039;%Y-%m-%d %H:%M:%S&#039;&lt;br /&gt;
log_formatter = logging.Formatter(fmt=log_format, datefmt=log_date_format)&lt;br /&gt;
log = logging.getLogger(__name__)&lt;br /&gt;
log.setLevel(logging.DEBUG)&lt;br /&gt;
&lt;br /&gt;
# Log to console&lt;br /&gt;
ch = logging.StreamHandler()&lt;br /&gt;
ch.setLevel(logging.INFO)&lt;br /&gt;
ch.setFormatter(log_formatter)&lt;br /&gt;
log.addHandler(ch)&lt;br /&gt;
&lt;br /&gt;
# Log to file&lt;br /&gt;
fh = logging.FileHandler(&#039;my_logger.log&#039;)&lt;br /&gt;
fh.setLevel(logging.DEBUG)&lt;br /&gt;
fh.setFormatter(log_formatter)&lt;br /&gt;
log.addHandler(fh)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Log all loggers to file - attach to root logger&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import logging&lt;br /&gt;
&lt;br /&gt;
logger = logging.getLogger(__name__)&lt;br /&gt;
&lt;br /&gt;
# Configure Logger&lt;br /&gt;
log_format=&#039;%(asctime)s | %(name)s | %(levelname)s | %(message)s&#039;&lt;br /&gt;
log_date_format=&#039;%Y-%m-%d %H:%M:%S&#039;&lt;br /&gt;
log_formatter = logging.Formatter(fmt=log_format, datefmt=log_date_format)&lt;br /&gt;
logging.basicConfig(level=logging.DEBUG, format=log_format, datefmt=log_date_format)&lt;br /&gt;
&lt;br /&gt;
# Setup Log to File handler, and attach to root logger&lt;br /&gt;
root_logger = logging.getLogger()  # Calling getLogger() without a name returns the root logger&lt;br /&gt;
fh = logging.FileHandler(&#039;logger.txt&#039;)&lt;br /&gt;
fh.setLevel(logging.DEBUG)&lt;br /&gt;
fh.setFormatter(log_formatter)&lt;br /&gt;
root_logger.addHandler(fh)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Application Setup (not basic log configuration carries across imported modules):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import logging&lt;br /&gt;
def main():&lt;br /&gt;
    logging.basicConfig(filename=&#039;myapp.log&#039;, level=logging.INFO)&lt;br /&gt;
    logging.info(&#039;Started&#039;)&lt;br /&gt;
    ...&lt;br /&gt;
    logging.info(&#039;Finished&#039;)&lt;br /&gt;
&lt;br /&gt;
if __name__ == &#039;__main__&#039;:&lt;br /&gt;
    main()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Log multiple lines:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
for line in output.splitlines():&lt;br /&gt;
    log.debug(line)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Set log level:  (warning is default)&lt;br /&gt;
 logging.basicConfig(level=logging.DEBUG)&lt;br /&gt;
&lt;br /&gt;
Set log level from string value: [http://docs.python.org/dev/howto/logging.html]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# assuming loglevel is bound to the string value obtained from the&lt;br /&gt;
# command line argument. Convert to upper case to allow the user to&lt;br /&gt;
# specify --log=DEBUG or --log=debug&lt;br /&gt;
numeric_level = getattr(logging, loglevel.upper(), None)&lt;br /&gt;
if not isinstance(numeric_level, int):&lt;br /&gt;
    raise ValueError(&#039;Invalid log level: %s&#039; % loglevel)&lt;br /&gt;
logging.basicConfig(level=numeric_level, ...)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Log to file:&lt;br /&gt;
 logging.basicConfig(filename=&#039;example.log&#039;,level=logging.DEBUG)&lt;br /&gt;
 logging.basicConfig(filename=&#039;example.log&#039;, filemode=&#039;w&#039;, level=logging.DEBUG)  # do not append&lt;br /&gt;
&lt;br /&gt;
Format output: (once set, can&#039;t be changed?)&lt;br /&gt;
 # WARNING:MESSAGE&lt;br /&gt;
 logging.basicConfig(format=&#039;%(levelname)s:%(message)s&#039;, level=logging.DEBUG)&lt;br /&gt;
&lt;br /&gt;
 # 05/23/2011 12:50:02 PM MESSAGE&lt;br /&gt;
 logging.basicConfig(format=&#039;%(asctime)s %(message)s&#039;, datefmt=&#039;%m/%d/%Y %I:%M:%S %p&#039;)&lt;br /&gt;
&lt;br /&gt;
 # 05/23/2011 12:55:28 PM : WARNING : MESSAGE&lt;br /&gt;
 logging.basicConfig(format=&#039;%(asctime)s : %(levelname)s : %(message)s&#039;, datefmt=&#039;%m/%d/%Y %I:%M:%S %p&#039;)&lt;br /&gt;
&lt;br /&gt;
 # 2011-05-23 13:05:30 : WARNING : MESSAGE&lt;br /&gt;
 logging.basicConfig(format=&#039;%(asctime)s : %(levelname)s : %(message)s&#039;, datefmt=&#039;%Y-%m-%d %H:%M:%S&#039;)&lt;br /&gt;
&lt;br /&gt;
 # 2011-05-23 13:05:30 | WARNING | FILE:FUNC | MESSAGE&lt;br /&gt;
 logging.basicConfig(format=&#039;%(asctime)s | %(levelname)s | %(filename)s:%(funcName)s | %(message)s&#039;, datefmt=&#039;%Y-%m-%d %H:%M:%S&#039;)&lt;br /&gt;
&lt;br /&gt;
Log record attributes - http://docs.python.org/library/logging.html#logrecord-attributes&lt;br /&gt;
&lt;br /&gt;
Format Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FORMAT = &#039;%(asctime)-15s %(clientip)s %(user)-8s %(message)s&#039;  # doesn&#039;t work!&lt;br /&gt;
logging.basicConfig(format=FORMAT)&lt;br /&gt;
d = { &#039;clientip&#039; : &#039;192.168.0.1&#039;, &#039;user&#039; : &#039;fbloggs&#039; }&lt;br /&gt;
logger = logging.getLogger(&#039;tcpserver&#039;)&lt;br /&gt;
logger.warning(&#039;Protocol problem: %s&#039;, &#039;connection reset&#039;, extra=d)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import logging&lt;br /&gt;
&lt;br /&gt;
# create logger with &#039;spam_application&#039;&lt;br /&gt;
logger = logging.getLogger(&#039;spam_application&#039;)&lt;br /&gt;
logger.setLevel(logging.DEBUG)&lt;br /&gt;
&lt;br /&gt;
# create file handler which logs even debug messages&lt;br /&gt;
fh = logging.FileHandler(&#039;spam.log&#039;)&lt;br /&gt;
fh.setLevel(logging.DEBUG)&lt;br /&gt;
&lt;br /&gt;
# create console handler with a higher log level&lt;br /&gt;
ch = logging.StreamHandler()&lt;br /&gt;
ch.setLevel(logging.ERROR)&lt;br /&gt;
&lt;br /&gt;
# create formatter and add it to the handlers&lt;br /&gt;
formatter = logging.Formatter(&#039;%(asctime)s - %(name)s - %(levelname)s - %(message)s&#039;)&lt;br /&gt;
fh.setFormatter(formatter)&lt;br /&gt;
ch.setFormatter(formatter)&lt;br /&gt;
&lt;br /&gt;
# add the handlers to the logger&lt;br /&gt;
logger.addHandler(fh)&lt;br /&gt;
logger.addHandler(ch)&lt;br /&gt;
&lt;br /&gt;
logger.info(&#039;Message to loggers and handlers&#039;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Templating ===&lt;br /&gt;
&lt;br /&gt;
 from string import Template&lt;br /&gt;
 t = Template(&#039;${name}&#039;s fav dish is $food&#039;)&lt;br /&gt;
 t.substitute(name = &#039;ken&#039;, food = &#039;beans&#039;) # throws exception if missing one, but can have more&lt;br /&gt;
 t.safe_substitute(name = &#039;ken&#039;)  # will fill in what it can&lt;br /&gt;
&lt;br /&gt;
Change delimiter:&lt;br /&gt;
 class MYT(Template):&lt;br /&gt;
   delimiter = &#039;%&#039;&lt;br /&gt;
 minput = input(&amp;quot;File name format (%d - date, %s - size): &amp;quot;)&lt;br /&gt;
 myt = MYT(minput)&lt;br /&gt;
 myt.substitute(%d=date, %s=size)&lt;br /&gt;
&lt;br /&gt;
=== [http://docs.python.org/library/threading.html Threading] ===&lt;br /&gt;
&lt;br /&gt;
Basic thread: [http://softwareramblings.com/2008/06/running-functions-as-threads-in-python.html]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import thread&lt;br /&gt;
 &lt;br /&gt;
def someFunc():&lt;br /&gt;
    print &amp;quot;someFunc was called&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
thread.start_new_thread(someFunc, ())&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
More complete basic thread:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import thread&lt;br /&gt;
import threading&lt;br /&gt;
import time&lt;br /&gt;
&lt;br /&gt;
def run_thread (threadname, sleeptime):&lt;br /&gt;
 print &amp;quot;Thread start: &amp;quot; + threadname&lt;br /&gt;
 time.sleep(sleeptime)&lt;br /&gt;
 print &amp;quot;Thread end: &amp;quot; + threadname&lt;br /&gt;
 thread.interrupt_main()   # throw keyboard interrupt to kill main program&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
 thread.start_new_thread(run_thread, (&amp;quot;Thread1&amp;quot;, 3))&lt;br /&gt;
 try:&lt;br /&gt;
     while 1:&lt;br /&gt;
         pass&lt;br /&gt;
 except:&lt;br /&gt;
     print &amp;quot;Thread1 exited....&amp;quot; &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Can use a global counter instead of exception to track number of threads:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import thread&lt;br /&gt;
import threading&lt;br /&gt;
import time&lt;br /&gt;
&lt;br /&gt;
threadcount = 3&lt;br /&gt;
&lt;br /&gt;
def run_thread (threadname, sleeptime):&lt;br /&gt;
  global threadcount&lt;br /&gt;
  print &amp;quot;Thread start: &amp;quot; + threadname&lt;br /&gt;
  time.sleep(sleeptime)&lt;br /&gt;
  print &amp;quot;Thread end: &amp;quot; + threadname&lt;br /&gt;
  threadcount -= 1&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
  thread.start_new_thread(run_thread, (&amp;quot;Thread1&amp;quot;, 3))&lt;br /&gt;
  thread.start_new_thread(run_thread, (&amp;quot;Thread2&amp;quot;, 4))&lt;br /&gt;
  thread.start_new_thread(run_thread, (&amp;quot;Thread3&amp;quot;, 2))&lt;br /&gt;
  while 1:&lt;br /&gt;
    if threadcount == 0:&lt;br /&gt;
      break&lt;br /&gt;
    else:&lt;br /&gt;
      pass&lt;br /&gt;
  print &amp;quot;completed&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
Thread object: [http://softwareramblings.com/2008/06/running-functions-as-threads-in-python.html]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import threading&lt;br /&gt;
 &lt;br /&gt;
t1 = threading.Thread(target=someFunc)&lt;br /&gt;
#  with parameters: Thread(target=myfunction, args=(&#039;MyStringHere&#039;,1)).start()&lt;br /&gt;
t1.start()&lt;br /&gt;
t1.join()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Basic threading with parameters:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import threading&lt;br /&gt;
t = threading.Thread(None, someFunc, None, (param1, param2))&lt;br /&gt;
t.start()&lt;br /&gt;
t.join()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
t = threading.Thread(target=client_recv, args=(s, name))&lt;br /&gt;
while True:&lt;br /&gt;
  t.join(timeout=2)&lt;br /&gt;
  if t.isAlive():&lt;br /&gt;
    print &amp;quot;Thread is dead...&amp;quot;&lt;br /&gt;
    break&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Threading as a class: [http://softwareramblings.com/2008/06/running-functions-as-threads-in-python.html]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import threading&lt;br /&gt;
 &lt;br /&gt;
class FuncThread(threading.Thread):&lt;br /&gt;
    def __init__(self, target, *args):&lt;br /&gt;
        self._target = target&lt;br /&gt;
        self._args = args&lt;br /&gt;
        threading.Thread.__init__(self)&lt;br /&gt;
 &lt;br /&gt;
    def run(self):&lt;br /&gt;
        self._target(*self._args)&lt;br /&gt;
 &lt;br /&gt;
# Example usage&lt;br /&gt;
def someOtherFunc(data, key):&lt;br /&gt;
    print &amp;quot;someOtherFunc was called : data=%s; key=%s&amp;quot; % (str(data), str(key))&lt;br /&gt;
 &lt;br /&gt;
t1 = FuncThread(someOtherFunc, [1,2], 6)&lt;br /&gt;
t1.start()&lt;br /&gt;
t1.join()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Threading as a class #2:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import threading&lt;br /&gt;
import time&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
class MyT(threading.Thread):&lt;br /&gt;
  def __init__(self, name, time):&lt;br /&gt;
    threading.Thread.__init__(self)&lt;br /&gt;
    self.name = name&lt;br /&gt;
    self.time = time&lt;br /&gt;
  def run(self):&lt;br /&gt;
    print(&amp;quot;Thread Start: &amp;quot; + self.name)&lt;br /&gt;
    for i in range(self.time):&lt;br /&gt;
      print(&amp;quot;[&amp;quot; + self.name + &amp;quot;]&amp;quot;, end=&#039;&#039;)&lt;br /&gt;
      sys.stdout.flush()&lt;br /&gt;
      time.sleep(1)&lt;br /&gt;
    print(&amp;quot;Thread Stop: &amp;quot; + self.name)&lt;br /&gt;
&lt;br /&gt;
myt1 = MyT(&#039;1&#039;, 10)&lt;br /&gt;
myt1.start()&lt;br /&gt;
&lt;br /&gt;
myt2 = MyT(&#039;2&#039;, 15)&lt;br /&gt;
myt2.start()&lt;br /&gt;
&lt;br /&gt;
myt3 = MyT(&#039;3&#039;, 5)&lt;br /&gt;
myt3.start()&lt;br /&gt;
&lt;br /&gt;
myt4 = MyT(&#039;4&#039;, 10)&lt;br /&gt;
myt4.start()&lt;br /&gt;
&lt;br /&gt;
myt1.join()&lt;br /&gt;
myt2.join()&lt;br /&gt;
myt3.join()&lt;br /&gt;
myt4.join()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Locking:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
lock=thread.allocate_lock()&lt;br /&gt;
&lt;br /&gt;
# pass lock to thread, and use in thread as such:&lt;br /&gt;
lock.acquire()&lt;br /&gt;
#some operation&lt;br /&gt;
lock.release()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Returning data from a thread (using a [http://docs.python.org/library/queue.html queue]): [http://stackoverflow.com/questions/1886090/return-value-from-thread] [http://stackoverflow.com/questions/2829329/catch-a-threads-exception-in-the-caller-thread-in-python]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Pass exception back to parent&lt;br /&gt;
import sys&lt;br /&gt;
import threading&lt;br /&gt;
import Queue&lt;br /&gt;
&lt;br /&gt;
class ExcThread(threading.Thread):&lt;br /&gt;
    def __init__(self, bucket):&lt;br /&gt;
        threading.Thread.__init__(self)&lt;br /&gt;
        self.bucket = bucket&lt;br /&gt;
    def run(self):&lt;br /&gt;
        try:&lt;br /&gt;
            raise Exception(&#039;An error occured here.&#039;)&lt;br /&gt;
        except Exception:&lt;br /&gt;
            self.bucket.put(sys.exc_info())&lt;br /&gt;
&lt;br /&gt;
def main():&lt;br /&gt;
    bucket = Queue.Queue()&lt;br /&gt;
    thread_obj = ExcThread(bucket)&lt;br /&gt;
    thread_obj.start()&lt;br /&gt;
    while True:&lt;br /&gt;
        try:&lt;br /&gt;
            exc = bucket.get(block=False)&lt;br /&gt;
        except Queue.Empty:&lt;br /&gt;
            pass&lt;br /&gt;
        else:&lt;br /&gt;
            exc_type, exc_obj, exc_trace = exc&lt;br /&gt;
            # deal with the exception&lt;br /&gt;
            print &amp;quot;Exception Caught:&amp;quot;, exc_type, exc_obj&lt;br /&gt;
            print &amp;quot;Exception Trace:&amp;quot;, exc_trace&lt;br /&gt;
        thread_obj.join(0.1)&lt;br /&gt;
        if thread_obj.isAlive():&lt;br /&gt;
            continue&lt;br /&gt;
        else:&lt;br /&gt;
            break&lt;br /&gt;
&lt;br /&gt;
if __name__ == &#039;__main__&#039;:&lt;br /&gt;
    main()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Exception Caught: &amp;lt;type &#039;exceptions.Exception&#039;&amp;gt; An error occured here.&lt;br /&gt;
Exception Trace: &amp;lt;traceback object at 0x2b2230a285f0&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Another Exception catching queue example: (kenneth&#039;s example)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# thread function&lt;br /&gt;
def run_thread(queue, item):&lt;br /&gt;
  ...&lt;br /&gt;
  queue.put( Exception(&amp;quot;Failure on item:&amp;quot; + item) )&lt;br /&gt;
&lt;br /&gt;
threads = []&lt;br /&gt;
queue = Queue.Queue()&lt;br /&gt;
&lt;br /&gt;
# start threads&lt;br /&gt;
for item in items:&lt;br /&gt;
  t = Thread(None, run_thread, None, (queue, item))&lt;br /&gt;
  t.start()&lt;br /&gt;
  threads.append(t)&lt;br /&gt;
&lt;br /&gt;
# wait for threads&lt;br /&gt;
for t in threads:&lt;br /&gt;
  t.join()&lt;br /&gt;
&lt;br /&gt;
# catch and reraise exceptions&lt;br /&gt;
while not queue.empty():&lt;br /&gt;
  raise(queue.get())&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Returning data from a thread (using a callback function): [http://stackoverflow.com/questions/1886090/return-value-from-thread]&lt;br /&gt;
:&amp;quot;Another approach is to pass a callback function to the thread. This gives a simple, safe and flexible way to return a value to the parent, anytime from the new thread.&amp;quot;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import threading&lt;br /&gt;
import time&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
class MyThread(threading.Thread):&lt;br /&gt;
    def __init__(self, cb):&lt;br /&gt;
        threading.Thread.__init__(self)&lt;br /&gt;
        self.callback = cb&lt;br /&gt;
    def run(self):&lt;br /&gt;
        for i in range(10):&lt;br /&gt;
            self.callback(i)&lt;br /&gt;
            time.sleep(1)&lt;br /&gt;
&lt;br /&gt;
def count(x):&lt;br /&gt;
    print x&lt;br /&gt;
    sys.stdout.flush()&lt;br /&gt;
&lt;br /&gt;
t = MyThread(count)&lt;br /&gt;
t.start()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* 16.2. threading — Higher-level threading interface — Python v2.7.1 documentation - http://docs.python.org/library/threading.html&lt;br /&gt;
* An Introduction to Thread Programming - http://www.prasannatech.net/2008/08/introduction-to-thread-programming.html&lt;br /&gt;
* Python - Multithreaded Programming - http://www.tutorialspoint.com/python/python_multithreading.htm&lt;br /&gt;
* Running Functions as Threads in Python « Software Ramblings - http://softwareramblings.com/2008/06/running-functions-as-threads-in-python.html&lt;br /&gt;
* Understanding Threading in Python LG #107 - http://linuxgazette.net/107/pai.html&lt;br /&gt;
* multithreading - Simple threading in Python 2.6 using thread.start_new_thread() - Stack Overflow - http://stackoverflow.com/questions/849674/simple-threading-in-python-2-6-using-thread-start-new-thread&lt;br /&gt;
* python - Return value from thread - Stack Overflow - http://stackoverflow.com/questions/1886090/return-value-from-thread&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
Interrupt main thread:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# source: http://stackoverflow.com/questions/4591917/python-how-to-quit-cli-when-stuck-in-blocking-raw-input&lt;br /&gt;
&lt;br /&gt;
import thread&lt;br /&gt;
import time&lt;br /&gt;
&lt;br /&gt;
def main():&lt;br /&gt;
    try:&lt;br /&gt;
        m = thread.start_new_thread(killable_input, tuple())&lt;br /&gt;
        while 1:&lt;br /&gt;
            time.sleep(0.1) &lt;br /&gt;
    except KeyboardInterrupt:&lt;br /&gt;
        print &amp;quot;exception&amp;quot; &lt;br /&gt;
&lt;br /&gt;
def killable_input():&lt;br /&gt;
    w = thread.start_new_thread(normal_input, tuple())&lt;br /&gt;
    i = thread.start_new_thread(wait_sometime, tuple())&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def normal_input():&lt;br /&gt;
    s = raw_input(&amp;quot;input:&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def wait_sometime():&lt;br /&gt;
    time.sleep(4) # or any other condition to kill the thread&lt;br /&gt;
    print &amp;quot;too slow, killing imput&amp;quot;&lt;br /&gt;
    thread.interrupt_main()&lt;br /&gt;
&lt;br /&gt;
if __name__ == &#039;__main__&#039;:&lt;br /&gt;
    main()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== urllib ===&lt;br /&gt;
&lt;br /&gt;
See [[Python/urllib]]&lt;br /&gt;
&lt;br /&gt;
=== Command line arguments ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import sys&lt;br /&gt;
for x in sys.argv:&lt;br /&gt;
    print x&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Execute other python script ===&lt;br /&gt;
&lt;br /&gt;
 import sys&lt;br /&gt;
 sys.argv = [&#039;&#039;, &#039;my&#039;, &#039;args&#039;, &#039;here&#039;]&lt;br /&gt;
 execfile(&#039;myscript.py&#039;)  # does not support arguments directly&lt;br /&gt;
&lt;br /&gt;
=== Exit Code ===&lt;br /&gt;
&lt;br /&gt;
sys.exit(n) http://docs.python.org/library/sys.html:&lt;br /&gt;
 import sys&lt;br /&gt;
 sys.exit(1)  # exit code of 1 (default is 0)&lt;br /&gt;
 sys.exit(&amp;quot;some error&amp;quot;)  # exit code of 1, and message displayed&lt;br /&gt;
&lt;br /&gt;
=== [http://docs.python.org/library/syslog.html syslog] ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import syslog&lt;br /&gt;
syslog.openlog(&#039;[WATER]&#039;)&lt;br /&gt;
syslog.syslog(&#039;Processing started&#039;)&lt;br /&gt;
if error:&lt;br /&gt;
    syslog.syslog(syslog.LOG_ERR, &#039;Processing started&#039;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import syslog&lt;br /&gt;
syslog.openlog(&#039;[WATER]&#039;)&lt;br /&gt;
def log(msg):&lt;br /&gt;
    syslog.syslog(str(msg))&lt;br /&gt;
log(&amp;quot;Starting...&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Subprocess ===&lt;br /&gt;
&lt;br /&gt;
Subprocess - http://docs.python.org/library/subprocess.html&lt;br /&gt;
&lt;br /&gt;
Methods of subprocess (or external command execution):&lt;br /&gt;
* subprocess (only method to rule/replace all others)&lt;br /&gt;
* os.system&lt;br /&gt;
* os.spawn*&lt;br /&gt;
* os.popen*&lt;br /&gt;
* popen2.*&lt;br /&gt;
* commands.*&lt;br /&gt;
&lt;br /&gt;
My New Favorite:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import subprocess&lt;br /&gt;
class Run(object):&lt;br /&gt;
    class RC(int):&lt;br /&gt;
        pass&lt;br /&gt;
    def __new__(cls, cmd, *args, **kwargs):&lt;br /&gt;
        p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)&lt;br /&gt;
        rc = cls.RC(p.wait())&lt;br /&gt;
        rc.output = &amp;quot;\n&amp;quot;.join(p.stdout.readlines())&lt;br /&gt;
        rc.error = &amp;quot;\n&amp;quot;.join(p.stderr.readlines())&lt;br /&gt;
        return rc&lt;br /&gt;
&lt;br /&gt;
if Run(&amp;quot;some command&amp;quot;): print &amp;quot;do something&amp;quot;  # on rc of not 0 (negative or positive)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
My Favorite:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def exe(cmd):&lt;br /&gt;
    p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)&lt;br /&gt;
    #output = &amp;quot; | &amp;quot;.join(p.stdout.readlines())&lt;br /&gt;
    output = &amp;quot;\n&amp;quot;.join(p.stdout.readlines())&lt;br /&gt;
    rc = p.wait()&lt;br /&gt;
    return (rc, output)&lt;br /&gt;
&lt;br /&gt;
def exe_checked(cmd, checked=True):&lt;br /&gt;
    p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)&lt;br /&gt;
    #output = &amp;quot; | &amp;quot;.join(p.stdout.readlines())&lt;br /&gt;
    output = &amp;quot;\n&amp;quot;.join(p.stdout.readlines())&lt;br /&gt;
    rc = p.wait()&lt;br /&gt;
    if rc and checked:&lt;br /&gt;
        raise Exception(&amp;quot;Command returned non zero [{0}]: {1}&amp;quot;.format(rc, cmd)&lt;br /&gt;
    return (rc, output)&lt;br /&gt;
&lt;br /&gt;
def exe_with_stderr(cmd):&lt;br /&gt;
    p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subproc&lt;br /&gt;
ess.PIPE)&lt;br /&gt;
    output = &amp;quot; | &amp;quot;.join(p.stdout.readlines())&lt;br /&gt;
    outputerr = &amp;quot; | &amp;quot;.join(p.stderr.readlines())&lt;br /&gt;
    rc = p.wait()&lt;br /&gt;
    return (rc, output, outputerr)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def exec_program(cmd):&lt;br /&gt;
    s = subprocess.Popen(cmd.split(), stdout=subprocess.PIPE, stderr=subprocess.PIPE)&lt;br /&gt;
    stdout, stderr = s.communicate()&lt;br /&gt;
    result = s.wait()&lt;br /&gt;
    return stdout, stderr, result&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pass along output and return true error code:&lt;br /&gt;
 import subprocess&lt;br /&gt;
 retcode = subprocess.call([&amp;quot;ls&amp;quot;, &amp;quot;-l&amp;quot;])  # true return code, output sent to STDOUT&lt;br /&gt;
&lt;br /&gt;
 retcode = subprocess.call([&amp;quot;foo.sh&amp;quot;,&amp;quot;args&amp;quot;],shell=True)  # Execute in shell, with shell processing&lt;br /&gt;
 retcode = subprocess.call([&#039;C:\\Temp\\a b c\\Notepad.exe&#039;])&lt;br /&gt;
 retcode = subprocess.call([&amp;quot;D:/Python24/Python.exe&amp;quot;, &amp;quot;Skripta.py&amp;quot;, &amp;quot;arg1&amp;quot;, &amp;quot;arg2&amp;quot;])&lt;br /&gt;
&lt;br /&gt;
Note: shell=True is equivalent to: subprocess.Popen([&#039;/bin/sh&#039;, &#039;-c&#039;, args[0], args[1], ...])&lt;br /&gt;
&lt;br /&gt;
Process STDOUT and STDERR and get return code:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
import subprocess&lt;br /&gt;
import string&lt;br /&gt;
&lt;br /&gt;
cmd = &amp;quot;cat /etc/passwd | grep ken&amp;quot;&lt;br /&gt;
p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) # stderr=subprocess.STDOUT to combine&lt;br /&gt;
&lt;br /&gt;
out = string.join(p.stdout.readlines())&lt;br /&gt;
outerr = string.join(p.stderr.readlines())&lt;br /&gt;
retcode = str(p.wait())&lt;br /&gt;
&lt;br /&gt;
print(&amp;quot;STDOUT: &amp;quot; + out)&lt;br /&gt;
print(&amp;quot;STDERR: &amp;quot; + outerr)&lt;br /&gt;
print(&amp;quot;RETCODE: &amp;quot; + retcode)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Above with stderr redirected to stdout (combined):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import subprocess&lt;br /&gt;
p = subprocess.Popen(&#039;ls&#039;, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)&lt;br /&gt;
for line in p.stdout.readlines():&lt;br /&gt;
    print line,&lt;br /&gt;
retval = p.wait()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Replacing shell backtick: [http://docs.python.org/library/subprocess.html]&lt;br /&gt;
 # shell code:&lt;br /&gt;
 # OUTPUT=`mycmd myarg`&lt;br /&gt;
 from subprocess import Popen&lt;br /&gt;
 output = Popen([&amp;quot;mycmd&amp;quot;, &amp;quot;myarg&amp;quot;], stdout=PIPE).communicate()[0]&lt;br /&gt;
&lt;br /&gt;
Replacing shell pipeline  [http://docs.python.org/library/subprocess.html]&lt;br /&gt;
 # shell code:&lt;br /&gt;
 # OUTPUT=`dmesg | grep hda`&lt;br /&gt;
 from subprocess import Popen&lt;br /&gt;
 p1 = Popen([&amp;quot;dmesg&amp;quot;], stdout=PIPE)&lt;br /&gt;
 p2 = Popen([&amp;quot;grep&amp;quot;, &amp;quot;hda&amp;quot;], stdin=p1.stdout, stdout=PIPE)&lt;br /&gt;
 p1.stdout.close()  # Allow p1 to receive a SIGPIPE if p2 exits.&lt;br /&gt;
 output = p2.communicate()[0]&lt;br /&gt;
&lt;br /&gt;
Replacing os.system(): [http://docs.python.org/library/subprocess.html]&lt;br /&gt;
 # old:&lt;br /&gt;
 sts = os.system(&amp;quot;mycmd&amp;quot; + &amp;quot; myarg&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
 # new:&lt;br /&gt;
 p = Popen(&amp;quot;mycmd&amp;quot; + &amp;quot; myarg&amp;quot;, shell=True)&lt;br /&gt;
 sts = os.waitpid(p.pid, 0)[1]&lt;br /&gt;
&lt;br /&gt;
Control an executed process:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cmd = &amp;quot;/usr/bin/java -Xms256M -Xmx1024M -jar minecraft_server.jar nogui&amp;quot;&lt;br /&gt;
&lt;br /&gt;
p = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE,&lt;br /&gt;
        stdout=subprocess.PIPE, stderr=subprocess.STDOUT)&lt;br /&gt;
&lt;br /&gt;
# cycle while process continues alive&lt;br /&gt;
while p.poll() == None:&lt;br /&gt;
&lt;br /&gt;
  # check if input&lt;br /&gt;
  if select.select([p.stdout.fileno()], [], [], 1)[0]:&lt;br /&gt;
    while select.select([p.stdout.fileno()], [], [], .1)[0]:&lt;br /&gt;
        line = p.stdout.readline()&lt;br /&gt;
        # ... process&lt;br /&gt;
&lt;br /&gt;
  # write something to process&lt;br /&gt;
  p.stdin.write(&amp;quot;tp %s %s\n&amp;quot; % (user1, user2))&lt;br /&gt;
&lt;br /&gt;
  ...&lt;br /&gt;
&lt;br /&gt;
  # time to force a quit: (choose which you need)&lt;br /&gt;
  p.kill()  # SIGKILL&lt;br /&gt;
  p.terminate()  # SIGTERM&lt;br /&gt;
  os.kill(p.pid, signal.SIGTERM)  # same as first, but not as clean&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Other Command Execution ====&lt;br /&gt;
&lt;br /&gt;
Old method with os.system(): [http://docs.python.org/library/os.html]&lt;br /&gt;
 import os&lt;br /&gt;
 encoded_wait_code = os.system(&amp;quot;some command&amp;quot;)  # output sent to STDOUT&lt;br /&gt;
 # Note: returns code of 0 if command returns 0, but wait() encoded value for all other values&lt;br /&gt;
&lt;br /&gt;
Quick and dirty old method (prints stderr, captures stdout)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import os&lt;br /&gt;
out = string.join( os.popen(cmd).readlines() )&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Quick and dirty old method (prints stderr, captures stdout, captures ugly wait() encoded return code)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import os&lt;br /&gt;
p = os.popen(cmd)&lt;br /&gt;
stdout = &amp;quot;&amp;quot;.join( p.readlines() )&lt;br /&gt;
encoded_wait_code = p.close()  # None if 0&lt;br /&gt;
rcode = os.WEXITSTATUS(ugly_rcode) # fix ugly wait() encoded rcode&lt;br /&gt;
print(stdout)&lt;br /&gt;
print(rcode)&lt;br /&gt;
&lt;br /&gt;
if os.popen(cmd).close():&lt;br /&gt;
  print &amp;quot;error with cmd: %s&amp;quot; % cmd&lt;br /&gt;
  sys.exit(1)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
???:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
os.spawnvp(os.P_WAIT,&amp;quot;/usr/bin/mplayer&amp;quot;,[&amp;quot;&amp;quot;,&amp;quot;-ao&amp;quot;,&amp;quot;pcm&amp;quot;,file])&lt;br /&gt;
# or &lt;br /&gt;
os.spawnvp(os.P_NOWAIT,&amp;quot;/usr/bin/mplayer&amp;quot;,[&amp;quot;&amp;quot;,&amp;quot;-ao&amp;quot;,&amp;quot;pcm&amp;quot;,file])&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Replacing os.system(): [http://docs.python.org/library/subprocess.html]&lt;br /&gt;
 # old:&lt;br /&gt;
 sts = os.system(&amp;quot;mycmd&amp;quot; + &amp;quot; myarg&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
 # new:&lt;br /&gt;
 p = Popen(&amp;quot;mycmd&amp;quot; + &amp;quot; myarg&amp;quot;, shell=True)&lt;br /&gt;
 sts = os.waitpid(p.pid, 0)[1]&lt;br /&gt;
&lt;br /&gt;
More realistic example replacing os.system(): [http://docs.python.org/library/subprocess.html]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
try:&lt;br /&gt;
    retcode = call(&amp;quot;mycmd&amp;quot; + &amp;quot; myarg&amp;quot;, shell=True)&lt;br /&gt;
    if retcode &amp;lt; 0:&lt;br /&gt;
        print &amp;gt;&amp;gt;sys.stderr, &amp;quot;Child was terminated by signal&amp;quot;, -retcode&lt;br /&gt;
    else:&lt;br /&gt;
        print &amp;gt;&amp;gt;sys.stderr, &amp;quot;Child returned&amp;quot;, retcode&lt;br /&gt;
except OSError, e:&lt;br /&gt;
    print &amp;gt;&amp;gt;sys.stderr, &amp;quot;Execution failed:&amp;quot;, e&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== select ====&lt;br /&gt;
&lt;br /&gt;
Select:&lt;br /&gt;
&lt;br /&gt;
select.select(rlist, wlist, xlist[, timeout])&lt;br /&gt;
: This is a straightforward interface to the Unix select() system call. The first three arguments are sequences of ‘waitable objects’: either integers representing file descriptors or objects with a parameterless method named fileno() returning such an integer&lt;br /&gt;
: The optional timeout argument specifies a time-out as a floating point number in seconds. When the timeout argument is omitted the function blocks until at least one file descriptor is ready. A time-out value of zero specifies a poll and never blocks.&lt;br /&gt;
&lt;br /&gt;
 if select.select([sys.stdin.fileno()], [], [], .1)[0]:&lt;br /&gt;
     line = p.stdout.readline()&lt;br /&gt;
&lt;br /&gt;
==== full wrapped execution ====&lt;br /&gt;
&lt;br /&gt;
Process timeout (by Kenneth):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import subprocess&lt;br /&gt;
import time&lt;br /&gt;
import os&lt;br /&gt;
import signal&lt;br /&gt;
&lt;br /&gt;
def cmd(cmd, timeout=300, retry=0):&lt;br /&gt;
    # Execute command, time progress, and kill on timeout&lt;br /&gt;
&lt;br /&gt;
    # (status, output) = commands.getstatusoutput(cmd)&lt;br /&gt;
    start_time = None&lt;br /&gt;
    status = None&lt;br /&gt;
    output = None&lt;br /&gt;
    for retry_count in range(retry+1):&lt;br /&gt;
        if retry_count &amp;gt; 0:&lt;br /&gt;
            print(&amp;quot;RETRY: &amp;quot; + str(retry_count) + &amp;quot; &amp;quot; + cmd)&lt;br /&gt;
        start_time = time.time()&lt;br /&gt;
        p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE,&lt;br /&gt;
                stderr=subprocess.STDOUT)&lt;br /&gt;
        timeout_fail = False&lt;br /&gt;
        while p.poll() == None:&lt;br /&gt;
            if time.time() - start_time &amp;gt; timeout:&lt;br /&gt;
                # kill process&lt;br /&gt;
                print(&amp;quot;TIMEOUT: &amp;quot; + str(timeout) + &amp;quot;sec - killing (&amp;quot; + str(p.pid) + &amp;quot;) - &amp;quot; + cmd)&lt;br /&gt;
                try:&lt;br /&gt;
                    os.kill(p.pid, signal.SIGTERM)&lt;br /&gt;
                except OSError as e:&lt;br /&gt;
                    print(&amp;quot;Kill exception: &amp;quot; + str(e))&lt;br /&gt;
                timeout_fail = True&lt;br /&gt;
                break&lt;br /&gt;
            #print(&amp;quot;.&amp;quot;)&lt;br /&gt;
            time.sleep(1)&lt;br /&gt;
        status = p.poll()&lt;br /&gt;
        output = p.stdout.read()&lt;br /&gt;
        if timeout_fail == False:&lt;br /&gt;
            break&lt;br /&gt;
    seconds = int(time.time() - start_time)&lt;br /&gt;
    return (status, output, seconds)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
Process input and output wrapper (from minecraft):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import subprocess&lt;br /&gt;
import select&lt;br /&gt;
import re&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
cmd = &amp;quot;/usr/bin/java -Xms256M -Xmx1024M -jar minecraft_server.jar nogui&amp;quot;&lt;br /&gt;
&lt;br /&gt;
p = subprocess.Popen(cmd, shell=True,&lt;br /&gt;
        stdin=subprocess.PIPE,&lt;br /&gt;
        stdout=subprocess.PIPE,&lt;br /&gt;
        stderr=subprocess.STDOUT)&lt;br /&gt;
&lt;br /&gt;
# cycle while process continues alive&lt;br /&gt;
while p.poll() == None:&lt;br /&gt;
&lt;br /&gt;
    if select.select([p.stdout.fileno()], [], [], 1)[0]:&lt;br /&gt;
        while select.select([p.stdout.fileno()], [], [], .1)[0]:&lt;br /&gt;
            line = p.stdout.readline()&lt;br /&gt;
            # &amp;lt;kiloforce&amp;gt; -tp joe&lt;br /&gt;
            match = re.findall(&amp;quot;&amp;lt;(.*)&amp;gt; -tp (.*)&amp;quot;, line)&lt;br /&gt;
            if match:&lt;br /&gt;
                user1 = match[0][0]&lt;br /&gt;
                user2 = match[0][1]&lt;br /&gt;
                print &amp;quot;&amp;gt;&amp;gt; ACTION: Teleporting %s to %s&amp;quot; % (user1, user2)&lt;br /&gt;
                p.stdin.write(&amp;quot;tp %s %s\n&amp;quot; % (user1, user2))&lt;br /&gt;
            if line:&lt;br /&gt;
                print &amp;quot;&amp;gt;&amp;gt; SERVER: %s&amp;quot; % line.strip()&lt;br /&gt;
            else:&lt;br /&gt;
                print &amp;quot;The server died!&amp;quot;&lt;br /&gt;
                sys.exit(1)&lt;br /&gt;
&lt;br /&gt;
    if select.select([sys.stdin.fileno()], [], [], .1)[0]:&lt;br /&gt;
        line = sys.stdin.readline()&lt;br /&gt;
        print &amp;quot;&amp;gt;&amp;gt; CONSOLE: %s&amp;quot; % line.strip()&lt;br /&gt;
        p.stdin.write(&amp;quot;%s&amp;quot; % line)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Command With Timeout ====&lt;br /&gt;
&lt;br /&gt;
python - Using module &#039;subprocess&#039; with timeout - Stack Overflow - http://stackoverflow.com/questions/1191374/using-module-subprocess-with-timeout&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import subprocess, threading&lt;br /&gt;
&lt;br /&gt;
class Command(object):&lt;br /&gt;
    def __init__(self, cmd):&lt;br /&gt;
        self.cmd = cmd&lt;br /&gt;
        self.process = None&lt;br /&gt;
&lt;br /&gt;
    def run(self, timeout):&lt;br /&gt;
        def target():&lt;br /&gt;
            print &#039;Thread started&#039;&lt;br /&gt;
            self.process = subprocess.Popen(self.cmd, shell=True)&lt;br /&gt;
            self.process.communicate()&lt;br /&gt;
            print &#039;Thread finished&#039;&lt;br /&gt;
&lt;br /&gt;
        thread = threading.Thread(target=target)&lt;br /&gt;
        thread.start()&lt;br /&gt;
&lt;br /&gt;
        thread.join(timeout)&lt;br /&gt;
        if thread.is_alive():&lt;br /&gt;
            print &#039;Terminating process&#039;&lt;br /&gt;
            self.process.terminate()&lt;br /&gt;
            thread.join()&lt;br /&gt;
        print self.process.returncode&lt;br /&gt;
&lt;br /&gt;
command = Command(&amp;quot;echo &#039;Process started&#039;; sleep 2; echo &#039;Process finished&#039;&amp;quot;)&lt;br /&gt;
command.run(timeout=3)&lt;br /&gt;
command.run(timeout=1)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
My version:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import subprocess&lt;br /&gt;
import threading&lt;br /&gt;
&lt;br /&gt;
class Command(object):&lt;br /&gt;
    def __init__(self, cmd, capture=False, shell=True):&lt;br /&gt;
        self.cmd = cmd&lt;br /&gt;
        self.process = None&lt;br /&gt;
        self.thread = None&lt;br /&gt;
        self.shell = shell&lt;br /&gt;
        if type(cmd) == list:&lt;br /&gt;
            self.shell = False&lt;br /&gt;
        self.rc = None&lt;br /&gt;
        self.pid = None&lt;br /&gt;
        self.stdout = None&lt;br /&gt;
        self.stderr = None&lt;br /&gt;
        self.capture = capture  # capture stdout?&lt;br /&gt;
&lt;br /&gt;
    def run(self, timeout=None, wait=True):&lt;br /&gt;
        def target():&lt;br /&gt;
            print &#039;&amp;gt;&amp;gt; Thread started (%s)&#039; % self.cmd&lt;br /&gt;
            if self.capture:&lt;br /&gt;
                self.process = subprocess.Popen(self.cmd, shell=self.shell, stdout=subprocess.PIPE, stderr=subprocess.PIPE)&lt;br /&gt;
            else:&lt;br /&gt;
                self.process = subprocess.Popen(self.cmd, shell=self.shell)&lt;br /&gt;
            print &#039;&amp;gt;&amp;gt; Thread PID: %d&#039; % self.process.pid&lt;br /&gt;
            self.pid = self.process.pid&lt;br /&gt;
            self.stdout, self.stderr = self.process.communicate()&lt;br /&gt;
            self.rc = self.process.returncode&lt;br /&gt;
            print &#039;&amp;gt;&amp;gt; Thread finished: %d&#039; % self.rc&lt;br /&gt;
&lt;br /&gt;
        self.thread = threading.Thread(target=target)&lt;br /&gt;
        self.thread.start()&lt;br /&gt;
&lt;br /&gt;
        if wait:&lt;br /&gt;
            self.wait(timeout)&lt;br /&gt;
        return self  # so you can do: c = Command().run()&lt;br /&gt;
&lt;br /&gt;
    def wait(self, timeout=None):&lt;br /&gt;
        print &#039;&amp;gt;&amp;gt; Waiting for thread...&#039;&lt;br /&gt;
        if timeout:&lt;br /&gt;
            self.thread.join(timeout)&lt;br /&gt;
        else:&lt;br /&gt;
            self.thread.join()&lt;br /&gt;
        if self.thread.is_alive():&lt;br /&gt;
            print &#039;&amp;gt;&amp;gt; Terminating process&#039;&lt;br /&gt;
            self.process.terminate()&lt;br /&gt;
            self.rc = self.process.returncode&lt;br /&gt;
            self.thread.join()&lt;br /&gt;
            if self.thread.is_alive():&lt;br /&gt;
                print &#039;&amp;gt;&amp;gt; Failed to terminate&#039;&lt;br /&gt;
        else:&lt;br /&gt;
            print &#039;&amp;gt;&amp;gt; Thread completed&#039;&lt;br /&gt;
        #print self.process.returncode&lt;br /&gt;
&lt;br /&gt;
    def is_alive(self ):&lt;br /&gt;
        return self.thread.is_alive()&lt;br /&gt;
&lt;br /&gt;
command = Command(&#039;do something&#039;).run()&lt;br /&gt;
&lt;br /&gt;
command2 = Command([&#039;do&#039;, &#039;something&#039;, &#039;long&#039;]).run(wait=False)&lt;br /&gt;
command2.wait(timeout=10)&lt;br /&gt;
&lt;br /&gt;
command3 = Command(&#039;want output&#039;, capture=True).run()&lt;br /&gt;
print command3.stdout&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== System call ===&lt;br /&gt;
&lt;br /&gt;
 os.system(&amp;quot;some_command with args&amp;quot;)&lt;br /&gt;
 os.system(&amp;quot;some_command &amp;lt; input_file | another_command &amp;gt; output_file&amp;quot;)&lt;br /&gt;
 stream = os.popen(&amp;quot;some_command with args&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Here&#039;s a summary of the ways to call external programs and the advantages and disadvantages of each:&lt;br /&gt;
&lt;br /&gt;
1.&lt;br /&gt;
: os.system(&amp;quot;some_command with args&amp;quot;) passes the command and arguments to your system&#039;s shell. This is nice because you can actually run multiple commands at once in this manner and set up pipes and input/output redirection. For example,&lt;br /&gt;
: os.system(&amp;quot;some_command &amp;lt; input_file | another_command &amp;gt; output_file&amp;quot;)&lt;br /&gt;
: However, while this is convenient, you have to manually handle the escaping of shell characters such as spaces, etc. On the other hand, this also lets you run commands which are simply shell commands and not actually external programs.&lt;br /&gt;
: http://docs.python.org/lib/os-process.html&lt;br /&gt;
&lt;br /&gt;
2.&lt;br /&gt;
: stream = os.popen(&amp;quot;some_command with args&amp;quot;) will do the same thing as os.system except that it gives you a file-like object that you can use to access standard input/output for that process. There are 3 other variants of popen that all handle the i/o slightly differently. If you pass everything as a string, then your command is passed to the shell; if you pass them as a list then you don&#039;t need to worry about escaping anything.&lt;br /&gt;
: http://docs.python.org/lib/os-newstreams.html&lt;br /&gt;
&lt;br /&gt;
3.&lt;br /&gt;
: The Popen class of the subprocess module. This is intended as a replacement for os.popen but has the downside of being slightly more complicated by virtue of being so comprehensive. For example, you&#039;d say&lt;br /&gt;
: print Popen(&amp;quot;echo Hello World&amp;quot;, stdout=PIPE, shell=True).stdout.read()&lt;br /&gt;
: instead of&lt;br /&gt;
: print os.popen(&amp;quot;echo Hello World&amp;quot;).read()&lt;br /&gt;
: but it is nice to have all of the options there in one unified class instead of 4 different popen functions.&lt;br /&gt;
: http://docs.python.org/lib/node528.html&lt;br /&gt;
&lt;br /&gt;
4.&lt;br /&gt;
: The call function from the subprocess module. This is basically just like the Popen class and takes all of the same arguments, but it simply wait until the command completes and gives you the return code. For example:&lt;br /&gt;
: return_code = call(&amp;quot;echo Hello World&amp;quot;, shell=True)&lt;br /&gt;
: http://docs.python.org/lib/node529.html&lt;br /&gt;
&lt;br /&gt;
5.&lt;br /&gt;
: The os module also has all of the fork/exec/spawn functions that you&#039;d have in a C program, but I don&#039;t recommend using them directly.&lt;br /&gt;
&lt;br /&gt;
: The subprocess module should probably be what you use.&lt;br /&gt;
&lt;br /&gt;
Source: [http://stackoverflow.com/questions/89228/how-to-call-external-command-in-python]&lt;br /&gt;
&lt;br /&gt;
== Advanced Code ==&lt;br /&gt;
&lt;br /&gt;
=== Executing Code from Command Line ===&lt;br /&gt;
&lt;br /&gt;
 python -c [cmd]&lt;br /&gt;
 # -c cmd : program passed in as string (terminates option list)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python -c &amp;quot;import sys;exec(sys.stdin.read())&amp;quot; &amp;lt;&amp;lt; &amp;quot;EOF&amp;quot;&lt;br /&gt;
def test1():&lt;br /&gt;
  print &amp;quot;test1&amp;quot;&lt;br /&gt;
test1()&lt;br /&gt;
print &amp;quot;test&amp;quot;&lt;br /&gt;
EOF&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Integer Return Code Class ===&lt;br /&gt;
&lt;br /&gt;
Python3 version:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class RC(int):&lt;br /&gt;
  def __new__(cls, rc, stdout=&#039;&#039;, stderr=&#039;&#039;):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;We can&#039;t use use __init__ because int is immutable.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    return super(RC, cls).__new__(cls, rc)&lt;br /&gt;
  def __init__(self, rc, stdout=&#039;&#039;, stderr=&#039;&#039;):&lt;br /&gt;
    super().__init__()&lt;br /&gt;
    self.rc = rc  # redundant&lt;br /&gt;
    self.stdout = stdout&lt;br /&gt;
    self.stderr = stderr&lt;br /&gt;
  def __repr__(self):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;Optional string output&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    return &amp;quot;(%s, &#039;%s&#039;, &#039;%s&#039;)&amp;quot; % (self.rc, self.stdout, self.stderr)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Python2 version:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class RC(int):&lt;br /&gt;
  def __new__(cls, rc, stdout=&#039;&#039;, stderr=&#039;&#039;):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;We can&#039;t use use __init__ because int is immutable.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    return super(RC, cls).__new__(cls, rc)&lt;br /&gt;
  def __init__(self, rc, stdout=&#039;&#039;, stderr=&#039;&#039;):&lt;br /&gt;
    super(self.__class__, self).__init__(rc)&lt;br /&gt;
    self.rc = rc  # redundant&lt;br /&gt;
    self.stdout = stdout&lt;br /&gt;
    self.stderr = stderr&lt;br /&gt;
  def __repr__(self):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;Optional string output&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    return &amp;quot;(%s, &#039;%s&#039;, &#039;%s&#039;)&amp;quot; % (self, self.stdout, self.stderr)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
sample:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; rc1 = RC(5)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; rc2 = RC(0, &#039;out&#039;, &#039;err&#039;)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; rc1&lt;br /&gt;
(5, &#039;&#039;, &#039;&#039;)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; rc2&lt;br /&gt;
(5, &#039;out&#039;, &#039;err&#039;)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; rc2.stdout&lt;br /&gt;
&#039;out&#039;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; int(rc1)&lt;br /&gt;
5&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; 0 + rc1&lt;br /&gt;
5&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; if rc1 &amp;lt;= 5:  print &amp;quot;yes&amp;quot;&lt;br /&gt;
...&lt;br /&gt;
yes&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; if rc2:  print &amp;quot;non-zero&amp;quot;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Smart Execute ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class RC(int):&lt;br /&gt;
    def __new__(cls, rc, output=&#039;&#039;):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;We can&#039;t use use __init__ because int is immutable.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        return super(RC, cls).__new__(cls, rc)&lt;br /&gt;
    def __init__(self, rc, output=&#039;&#039;):&lt;br /&gt;
        super().__init__()&lt;br /&gt;
        self.rc = rc  # redundant&lt;br /&gt;
        self.output = output&lt;br /&gt;
    def __repr__(self):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Optional string output&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        return &amp;quot;(%s, &#039;%s&#039;)&amp;quot; % (self.rc, self.output)&lt;br /&gt;
&lt;br /&gt;
def smart_execute(cmd, display=True, checked=False):&lt;br /&gt;
    output = &amp;quot;&amp;quot;&lt;br /&gt;
    process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, bufsize=1, shell=True, encoding=&#039;utf-8&#039;)&lt;br /&gt;
    for c in iter(lambda: process.stdout.read(1), &amp;quot;&amp;quot;):&lt;br /&gt;
        if display:&lt;br /&gt;
            sys.stdout.buffer.write(c.encode(&#039;utf-8&#039;))&lt;br /&gt;
        output += c&lt;br /&gt;
    process.stdout.close()&lt;br /&gt;
    rc = process.wait()&lt;br /&gt;
    if checked and rc:&lt;br /&gt;
        raise subprocess.CalledProcessError(ret, cmd)&lt;br /&gt;
    return RC(rc, output.strip())&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Not smart version:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def execute(cmd, return_output=False):&lt;br /&gt;
    out = &amp;quot;&amp;quot;&lt;br /&gt;
    process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, bufsize=1, shell=True, encoding=&#039;utf-8&#039;)&lt;br /&gt;
    for c in iter(lambda: process.stdout.read(1), &amp;quot;&amp;quot;):&lt;br /&gt;
        sys.stdout.buffer.write(c.encode(&#039;utf-8&#039;))&lt;br /&gt;
        if return_output:&lt;br /&gt;
            out += c&lt;br /&gt;
    process.stdout.close()&lt;br /&gt;
    ret = process.wait()&lt;br /&gt;
    if ret:&lt;br /&gt;
        raise subprocess.CalledProcessError(ret, cmd)&lt;br /&gt;
    if return_output:&lt;br /&gt;
        return out.strip()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== select ===&lt;br /&gt;
&lt;br /&gt;
usage: select.select(rlist, wlist, xlist[, timeout]) [http://docs.python.org/2/library/select.html]&lt;br /&gt;
* rlist: wait until ready for reading&lt;br /&gt;
* wlist: wait until ready for writing&lt;br /&gt;
* xlist: wait for an “exceptional condition” (see the manual page for what your system considers such a condition)&lt;br /&gt;
* The optional timeout argument specifies a time-out as a floating point number in seconds.&lt;br /&gt;
&lt;br /&gt;
 if select.select([p.stdout.fileno()], [], [], 1)[0]:&lt;br /&gt;
&lt;br /&gt;
=== ANSI Color ===&lt;br /&gt;
&lt;br /&gt;
* ANSI escape code - http://en.wikipedia.org/wiki/ANSI_escape_code&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
unicode - Print in terminal with colors using Python? - Stack Overflow - https://stackoverflow.com/questions/287871/print-in-terminal-with-colors-using-python&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class bcolors:&lt;br /&gt;
    HEADER = &#039;\033[95m&#039;&lt;br /&gt;
    OKBLUE = &#039;\033[94m&#039;&lt;br /&gt;
    OKGREEN = &#039;\033[92m&#039;&lt;br /&gt;
    WARNING = &#039;\033[93m&#039;&lt;br /&gt;
    FAIL = &#039;\033[91m&#039;&lt;br /&gt;
    ENDC = &#039;\033[0m&#039;&lt;br /&gt;
    BOLD = &#039;\033[1m&#039;&lt;br /&gt;
    UNDERLINE = &#039;\033[4m&#039;&lt;br /&gt;
&lt;br /&gt;
print bcolors.WARNING + &amp;quot;Warning: No active frommets remain. Continue?&amp;quot; + bcolors.ENDC&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class colors:&lt;br /&gt;
  black = 0&lt;br /&gt;
  red = 1&lt;br /&gt;
  green = 2&lt;br /&gt;
  yellow = 3&lt;br /&gt;
  blue = 4&lt;br /&gt;
  magenta = 5&lt;br /&gt;
  cyan = 6&lt;br /&gt;
  white = 7&lt;br /&gt;
  fg = 30  # foreground add&lt;br /&gt;
  bg = 40  # background add&lt;br /&gt;
  bfg = 90  # bold foreground add&lt;br /&gt;
  bbg = 100  # bold background add&lt;br /&gt;
&lt;br /&gt;
print &#039;\033[%dm red foreground \033[0m&#039; % (colors.red + colors.fg)&lt;br /&gt;
print &#039;\033[%dm bold red foreground \033[0m&#039; % (colors.red + colors.bfg)&lt;br /&gt;
print &#039;\033[%dm blue background \033[0m&#039; % (colors.blue + colors.bg)&lt;br /&gt;
print &#039;\033[%dm bold blue background \033[0m&#039; % (colors.blue + colors.bbg)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
Before you start spouting escape sequences, you should check that stdout is a tty. You can do this with sys.stdout.isatty()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sys.stdout.isatty()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def hilite(string, status, bold):&lt;br /&gt;
    attr = []&lt;br /&gt;
    if status:&lt;br /&gt;
        # green&lt;br /&gt;
        attr.append(&#039;32&#039;)&lt;br /&gt;
    else:&lt;br /&gt;
        # red&lt;br /&gt;
        attr.append(&#039;31&#039;)&lt;br /&gt;
    if bold:&lt;br /&gt;
        attr.append(&#039;1&#039;)&lt;br /&gt;
    return &#039;\x1b[%sm%s\x1b[0m&#039; % (&#039;;&#039;.join(attr), string)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Python | change text color in shell - Stack Overflow - https://stackoverflow.com/questions/2330245/python-change-text-color-in-shell&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
For reference, a small bash script which prints a table of escape sequences: colortable16.sh: ([http://www.frexx.de/xterm-256-notes/ The 256 color mode of xterm], [http://plug.org/pipermail/plug/2008-March/016821.html The 90s called; they want their 256 colors back])&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
&lt;br /&gt;
# prints a color table of 8bg * 8fg * 2 states (regular/bold)&lt;br /&gt;
echo&lt;br /&gt;
echo Table for 16-color terminal escape sequences.&lt;br /&gt;
echo Replace ESC with \\033 in bash.&lt;br /&gt;
echo&lt;br /&gt;
echo &amp;quot;Background | Foreground colors&amp;quot;&lt;br /&gt;
echo &amp;quot;---------------------------------------------------------------------&amp;quot;&lt;br /&gt;
for((bg=40;bg&amp;lt;=47;bg++)); do&lt;br /&gt;
	for((bold=0;bold&amp;lt;=1;bold++)) do&lt;br /&gt;
		echo -en &amp;quot;\033[0m&amp;quot;&amp;quot; ESC[${bg}m   | &amp;quot;&lt;br /&gt;
		for((fg=30;fg&amp;lt;=37;fg++)); do&lt;br /&gt;
			if [ $bold == &amp;quot;0&amp;quot; ]; then&lt;br /&gt;
				echo -en &amp;quot;\033[${bg}m\033[${fg}m [${fg}m  &amp;quot;&lt;br /&gt;
			else&lt;br /&gt;
				echo -en &amp;quot;\033[${bg}m\033[1;${fg}m [1;${fg}m&amp;quot;&lt;br /&gt;
			fi&lt;br /&gt;
		done&lt;br /&gt;
		echo -e &amp;quot;\033[0m&amp;quot;&lt;br /&gt;
	done&lt;br /&gt;
	echo &amp;quot;--------------------------------------------------------------------- &amp;quot;&lt;br /&gt;
done&lt;br /&gt;
&lt;br /&gt;
echo&lt;br /&gt;
echo&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Python version: (modified by me)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
# prints a color table of 8bg * 8fg * 2 states (regular/bold)&lt;br /&gt;
print&lt;br /&gt;
print &amp;quot;Table for 16-color terminal escape sequences.&amp;quot;&lt;br /&gt;
print &amp;quot;Replace ESC with \\033 in bash.&amp;quot;&lt;br /&gt;
print&lt;br /&gt;
print &amp;quot;Background | Foreground colors&amp;quot;&lt;br /&gt;
print &amp;quot;---------------------------------------------------------------------&amp;quot;&lt;br /&gt;
for bg in range(40, 47+1):&lt;br /&gt;
  for bold in range(0, 1+1):&lt;br /&gt;
                sys.stdout.write(&amp;quot;\033[0m&amp;quot;&amp;quot; ESC[{bg}m   | &amp;quot;.format(bg=bg))&lt;br /&gt;
                for fg in range(30, 37+1):&lt;br /&gt;
                        if bold == 0:&lt;br /&gt;
                                sys.stdout.write(&amp;quot;\033[{bg}m\033[{fg}m [{fg}m  &amp;quot;.format(bg=bg, fg=fg))&lt;br /&gt;
                        else:&lt;br /&gt;
                                sys.stdout.write(&amp;quot;\033[{bg}m\033[1;{fg}m [1;{fg}m&amp;quot;.format(bg=bg, fg=fg))&lt;br /&gt;
                sys.stdout.write(&amp;quot;\033[0m\n&amp;quot;)&lt;br /&gt;
  print &amp;quot;--------------------------------------------------------------------- &amp;quot;&lt;br /&gt;
&lt;br /&gt;
print&lt;br /&gt;
print&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Execute External Application ===&lt;br /&gt;
&lt;br /&gt;
Execute program: (and send output to STDOUT)&lt;br /&gt;
 encoded_wait_code = os.system(&#039;mkdir mydir&#039;)  # output sent to STDOUT&lt;br /&gt;
&lt;br /&gt;
Get output and ugly return code: (STDERR goes to STDOUT)&lt;br /&gt;
 p = os.popen(cmd)&lt;br /&gt;
 print p.readlines()&lt;br /&gt;
 encoded_wait_code = p.close()&lt;br /&gt;
&lt;br /&gt;
Execute other python script&lt;br /&gt;
 import sys&lt;br /&gt;
 sys.argv = [, &#039;my&#039;, &#039;args&#039;, &#039;here&#039;]&lt;br /&gt;
 execfile(&#039;myscript.py&#039;)  # does not support arguments directly&lt;br /&gt;
&lt;br /&gt;
Subprocess:&lt;br /&gt;
* See [[#Subprocess]]&lt;br /&gt;
&lt;br /&gt;
=== Program Layout ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
PackageName/&lt;br /&gt;
    README&lt;br /&gt;
    setup.py&lt;br /&gt;
    bin/&lt;br /&gt;
        script&lt;br /&gt;
    docs/&lt;br /&gt;
    test/  # some include in package_name&lt;br /&gt;
    pacakgename/&lt;br /&gt;
        __init__.py&lt;br /&gt;
        code1.py&lt;br /&gt;
        subpackage/&lt;br /&gt;
            __init__.py&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== __init__.py ===&lt;br /&gt;
&lt;br /&gt;
Purpose: Makes the folder into a package library&lt;br /&gt;
&lt;br /&gt;
NOTE: This file is most commonly blank&lt;br /&gt;
&lt;br /&gt;
Good place to put your package functions.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# ken/__init__.py&lt;br /&gt;
def load():&lt;br /&gt;
  ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import ken&lt;br /&gt;
ken.load()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Can import other modules to then use as package modules:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# ken/__init__.py&lt;br /&gt;
from ken.client import Server&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import ken&lt;br /&gt;
ken.Server()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Good place to put your Exceptions.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class MyException(Exception):&lt;br /&gt;
  &amp;quot;&amp;quot;&amp;quot; My Error Exception &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use the __all__ to specify what gets imported on &#039;from package import *&#039;&lt;br /&gt;
  __all__ = [&#039;func1&#039;, &#039;func2&#039;]&lt;br /&gt;
&lt;br /&gt;
=== Metadata ===&lt;br /&gt;
&lt;br /&gt;
 VERSION = (0, 2, 1)&lt;br /&gt;
or&lt;br /&gt;
 __version__ = &#039;0.2.1&#039;&lt;br /&gt;
&lt;br /&gt;
Also See [[#pydoc]]&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
 __version__ = &#039;1.10&#039;&lt;br /&gt;
 __author__ = &#039;Joshua Roesslein&#039;&lt;br /&gt;
 __license__ = &#039;MIT&#039;&lt;br /&gt;
&lt;br /&gt;
=== setup.py ===&lt;br /&gt;
&lt;br /&gt;
See [[#Distributing Python Modules with Distutils]]&lt;br /&gt;
&lt;br /&gt;
=== Distributing Python Modules with Distutils ===&lt;br /&gt;
&lt;br /&gt;
Distributing Python Modules — http://docs.python.org/distutils/index.html&lt;br /&gt;
&lt;br /&gt;
Uses setup.py for package installation.&lt;br /&gt;
 python setup.py install&lt;br /&gt;
&lt;br /&gt;
==== Simple example ====&lt;br /&gt;
&lt;br /&gt;
To install foo.py:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from distutils.core import setup&lt;br /&gt;
setup(name=&#039;foo&#039;,&lt;br /&gt;
      version=&#039;1.0&#039;,&lt;br /&gt;
      py_modules=[&#039;foo&#039;],&lt;br /&gt;
      )&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Source: http://docs.python.org/distutils/introduction.html&lt;br /&gt;
&lt;br /&gt;
==== klib example ====&lt;br /&gt;
&lt;br /&gt;
klib setup.py:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from distutils.core import setup&lt;br /&gt;
&lt;br /&gt;
setup(name = &amp;quot;klib&amp;quot;,&lt;br /&gt;
    version = &amp;quot;101&amp;quot;,&lt;br /&gt;
    description = &amp;quot;klib library&amp;quot;,&lt;br /&gt;
    url = &amp;quot;http://www.oeey.com/klib&amp;quot;,&lt;br /&gt;
    author = &amp;quot;Kenneth&amp;quot;,&lt;br /&gt;
    author_email = &amp;quot;kenneth@oeey.com&amp;quot;,&lt;br /&gt;
    license = &amp;quot;Kenneth License&amp;quot;,&lt;br /&gt;
    long_description = &amp;quot;&amp;quot;&amp;quot;Really long text here.&amp;quot;&amp;quot;&amp;quot;,&lt;br /&gt;
    platforms = &amp;quot;Any Platform&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
    packages = [&#039;klib&#039;,&#039;klib.messenger&#039;],&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Installed to:&lt;br /&gt;
 /opt/python26/lib/python2.6/site-packages/klib/&lt;br /&gt;
 /opt/python26/lib/python2.6/site-packages/klib-100-py2.6.egg-info&lt;br /&gt;
&lt;br /&gt;
Metadata: (/opt/python26/lib/python2.6/site-packages/klib-101-py2.6.egg-info)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Metadata-Version: 1.0&lt;br /&gt;
Name: klib&lt;br /&gt;
Version: 101&lt;br /&gt;
Summary: klib library&lt;br /&gt;
Home-page: http://www.oeey.com/klib&lt;br /&gt;
Author: Kenneth&lt;br /&gt;
Author-email: kenneth@oeey.com&lt;br /&gt;
License: Kenneth License&lt;br /&gt;
Description: Really long text here.&lt;br /&gt;
Platform: Any platform&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Any fields not included will be marked:&lt;br /&gt;
 Platform: UNKNOWN&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* 2. Writing the Setup Script — Python v2.7.2 documentation - http://docs.python.org/distutils/setupscript.html&lt;br /&gt;
* http://wiki.python.org/moin/Distutils/Tutorial&lt;br /&gt;
&lt;br /&gt;
==== Uninstall Package ====&lt;br /&gt;
&lt;br /&gt;
Collect files during install:&lt;br /&gt;
 python setup.py install --record install-record.txt&lt;br /&gt;
 sudo rm $(cat install-record.txt)&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* installation - python setup.py uninstall - Stack Overflow - http://stackoverflow.com/questions/1550226/python-setup-py-uninstall&lt;br /&gt;
&lt;br /&gt;
=== Distributing Python Modules with Setuptools ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
import setuptools&lt;br /&gt;
&lt;br /&gt;
setuptools.setup(name=&amp;quot;tweepy&amp;quot;,&lt;br /&gt;
      version=&amp;quot;1.10&amp;quot;,&lt;br /&gt;
      description=&amp;quot;Twitter library for python&amp;quot;,&lt;br /&gt;
      license=&amp;quot;MIT&amp;quot;,&lt;br /&gt;
      author=&amp;quot;Joshua Roesslein&amp;quot;,&lt;br /&gt;
      author_email=&amp;quot;tweepy@googlegroups.com&amp;quot;,&lt;br /&gt;
      url=&amp;quot;http://github.com/tweepy/tweepy&amp;quot;,&lt;br /&gt;
      packages = setuptools.find_packages(),&lt;br /&gt;
      keywords= &amp;quot;twitter library&amp;quot;,&lt;br /&gt;
      zip_safe = True)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Decorators ===&lt;br /&gt;
&lt;br /&gt;
Decorators wrap functions&lt;br /&gt;
&lt;br /&gt;
Function Counter: [http://stackoverflow.com/questions/739654/understanding-python-decorators]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def fcount(func):&lt;br /&gt;
    def wrapper(*args, **kw):&lt;br /&gt;
        wrapper.count = wrapper.count + 1&lt;br /&gt;
        return func(*args, **kw)&lt;br /&gt;
    wrapper.count = 0&lt;br /&gt;
    return wrapper&lt;br /&gt;
&lt;br /&gt;
@fcount&lt;br /&gt;
def f(n):&lt;br /&gt;
    return n*n&lt;br /&gt;
&lt;br /&gt;
print &amp;quot;f.count = &amp;quot;, f.count&lt;br /&gt;
print &amp;quot;f(10) = &amp;quot;, f(10)&lt;br /&gt;
print &amp;quot;f.count = &amp;quot;, f.count&lt;br /&gt;
print &amp;quot;f(3) = &amp;quot;, f(3)&lt;br /&gt;
print &amp;quot;f.count = &amp;quot;, f.count&lt;br /&gt;
print &amp;quot;f(12) = &amp;quot;, f(12)&lt;br /&gt;
print &amp;quot;f.count = &amp;quot;, f.count&lt;br /&gt;
print &amp;quot;f(15) = &amp;quot;, f(15)&lt;br /&gt;
print &amp;quot;f.count = &amp;quot;, f.count&lt;br /&gt;
&lt;br /&gt;
# Output:&lt;br /&gt;
# f.count =  0&lt;br /&gt;
# f(10) =  100&lt;br /&gt;
# f.count =  1&lt;br /&gt;
# f(3) =  9&lt;br /&gt;
# f.count =  2&lt;br /&gt;
# f(12) =  144&lt;br /&gt;
# f.count =  3&lt;br /&gt;
# f(15) =  225&lt;br /&gt;
# f.count =  4&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Great reference: Understanding Python decorators - Stack Overflow - http://stackoverflow.com/questions/739654/understanding-python-decorators&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Example 1:&lt;br /&gt;
 @dec1&lt;br /&gt;
 def func(arg1, arg2, ...): pass&lt;br /&gt;
&lt;br /&gt;
 # equivalent to:&lt;br /&gt;
 def func(arg1, arg2, ...): pass&lt;br /&gt;
 func = dec1(func)&lt;br /&gt;
&lt;br /&gt;
Example 2:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
@dec2&lt;br /&gt;
@dec1&lt;br /&gt;
def func(arg1, arg2, ...):&lt;br /&gt;
    pass&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# equivalent to:&lt;br /&gt;
def func(arg1, arg2, ...):&lt;br /&gt;
    pass&lt;br /&gt;
func = dec2(dec1(func))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example 3:&lt;br /&gt;
 @decomaker(argA, argB, ...)&lt;br /&gt;
 def func(arg1, arg2, ...):&lt;br /&gt;
     pass&lt;br /&gt;
&lt;br /&gt;
 # equivalent to:&lt;br /&gt;
 func = decomaker(argA, argB, ...)(func)&lt;br /&gt;
&lt;br /&gt;
 # example:&lt;br /&gt;
 @accepts(int,int)&lt;br /&gt;
 @returns(float)&lt;br /&gt;
 def bar(low,high):&lt;br /&gt;
     pass&lt;br /&gt;
&lt;br /&gt;
Example 4: (overrides and ignores passed in function - bad, unless desired)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def spamrun(fn):&lt;br /&gt;
    def sayspam(*args):&lt;br /&gt;
        print &amp;quot;spam, spam, spam&amp;quot;&lt;br /&gt;
    return sayspam&lt;br /&gt;
&lt;br /&gt;
@spamrun&lt;br /&gt;
def useful(a, b):&lt;br /&gt;
    print a**2 + b**2&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example 5: (Decorator that modifies behavior of undecorated func)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def addspam(fn):&lt;br /&gt;
    def new(*args):&lt;br /&gt;
        print &amp;quot;spam, spam, spam&amp;quot;&lt;br /&gt;
        return fn(*args)&lt;br /&gt;
    return new&lt;br /&gt;
&lt;br /&gt;
@addspam&lt;br /&gt;
def useful(a, b):&lt;br /&gt;
    print a**2 + b**2&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
My Example 1: (print args and continue to function)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def showargs(fn):&lt;br /&gt;
    def doshowargs(*args, **kw):&lt;br /&gt;
        print &amp;quot;Args for:&amp;quot;, fn.__name__, args, kw&lt;br /&gt;
        return fn(*args, **kw)&lt;br /&gt;
    return doshowargs&lt;br /&gt;
&lt;br /&gt;
@showargs&lt;br /&gt;
def useful(a, b):&lt;br /&gt;
    print a**2 + b**2&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Another Example: [http://stackoverflow.com/questions/739654/understanding-python-decorators]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def makebold(fn):&lt;br /&gt;
    def wrapped(*args, **kw):&lt;br /&gt;
        return &amp;quot;&amp;lt;b&amp;gt;&amp;quot; + fn(*args, **kw) + &amp;quot;&amp;lt;/b&amp;gt;&amp;quot;&lt;br /&gt;
    return wrapped&lt;br /&gt;
&lt;br /&gt;
def makeitalic(fn):&lt;br /&gt;
    def wrapped(*args, **kw):&lt;br /&gt;
        return &amp;quot;&amp;lt;i&amp;gt;&amp;quot; + fn(*args, **kw) + &amp;quot;&amp;lt;/i&amp;gt;&amp;quot;&lt;br /&gt;
    return wrapped&lt;br /&gt;
&lt;br /&gt;
@makebold&lt;br /&gt;
@makeitalic&lt;br /&gt;
def hello(msg):&lt;br /&gt;
    return msg&lt;br /&gt;
&lt;br /&gt;
print hello(&amp;quot;hello world&amp;quot;)&lt;br /&gt;
# output: &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;hello world&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* PEP 318 -- Decorators for Functions and Methods - http://www.python.org/dev/peps/pep-0318/&lt;br /&gt;
* Charming Python: Decorators make magic easy - http://www.ibm.com/developerworks/linux/library/l-cpdecor/index.html&lt;br /&gt;
* What are some common uses for Python decorators? - Stack Overflow - http://stackoverflow.com/questions/489720/what-are-some-common-uses-for-python-decorators&lt;br /&gt;
* Understanding Python decorators - Stack Overflow - http://stackoverflow.com/questions/739654/understanding-python-decorators&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
Utah Python July 2013 Meeting - Decorator Examples: [https://www.youtube.com/watch?v=uh9uhzitdvw]&lt;br /&gt;
&lt;br /&gt;
Example of uses:&lt;br /&gt;
* Count function calls&lt;br /&gt;
* Add additional output (debugging)&lt;br /&gt;
* Timing code&lt;br /&gt;
* Thread synchronization (locks)&lt;br /&gt;
* Type checking&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
## Simple wrapping call&lt;br /&gt;
def shout(f):&lt;br /&gt;
    def wrapper(*args):&lt;br /&gt;
        print(&#039;This is before {name}&#039;.format(name=f.__name__))&lt;br /&gt;
        ret = f(*args)&lt;br /&gt;
        print(&#039;This is after {name}&#039;.format(name=f.__name__))&lt;br /&gt;
        return ret&lt;br /&gt;
    wrapper.__name__ = f.__name__&lt;br /&gt;
    return wrapper&lt;br /&gt;
&lt;br /&gt;
@shout&lt;br /&gt;
def echo(text):&lt;br /&gt;
    print(text)&lt;br /&gt;
&lt;br /&gt;
echo(&#039;this is a test&#039;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
## Counting function calls&lt;br /&gt;
def count(f):&lt;br /&gt;
    def wrapper(*args):&lt;br /&gt;
        wrapper.counter += 1&lt;br /&gt;
        print(&amp;quot;Function called {count} times&amp;quot;.format(count=wrapper.counter))&lt;br /&gt;
        return f(*args)&lt;br /&gt;
    wrapper.counter = 0&lt;br /&gt;
    # change wrapper name, or it will just be &#039;wrapper&#039; (for inspection)&lt;br /&gt;
    wrapper.__name__ = f.__name__&lt;br /&gt;
    return wrapper&lt;br /&gt;
&lt;br /&gt;
@count&lt;br /&gt;
def donothing():&lt;br /&gt;
    pass&lt;br /&gt;
&lt;br /&gt;
donothing()&lt;br /&gt;
donothing()&lt;br /&gt;
print(&amp;quot;Function called a total of {count} times&amp;quot;.format(count=donothing.counter))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
## Timing your code&lt;br /&gt;
import time&lt;br /&gt;
&lt;br /&gt;
def timer(f):&lt;br /&gt;
    def wrapper(*arg):&lt;br /&gt;
        t = time.time()&lt;br /&gt;
        ret = f(*arg)&lt;br /&gt;
        print(&amp;quot;Took {elapsedtime} seconds&amp;quot;.format(elapsedtime=time.time()-t))&lt;br /&gt;
        return ret&lt;br /&gt;
    return wrapper&lt;br /&gt;
&lt;br /&gt;
@timer&lt;br /&gt;
def fact(n):&lt;br /&gt;
    prod = 1&lt;br /&gt;
    while n &amp;gt; 0:&lt;br /&gt;
        prod *= n&lt;br /&gt;
        n -= 1&lt;br /&gt;
    return prod&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
total = fact(10000)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
## Synchronization&lt;br /&gt;
import threading&lt;br /&gt;
&lt;br /&gt;
def synchronized(lock):&lt;br /&gt;
    def wrap(f):&lt;br /&gt;
        def wrapper(*args, **kwargs):&lt;br /&gt;
            lock.acquire()&lt;br /&gt;
            try:&lt;br /&gt;
                return f(*args, **kwargs)&lt;br /&gt;
            finally:&lt;br /&gt;
                lock.release()&lt;br /&gt;
        return wrapper&lt;br /&gt;
    return wrap&lt;br /&gt;
&lt;br /&gt;
mylock = threading.Lock()&lt;br /&gt;
&lt;br /&gt;
@synchronized(mylock)&lt;br /&gt;
def myfunc():&lt;br /&gt;
    pass&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
## Type checking&lt;br /&gt;
def myMethod(ID, name):&lt;br /&gt;
    &#039;&#039;&#039; Old way &#039;&#039;&#039;&lt;br /&gt;
    if not (isinstance(ID, &#039;uint&#039;) and isinstance(name, &#039;utf8string&#039;)):&lt;br /&gt;
        raise Exception()&lt;br /&gt;
&lt;br /&gt;
def accepts(*typeargs):&lt;br /&gt;
    &#039;&#039;&#039; Decorator way &#039;&#039;&#039;&lt;br /&gt;
    def wrap(f):&lt;br /&gt;
        def wrapper(*args):&lt;br /&gt;
            for a, t in zip(args, typeargs):&lt;br /&gt;
                if not isinstance(a, t):&lt;br /&gt;
                    raise Exception(&#039;{a} not of type {t}&#039;.format(a=a, t=t))&lt;br /&gt;
            return f(*args)&lt;br /&gt;
        return wrapper&lt;br /&gt;
    return wrap&lt;br /&gt;
&lt;br /&gt;
@accepts(int)&lt;br /&gt;
def add1(n):&lt;br /&gt;
    return n + 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
## Memoize&lt;br /&gt;
def memoize(f):&lt;br /&gt;
    def wrapper(*args):&lt;br /&gt;
        if not wrapper.ret:&lt;br /&gt;
            wrapper.ret = f(*args)&lt;br /&gt;
        return wrapper.ret&lt;br /&gt;
    wrapper.ret = False&lt;br /&gt;
    wrapper.__name__ = f.__name__&lt;br /&gt;
    return wrapper&lt;br /&gt;
&lt;br /&gt;
import time&lt;br /&gt;
&lt;br /&gt;
@memoize&lt;br /&gt;
def sumto10():&lt;br /&gt;
    count = 0&lt;br /&gt;
    sum = 0&lt;br /&gt;
    while count &amp;lt; 10:&lt;br /&gt;
        sum += count&lt;br /&gt;
        time.sleep(1)&lt;br /&gt;
        count += 1&lt;br /&gt;
    return sum&lt;br /&gt;
&lt;br /&gt;
# first time will count slow&lt;br /&gt;
print sumto10()&lt;br /&gt;
# second time will return cached value instantly&lt;br /&gt;
print sumto10()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Memoize: &amp;quot;Caches a function&#039;s return value each time it is called. If called later with the same arguments, the cached value is returned (not reevaluated)&amp;quot; [http://wiki.python.org/moin/PythonDecoratorLibrary#Memoize]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
## Nested decorators&lt;br /&gt;
import time&lt;br /&gt;
@shout&lt;br /&gt;
@memoize&lt;br /&gt;
def test1():&lt;br /&gt;
  print &amp;quot;calculating&amp;quot;&lt;br /&gt;
  time.sleep(3)&lt;br /&gt;
  return 100&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Order is important!  For tested decorators the execution order is from the top to the bottom.  If you reverse @shout and @memoize, the @shout will not run because of the way @memoize was written.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
## registry&lt;br /&gt;
registry = []&lt;br /&gt;
# can also decorate decorators:&lt;br /&gt;
@shout&lt;br /&gt;
def registry(f):&lt;br /&gt;
    registry.append(f)&lt;br /&gt;
    return f&lt;br /&gt;
&lt;br /&gt;
@register&lt;br /&gt;
def test2():&lt;br /&gt;
    pass&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Decorator is just a function that returns a function.&lt;br /&gt;
&lt;br /&gt;
Can use functools to automatically update decorator wrappers with __name__, etc [http://docs.python.org/2/library/functools.html]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
## Auto syntax sygar the wrapper for you&lt;br /&gt;
import functools&lt;br /&gt;
def my_decorator(f):&lt;br /&gt;
    @functools.wraps(f)&lt;br /&gt;
    def wrapper(*args, **kwds):&lt;br /&gt;
        print &#039;Calling decorated function&#039;&lt;br /&gt;
        return f(*args, **kwds)&lt;br /&gt;
    return wrapper&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Class Method Decorators ===&lt;br /&gt;
&lt;br /&gt;
Static methods: [http://docs.python.org/library/functions.html#staticmethod]&lt;br /&gt;
: Similar to C++ and Java static methods&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class C:&lt;br /&gt;
  @staticmethod&lt;br /&gt;
  def say(msg):&lt;br /&gt;
    print(msg)&lt;br /&gt;
&lt;br /&gt;
C.say(&#039;hi&#039;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Class method: [http://docs.python.org/library/functions.html#classmethod]&lt;br /&gt;
: A class method receives the class as implicit first argument, just like an instance method receives the instance.&lt;br /&gt;
: Class methods are different than C++ or Java static methods. If you want those, see staticmethod() in this section.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    @classmethod&lt;br /&gt;
    def setup_parser(cls, parser):&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See also [[#Class Properties]]&lt;br /&gt;
&lt;br /&gt;
=== Class Properties ===&lt;br /&gt;
&lt;br /&gt;
Properties: (not using decorators)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class C(object):&lt;br /&gt;
    def __init__(self):&lt;br /&gt;
        self._x = None&lt;br /&gt;
    def getx(self):&lt;br /&gt;
        print(&amp;quot;get x&amp;quot;)&lt;br /&gt;
        return self._x&lt;br /&gt;
    def setx(self, value):&lt;br /&gt;
        print(&amp;quot;set x&amp;quot;)&lt;br /&gt;
        self._x = value&lt;br /&gt;
    def delx(self):&lt;br /&gt;
        print(&amp;quot;del x&amp;quot;)&lt;br /&gt;
        del self._x&lt;br /&gt;
    x = property(getx, setx, delx, &amp;quot;I&#039;m the &#039;x&#039; property.&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#usage&lt;br /&gt;
c = C()&lt;br /&gt;
c.x = 5&lt;br /&gt;
print(c.x)&lt;br /&gt;
del(c.x)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Getter and Setter Property Decorators: [http://docs.python.org/library/functions.html#property]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class C(object):    # make sure to inherit from object for these properties to work!&lt;br /&gt;
    def __init__(self):&lt;br /&gt;
        self._x = None&lt;br /&gt;
    &lt;br /&gt;
    @property&lt;br /&gt;
    def x(self):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;I&#039;m the &#039;x&#039; property.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        print(&amp;quot;get x&amp;quot;)&lt;br /&gt;
        return self._x&lt;br /&gt;
    &lt;br /&gt;
    @x.setter   # python &amp;gt;= 2.6&lt;br /&gt;
    def x(self, value):&lt;br /&gt;
        print(&amp;quot;set x&amp;quot;)&lt;br /&gt;
        self._x = value&lt;br /&gt;
    &lt;br /&gt;
    @x.deleter  # python &amp;gt;= 2.6&lt;br /&gt;
    def x(self):&lt;br /&gt;
        print(&amp;quot;del x&amp;quot;)&lt;br /&gt;
        del self._x&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#usage&lt;br /&gt;
c = C()&lt;br /&gt;
c.x = 5&lt;br /&gt;
print(c.x)&lt;br /&gt;
del(c.x)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: If you don&#039;t add the @x.setter, the property will be read only, and will throw a &amp;quot;AttributeError: can&#039;t set attribute&amp;quot; if attempted to be set.&lt;br /&gt;
&lt;br /&gt;
Using x.getter example: [http://wiki.python.org/moin/AlternativeDescriptionOfProperty]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Cls(object):&lt;br /&gt;
    def __init__(self):&lt;br /&gt;
        self._x = 100&lt;br /&gt;
&lt;br /&gt;
    x = property()&lt;br /&gt;
&lt;br /&gt;
    @x.getter&lt;br /&gt;
    def x(self):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;I&#039;m the &#039;x&#039; property.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        return self._x&lt;br /&gt;
&lt;br /&gt;
    @x.setter&lt;br /&gt;
    def x(self, value):&lt;br /&gt;
        self._x = value&lt;br /&gt;
&lt;br /&gt;
    @x.deleter&lt;br /&gt;
    def x(self):&lt;br /&gt;
        del self._x&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Custom Decorators ===&lt;br /&gt;
&lt;br /&gt;
decorator&lt;br /&gt;
 @dec1&lt;br /&gt;
 def func(arg1, arg2, ...): pass&lt;br /&gt;
&lt;br /&gt;
equivalent to:&lt;br /&gt;
 def func(arg1, arg2, ...): pass&lt;br /&gt;
 func = dec1(func)&lt;br /&gt;
&lt;br /&gt;
Basic layout (names are arbitrary):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def my_decorator(function_name):&lt;br /&gt;
  # update wrapper.__doc__ and .func_name&lt;br /&gt;
  # or @functools.wraps(my_wrapper)&lt;br /&gt;
  def mywrapper(*args, **kw):&lt;br /&gt;
    # do something before&lt;br /&gt;
    result = function_name(*args, **kw)&lt;br /&gt;
    # do something after&lt;br /&gt;
    return result&lt;br /&gt;
  return my_wrapper&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def limit(length):&lt;br /&gt;
  def decorator(function):&lt;br /&gt;
    def wrapper(*args, **kw):&lt;br /&gt;
      result = function(*args, **kw)&lt;br /&gt;
      result = result[:length]&lt;br /&gt;
      return result&lt;br /&gt;
    return wrapper&lt;br /&gt;
  return decorator&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
@limit(3)&lt;br /&gt;
def echo(foo):  return foo&lt;br /&gt;
&lt;br /&gt;
echo(&#039;123456&#039;)  # &#039;123&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== assert ===&lt;br /&gt;
&lt;br /&gt;
 assert True&lt;br /&gt;
 assert False  # exception&lt;br /&gt;
 assert 1 == 1&lt;br /&gt;
 assert 1 == 2, &amp;quot;some message&amp;quot;  # AssertionError: some message&lt;br /&gt;
&lt;br /&gt;
=== Snake Case ===&lt;br /&gt;
&lt;br /&gt;
Convert Camel Case to Snake Case: [http://stackoverflow.com/questions/1175208/elegant-python-function-to-convert-camelcase-to-snake-case]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def snake_case(name):&lt;br /&gt;
    s1 = re.sub(&#039;(.)([A-Z][a-z]+)&#039;, r&#039;\1_\2&#039;, name)&lt;br /&gt;
    return re.sub(&#039;([a-z0-9])([A-Z])&#039;, r&#039;\1_\2&#039;, s1).lower()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; convert(&#039;CamelCase&#039;)&lt;br /&gt;
&#039;camel_case&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Camel Case ===&lt;br /&gt;
&lt;br /&gt;
Camel Case: [http://stackoverflow.com/questions/8347048/camelcase-every-string-any-standard-library]&lt;br /&gt;
&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; &#039;&#039;.join(x for x in &#039;make IT camel CaSe&#039;.title() if not x.isspace())&lt;br /&gt;
 &#039;MakeItCamelCase&#039;&lt;br /&gt;
&lt;br /&gt;
To titleize a sentence:&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; &amp;quot;this is a test&amp;quot;.title()&lt;br /&gt;
 &amp;quot;This Is A Test&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Lambda ===&lt;br /&gt;
&lt;br /&gt;
Simple functions&lt;br /&gt;
 mul = lambda a, b: a * b&lt;br /&gt;
&lt;br /&gt;
 # equivalent to:&lt;br /&gt;
 def mul(a, b):&lt;br /&gt;
   return a * b&lt;br /&gt;
&lt;br /&gt;
Sort usage:&lt;br /&gt;
 data = [dict(number=x) for x in &#039;036149&#039;]&lt;br /&gt;
 data.sort(key=lambda x: float(x[&#039;number&#039;]))&lt;br /&gt;
&lt;br /&gt;
Compare usage:&lt;br /&gt;
 data = [dict(number=x) for x in &#039;036149&#039;]&lt;br /&gt;
 data.sort(cmp=lambda x,y: cmp(x[&#039;number&#039;], y[&#039;number&#039;]))&lt;br /&gt;
&lt;br /&gt;
Boolean:&lt;br /&gt;
 lambda x: x % 3 == 0&lt;br /&gt;
&lt;br /&gt;
Multiple parameter:&lt;br /&gt;
 lambda x, y: x + y&lt;br /&gt;
&lt;br /&gt;
Call another function:&lt;br /&gt;
 lambda word: len(word)&lt;br /&gt;
&lt;br /&gt;
Strings:&lt;br /&gt;
 lambda line: line.split()[2]&lt;br /&gt;
&lt;br /&gt;
Embedded:&lt;br /&gt;
 def transform(n):&lt;br /&gt;
    return lambda x: x + n&lt;br /&gt;
&lt;br /&gt;
No parameters:&lt;br /&gt;
 lambda: 1&lt;br /&gt;
&lt;br /&gt;
Default parameters:&lt;br /&gt;
 lambda x=1: x+1&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* Python: Lambda Functions - http://www.secnetix.de/olli/Python/lambda_functions.hawk&lt;br /&gt;
&lt;br /&gt;
=== Map ===&lt;br /&gt;
&lt;br /&gt;
Apply a function to items of a sequence:&lt;br /&gt;
 map(str, range(3))   # [&#039;0&#039;, &#039;1&#039;, &#039;2&#039;]&lt;br /&gt;
&lt;br /&gt;
Note: list comprehensions can replace map and filter&lt;br /&gt;
&lt;br /&gt;
=== Reduce ===&lt;br /&gt;
&lt;br /&gt;
Apply a function to pairs of the sequence:&lt;br /&gt;
 import operator&lt;br /&gt;
 reduce(operator.mul, [1,2,3,4])   # 24   - ((1*2)*3)*4)&lt;br /&gt;
&lt;br /&gt;
Note: sum or for loop can replace reduce&lt;br /&gt;
&lt;br /&gt;
=== Filter ===&lt;br /&gt;
&lt;br /&gt;
Return a sequence of items for which function(item) is True&lt;br /&gt;
 filter(lambda x: x &amp;gt;= 0, [0, -1, 3])  # [0, 3]&lt;br /&gt;
&lt;br /&gt;
Note: list comprehensions can replace map and filter&lt;br /&gt;
&lt;br /&gt;
Find matching items in two lists:&lt;br /&gt;
 a = [&#039;a&#039;,&#039;b&#039;,&#039;c&#039;]&lt;br /&gt;
 b = [&#039;c&#039;,&#039;d&#039;]&lt;br /&gt;
 filter(lambda x: x in a, b)  # returns only &#039;c&#039; as it is in both lists&lt;br /&gt;
&lt;br /&gt;
=== List comprehension ===&lt;br /&gt;
&lt;br /&gt;
Nothing more than Syntactic Sugar&lt;br /&gt;
&lt;br /&gt;
5. Data Structures — Python v2.7.5 documentation - http://docs.python.org/2/tutorial/datastructures.html#list-comprehensions&lt;br /&gt;
: &amp;quot;List comprehensions provide a concise way to create lists.&amp;quot;&lt;br /&gt;
: &amp;quot;A list comprehension consists of &#039;&#039;&#039;brackets&#039;&#039;&#039; containing an &#039;&#039;&#039;expression&#039;&#039;&#039; followed by a &#039;&#039;&#039;for clause&#039;&#039;&#039;, then &#039;&#039;&#039;zero or more for or if clauses&#039;&#039;&#039;. &amp;quot;&lt;br /&gt;
&lt;br /&gt;
Remove newlines from each item in a list:&lt;br /&gt;
 mylist = [x.strip() for x in mylist]&lt;br /&gt;
&lt;br /&gt;
Simple:&lt;br /&gt;
 doubled = [x*2 for x in mylist]&lt;br /&gt;
 squares = [x**2 for x in range(10)]&lt;br /&gt;
&lt;br /&gt;
If:&lt;br /&gt;
 [ 2*x for x in range(1,10) if x &amp;gt;= 5 ]&lt;br /&gt;
&lt;br /&gt;
Complex:&lt;br /&gt;
 [(x, y) for x in [1,2,3] for y in [3,1,4] if x != y]&lt;br /&gt;
&lt;br /&gt;
Expanding PI:&lt;br /&gt;
 [str(round(pi, i)) for i in range(1, 6)]&lt;br /&gt;
&lt;br /&gt;
Return list of words&lt;br /&gt;
 my_list = [current_word.lower() for current_word in words]&lt;br /&gt;
&lt;br /&gt;
Utah Python July 2013 Meeting: (http://basepi.net)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Iterative&lt;br /&gt;
squares = []&lt;br /&gt;
for x in range(10):&lt;br /&gt;
    squares.append(x**2)&lt;br /&gt;
# [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]&lt;br /&gt;
&lt;br /&gt;
## Functional&lt;br /&gt;
squares = map(lambda x: x**2, range(10))&lt;br /&gt;
&lt;br /&gt;
## List comprehension&lt;br /&gt;
squares = [x**2 for x in range(10)]&lt;br /&gt;
even_squares = [x**2 for x in range(10) if x%2 == 0]&lt;br /&gt;
&lt;br /&gt;
# get hash of strings in list:&lt;br /&gt;
import sha&lt;br /&gt;
strings = [&#039;Python is cool!&#039;, &#039;I love python&#039;]&lt;br /&gt;
hashes = [sha.sha(x).digest() for x in strings]&lt;br /&gt;
&lt;br /&gt;
# flatten matrix:&lt;br /&gt;
matrix = [[1, 2, 3], [4, 5, 6]]&lt;br /&gt;
[x for row in matrix for x in row]&lt;br /&gt;
# [1, 2, 3, 4, 5, 6]&lt;br /&gt;
&lt;br /&gt;
# build matrix:&lt;br /&gt;
[(x,y) for x in range(10) for y in range(10)]&lt;br /&gt;
# matrix of not both odd and not both even&lt;br /&gt;
[(x,y) for x in range(10) for y in range(10) if x%2 != y%2]&lt;br /&gt;
&lt;br /&gt;
# suck lines of files into list, ignoring commented lines&lt;br /&gt;
[line.strip().split(&amp;quot;\t&amp;quot;) for line in open(&amp;quot;my_file.tab&amp;quot;)&lt;br /&gt;
    if not line.startswith(&#039;#&#039;)]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* 5.1.4. List Comprehensions - Data Structures — Python v2.7.2 documentation - http://docs.python.org/tutorial/datastructures.html#list-comprehensions&lt;br /&gt;
* Utah Python July 2013 Meeting - YouTube - https://www.youtube.com/watch?v=uh9uhzitdvw [http://basepi.net]&lt;br /&gt;
&lt;br /&gt;
=== [http://docs.python.org/reference/expressions#calls Mass Parameter Passing] ===&lt;br /&gt;
&lt;br /&gt;
Using: *args and **kw&lt;br /&gt;
* *args a tuple of remaining unnamed parameters&lt;br /&gt;
* **kw a dictionary of remaining named parameters&lt;br /&gt;
&lt;br /&gt;
 def param_func(a, b=&#039;b&#039;, *args, **kw):&lt;br /&gt;
   print( [a, b, args, kw] )&lt;br /&gt;
&lt;br /&gt;
WARNING: If not careful, this can result in this error: &amp;quot;TypeError: param_func() got multiple values for keyword argument &#039;myvar&#039;&amp;quot;.  Might be better to just use:&lt;br /&gt;
&lt;br /&gt;
 def param_func(*args, **kw):&lt;br /&gt;
   print( [args, kw] )&lt;br /&gt;
&lt;br /&gt;
 param_func(1, 2, 3, 4, 5)  # [1, 2, (3, 4, 5), {}]&lt;br /&gt;
 param_func(1, 2, 3, 4, 5, joe=&#039;test&#039;)  # [1, 2, (3, 4, 5), {&#039;joe&#039;: &#039;test&#039;}]&lt;br /&gt;
 mylist = (&amp;quot;a&amp;quot;, &amp;quot;c&amp;quot;, &amp;quot;g&amp;quot;, &amp;quot;h&amp;quot;, 5)&lt;br /&gt;
 param_func(mylist)  # [(&#039;a&#039;, &#039;c&#039;, &#039;g&#039;, &#039;h&#039;, 5), &#039;b&#039;, (), {}]&lt;br /&gt;
 param_func(*mylist)  # [&#039;a&#039;, &#039;c&#039;, (&#039;g&#039;, &#039;h&#039;, 5), {}]  *tricky*&lt;br /&gt;
 Note: *mydict will strip out just keys and treat like list&lt;br /&gt;
 Note: **mydict will treat like named parameters&lt;br /&gt;
&lt;br /&gt;
 def mywrapper(*args, **kw):&lt;br /&gt;
   # do something before&lt;br /&gt;
   result = function_name(*args, **kw)&lt;br /&gt;
&lt;br /&gt;
Passing arbitrary parameters:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def fun2(**kw):&lt;br /&gt;
  print kw  # {&#039;a&#039;: &#039;1&#039;, &#039;b&#039;: &#039;2&#039;, &#039;c&#039;: &#039;3&#039;}&lt;br /&gt;
&lt;br /&gt;
def fun1(c=&#039;3&#039;, **kw):&lt;br /&gt;
 print kw  # {&#039;a&#039;: &#039;1&#039;, &#039;b&#039;: &#039;2&#039;}&lt;br /&gt;
 fun2(c=&#039;3&#039;, **kw)&lt;br /&gt;
&lt;br /&gt;
fun1(a=&#039;1&#039;, b=&#039;2&#039;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [http://www.python.org/dev/peps/pep-0234/ Iteration Protocol] ===&lt;br /&gt;
&lt;br /&gt;
[http://www.python.org/dev/peps/pep-0234/ PEP 234 -- Iterators]&lt;br /&gt;
&lt;br /&gt;
Making a class iterable:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class mycount(object):&lt;br /&gt;
  def __init__(self, max):&lt;br /&gt;
    self.x = 0&lt;br /&gt;
    self.max = max&lt;br /&gt;
  def __iter__(self):  # return object that implements __next__() or next()&lt;br /&gt;
    return self&lt;br /&gt;
  def next(self):&lt;br /&gt;
    if self.x &amp;lt; self.max:&lt;br /&gt;
      self.x += 1&lt;br /&gt;
      return self.x&lt;br /&gt;
    else:&lt;br /&gt;
      self.x = 0&lt;br /&gt;
      raise StopIteration()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 for i in mycount(10): print i     # 1 ... 10&lt;br /&gt;
 print [x for x in mycount(10) ]   # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]&lt;br /&gt;
&lt;br /&gt;
 c = mycount(10)&lt;br /&gt;
 for i in c: print i    # 1 ... 10&lt;br /&gt;
 [ x for x in c ]       # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]&lt;br /&gt;
&lt;br /&gt;
=== Generators ===&lt;br /&gt;
&lt;br /&gt;
Generators are functions that return to their previous state (using &#039;yield&#039;) when iterated over, which can be used in for loops.&lt;br /&gt;
&lt;br /&gt;
==== Yield ====&lt;br /&gt;
&lt;br /&gt;
Improve on Iterators:&lt;br /&gt;
* Infinite data (infinite iterators)&lt;br /&gt;
* Memory-intensive iteration&lt;br /&gt;
* Cooperative Multi-threading&lt;br /&gt;
&lt;br /&gt;
Generators are functions that return to their previous state when iterated over, which can be used in for loops.&lt;br /&gt;
&lt;br /&gt;
Note: Generators throw StopIteration when completed&lt;br /&gt;
&lt;br /&gt;
Note: the &#039;yield&#039; keyword will stash away the state of the function and return the value. (Continuations)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def gen_range(end):&lt;br /&gt;
  cur = 0&lt;br /&gt;
  while cur &amp;lt; end:&lt;br /&gt;
    yield cur&lt;br /&gt;
    # return here next time&lt;br /&gt;
    cur += 1&lt;br /&gt;
&lt;br /&gt;
# for loop iteration&lt;br /&gt;
for i in gen_range(10):  print i&lt;br /&gt;
&lt;br /&gt;
# manual iteration&lt;br /&gt;
my_gen = gen_range(10)&lt;br /&gt;
try:&lt;br /&gt;
  while True:&lt;br /&gt;
    print my_gen.next()&lt;br /&gt;
except StopIteration:&lt;br /&gt;
  pass&lt;br /&gt;
&lt;br /&gt;
# list comprehension&lt;br /&gt;
numbers = [x for x in gen_range(10)]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: one can place an empty &#039;return&#039; in a generator if needed.  A &#039;return&#039; with argument is invalid.&lt;br /&gt;
&lt;br /&gt;
Making a class generate:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class mycount(object):&lt;br /&gt;
  def __init__(self, max):&lt;br /&gt;
    self.max = max&lt;br /&gt;
  def __iter__(self):&lt;br /&gt;
    return self.next()      # change here&lt;br /&gt;
  def next(self):           # change here&lt;br /&gt;
    x = 0&lt;br /&gt;
    while x &amp;lt; self.max:&lt;br /&gt;
      x += 1&lt;br /&gt;
      yield x&lt;br /&gt;
&lt;br /&gt;
for i in mycount(10): print i     # 1 ... 10&lt;br /&gt;
print [x for x in mycount(10) ]   # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]&lt;br /&gt;
&lt;br /&gt;
c = mycount(10)&lt;br /&gt;
for i in c: print i    # 1 ... 10&lt;br /&gt;
[ x for x in c ]       # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]&lt;br /&gt;
&lt;br /&gt;
itr = mycount(10).next()&lt;br /&gt;
itr.next()  # 1&lt;br /&gt;
itr.next()  # 2  - eventually throws StopIteration exception&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Utah Python July 2013 Meeting: [https://www.youtube.com/watch?v=uh9uhzitdvw] [http://basepi.net]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
* Iterators are used to traverse a list&lt;br /&gt;
* Generators are more powerful Iterators&lt;br /&gt;
&lt;br /&gt;
# simple &#039;n&#039; number in functional form&lt;br /&gt;
def firstn(n):&lt;br /&gt;
    num = 0&lt;br /&gt;
    nums = []&lt;br /&gt;
    while num &amp;lt; n:&lt;br /&gt;
        nums.append(num)&lt;br /&gt;
        num += 1&lt;br /&gt;
    return nums&lt;br /&gt;
&lt;br /&gt;
# simple &#039;n&#039; number in generator form&lt;br /&gt;
def firstn(n):&lt;br /&gt;
    num = 0&lt;br /&gt;
    while num &amp;lt; n:&lt;br /&gt;
        yield num&lt;br /&gt;
        num += 1&lt;br /&gt;
&lt;br /&gt;
-&lt;br /&gt;
&lt;br /&gt;
# Infinite list generator&lt;br /&gt;
def counter():&lt;br /&gt;
    num = 0&lt;br /&gt;
    while True:&lt;br /&gt;
        yield num&lt;br /&gt;
        num += 1&lt;br /&gt;
&lt;br /&gt;
# Fibbonacci generator&lt;br /&gt;
def fib():&lt;br /&gt;
    num1 = 0&lt;br /&gt;
    num2 = 1&lt;br /&gt;
    yield num1&lt;br /&gt;
    while True:&lt;br /&gt;
        num1, num2 = num2, num1 + num2&lt;br /&gt;
        yield num1&lt;br /&gt;
&lt;br /&gt;
# Fibbonacci generator 2&lt;br /&gt;
def fib(n):&lt;br /&gt;
    num1 = 0&lt;br /&gt;
    num2 = 1&lt;br /&gt;
    count = 0&lt;br /&gt;
    yield num1&lt;br /&gt;
    while count &amp;lt; n:&lt;br /&gt;
        count += 1&lt;br /&gt;
        num1, num2 = num2, num1 + num2&lt;br /&gt;
        yield num1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Utah Python July 2013 Meeting: [https://www.youtube.com/watch?v=uh9uhzitdvw] [http://basepi.net]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
## Cooperative Multi-Threading:&lt;br /&gt;
# Cooperative multithreading relies on the threads themselves to relinquish control once they are at a stopping point.&lt;br /&gt;
&lt;br /&gt;
def mythread(name):&lt;br /&gt;
    print(&#039;Starting Thread: {name}...&#039;.format(name=name))&lt;br /&gt;
    counter = 10&lt;br /&gt;
    while counter &amp;gt; 0:&lt;br /&gt;
        print(&#039;Thread: {name} doing some work!&#039;.format(name=name))&lt;br /&gt;
        counter -= 1&lt;br /&gt;
        yield&lt;br /&gt;
&lt;br /&gt;
thread1 = mythread(&#039;Alice&#039;)&lt;br /&gt;
thread2 = mythread(&#039;Bob&#039;)&lt;br /&gt;
thread3 = mythread(&#039;Trudy&#039;)&lt;br /&gt;
&lt;br /&gt;
try:&lt;br /&gt;
    while True:&lt;br /&gt;
        thread1.next()&lt;br /&gt;
        thread2.next()&lt;br /&gt;
        thread3.next()&lt;br /&gt;
except StopIteration:&lt;br /&gt;
    pass&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* Utah Python July 2013 Meeting: [https://www.youtube.com/watch?v=uh9uhzitdvw] [http://basepi.net]&lt;br /&gt;
** http://files.basepi.net/talks/pyarmory.zip&lt;br /&gt;
&lt;br /&gt;
=== dunder methods ===&lt;br /&gt;
&lt;br /&gt;
Some dunder (double under) methods determine what will happen when + (__add__) or other similar numerical symbols used.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class str_add(object):&lt;br /&gt;
    def __init__(self, name):&lt;br /&gt;
        self.name = name&lt;br /&gt;
    def __add__(self, other):&lt;br /&gt;
        self.name += other.name&lt;br /&gt;
        return self&lt;br /&gt;
        # note: only need to return self if you want to go beyond &#039;a + b&#039;&lt;br /&gt;
&lt;br /&gt;
a = str_add(&#039;a_&#039;)&lt;br /&gt;
b = str_add(&#039;b_&#039;)&lt;br /&gt;
c = str_add(&#039;c_&#039;)&lt;br /&gt;
d = a + b + c&lt;br /&gt;
print(a.name)  # a_b_c_&lt;br /&gt;
print(b.name)  # b_&lt;br /&gt;
print(c.name)  # c_&lt;br /&gt;
print(d.name)  # a_b_c_&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Other common methods to override:&lt;br /&gt;
* __add__ for +&lt;br /&gt;
* __sub__ for -&lt;br /&gt;
* __mul__ for *&lt;br /&gt;
* __div__ for /&lt;br /&gt;
* __mod__ for %&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* Emulating numeric types - http://docs.python.org/2/reference/datamodel.html#emulating-numeric-types&lt;br /&gt;
&lt;br /&gt;
=== [http://docs.python.org/library/doctest.html doctest] ===&lt;br /&gt;
&lt;br /&gt;
test.py:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
This is the &amp;quot;example&amp;quot; module.&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; double(5)&lt;br /&gt;
10&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
def double(n):&lt;br /&gt;
  &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  This is double function&lt;br /&gt;
&lt;br /&gt;
  &amp;gt;&amp;gt;&amp;gt; double(3)&lt;br /&gt;
  6&lt;br /&gt;
  &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  return n * 2&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
    import doctest&lt;br /&gt;
    doctest.testmod()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== unittest ===&lt;br /&gt;
&lt;br /&gt;
 unittest.TestCase&lt;br /&gt;
&lt;br /&gt;
Here is a short script to test three functions from the random module:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import random&lt;br /&gt;
import unittest&lt;br /&gt;
&lt;br /&gt;
class TestSequenceFunctions(unittest.TestCase):&lt;br /&gt;
&lt;br /&gt;
    def setUp(self):&lt;br /&gt;
        self.seq = range(10)&lt;br /&gt;
&lt;br /&gt;
    def test_shuffle(self):&lt;br /&gt;
        # make sure the shuffled sequence does not lose any elements&lt;br /&gt;
        random.shuffle(self.seq)&lt;br /&gt;
        self.seq.sort()&lt;br /&gt;
        self.assertEqual(self.seq, range(10))&lt;br /&gt;
&lt;br /&gt;
        # should raise an exception for an immutable sequence&lt;br /&gt;
        self.assertRaises(TypeError, random.shuffle, (1,2,3))&lt;br /&gt;
&lt;br /&gt;
    def test_choice(self):&lt;br /&gt;
        element = random.choice(self.seq)&lt;br /&gt;
        self.assertTrue(element in self.seq)&lt;br /&gt;
&lt;br /&gt;
    def test_sample(self):&lt;br /&gt;
        with self.assertRaises(ValueError):&lt;br /&gt;
            random.sample(self.seq, 20)&lt;br /&gt;
        for element in random.sample(self.seq, 5):&lt;br /&gt;
            self.assertTrue(element in self.seq)&lt;br /&gt;
&lt;br /&gt;
if __name__ == &#039;__main__&#039;:&lt;br /&gt;
    unittest.main()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The unittest module can be used from the command line to run tests from modules, classes or even individual test methods:&lt;br /&gt;
 python -m unittest test_module1 test_module2&lt;br /&gt;
 python -m unittest test_module.TestClass&lt;br /&gt;
 python -m unittest test_module.TestClass.test_method&lt;br /&gt;
 python -m unittest -v test_module  # verbose&lt;br /&gt;
 python -m unittest -h   # help&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* 25.3. unittest — Unit testing framework — Python v2.7.4 documentation - http://docs.python.org/2/library/unittest.html&lt;br /&gt;
* Python Debugging Tips - Google Drive - https://docs.google.com/presentation/d/130Wl--IzbDh9ymF6KHMu0WrsIwz6k32pav1gFbsw7NI/edit?usp=sharing&lt;br /&gt;
&lt;br /&gt;
=== Internet Access ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Python 3&lt;br /&gt;
from urllib.request import urlopen&lt;br /&gt;
for line in urlopen(&#039;http://tycho.usno.navy.mil/cgi-bin/timer.pl&#039;):&lt;br /&gt;
  line = line.decode(&#039;utf-8&#039;)&lt;br /&gt;
  if &#039;EST&#039; in line or &#039;EDT&#039; in line:  # look for eastern time&lt;br /&gt;
    print(line)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Simple SMTP ===&lt;br /&gt;
&lt;br /&gt;
Requires local STMP server.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import smtplib&lt;br /&gt;
server = smtplib.SMTP(&amp;quot;localhost&amp;quot;)&lt;br /&gt;
server.sendmail(&#039;mrken@demo.oeey.com&#039;, &#039;kenneth@demo.oeey.com&#039;,&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;To: kenneth@demo.oeey.com&lt;br /&gt;
From: mrken@demo.oeey.com&lt;br /&gt;
Subject: This is fun&lt;br /&gt;
&lt;br /&gt;
Beware of the dog.&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;)&lt;br /&gt;
server.quit()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
s = smtplib.SMTP(smtp_server)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
with TLS:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
s = smtplib.SMTP(&amp;quot;smtp.gmail.com&amp;quot;,587)&lt;br /&gt;
s.ehlo()&lt;br /&gt;
s.starttls()&lt;br /&gt;
s.ehlo()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
SSL:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
s = smtplib.SMTP_SSL(&#039;smtp.mail.yahoo.com&#039;, 465)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Data Compress ===&lt;br /&gt;
&lt;br /&gt;
zlib, gzip, bz2, zipfile, tarfile&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import zlib&lt;br /&gt;
s = b&#039;hello world&#039;  # only in python &amp;gt;3&lt;br /&gt;
len(s)&lt;br /&gt;
t = zlib.compress(s)&lt;br /&gt;
zlib.decompress(t)&lt;br /&gt;
zlib.crc32(s)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== gzip ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import gzip&lt;br /&gt;
content = &amp;quot;Lots of content here&amp;quot;&lt;br /&gt;
f = gzip.open(&#039;file.txt.gz&#039;, &#039;wb&#039;)&lt;br /&gt;
f.write(content)&lt;br /&gt;
f.close()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import gzip&lt;br /&gt;
f_in = open(&#039;file.txt&#039;, &#039;rb&#039;)&lt;br /&gt;
f_out = gzip.open(&#039;file.txt.gz&#039;, &#039;wb&#039;)&lt;br /&gt;
f_out.writelines(f_in)&lt;br /&gt;
f_out.close()&lt;br /&gt;
f_in.close()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Performance Timer ===&lt;br /&gt;
&lt;br /&gt;
Time a task repeated 10 times:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from timeit import Timer&lt;br /&gt;
Timer(&#039;t=a; a=b; b=t&#039;, &#039;a=1; b=2&#039;).timeit()&lt;br /&gt;
Timer(&#039;print(&amp;quot;hi&amp;quot;)&#039;).timeit(10)  # repeat 10 times and time&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Simple method:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
start_time = int(time.time())&lt;br /&gt;
... task ...&lt;br /&gt;
compute_time = int(time.time()) - start_time&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Python Version Check ===&lt;br /&gt;
&lt;br /&gt;
Solution:&lt;br /&gt;
&lt;br /&gt;
__init__.py:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Check Python Version:&lt;br /&gt;
import sys&lt;br /&gt;
assert sys.version_info &amp;gt;= (2, 6, 0), &#039;requires Python 2.6 or higher&#039;&lt;br /&gt;
del sys&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
resulting error if not &amp;gt; 2.6:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import nucleon&lt;br /&gt;
Traceback (most recent call last):&lt;br /&gt;
  File &amp;quot;&amp;lt;stdin&amp;gt;&amp;quot;, line 1, in ?&lt;br /&gt;
  File &amp;quot;nucleon/__init__.py&amp;quot;, line 9, in ?&lt;br /&gt;
    assert sys.version_info &amp;gt;= (2, 6, 0), &#039;nucleon requires Python 2.6 or higher&#039;&lt;br /&gt;
AssertionError: nucleon requires Python 2.6 or higher&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Other solutions:&lt;br /&gt;
&lt;br /&gt;
Note: this will throw syntax error on 2.4 due to ternary&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import sys&lt;br /&gt;
if sys.version_info &amp;lt; (2, 4):&lt;br /&gt;
    raise &amp;quot;must use python 2.5 or greater&amp;quot;&lt;br /&gt;
else:&lt;br /&gt;
    # syntax error in 2.4, ok in 2.5&lt;br /&gt;
    x = 1 if True else 2&lt;br /&gt;
    print x&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
maybe solution:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
try:&lt;br /&gt;
  eval(&amp;quot;1 if True else 2&amp;quot;)&lt;br /&gt;
except SyntaxError:&lt;br /&gt;
  # doesn&#039;t have ternary&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; try:&lt;br /&gt;
...     from my_module import twoPointSixCode&lt;br /&gt;
... except Exception: &lt;br /&gt;
...     print &amp;quot;can&#039;t import, probably because your python is too old!&amp;quot;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/env/python&lt;br /&gt;
import sys&lt;br /&gt;
if sys.version_info&amp;lt;(2,6,0):&lt;br /&gt;
  sys.stderr.write(&amp;quot;You need python 2.6 or later to run this script\n&amp;quot;)&lt;br /&gt;
  exit(1)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import sys&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; sys.hexversion  # hex printed as integer&lt;br /&gt;
33817584&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; &#039;%x&#039; % sys.hexversion  # output as hex, not zero fill  2.4.3&lt;br /&gt;
&#039;20403f0&#039;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; sys.hexversion &amp;lt; 0x02060000  # test if version less than 2.6&lt;br /&gt;
True&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; print &amp;quot;0x%08x&amp;quot; % sys.hexversion  # print as hex and zero fill and prepend &#039;0x&#039;&lt;br /&gt;
0x020403f0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import sys&lt;br /&gt;
if sys.hexversion &amp;lt; 0x02060500:&lt;br /&gt;
    print &amp;gt;&amp;gt; sys.stderr, &amp;quot;This script requires python 2.6.5 or higher.&amp;quot;&lt;br /&gt;
    exit(1)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import sys&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; sys.version_info&lt;br /&gt;
(2, 6, 4, &#039;final&#039;, 0)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; if not sys.version_info[:2] == (2, 6):&lt;br /&gt;
...    print &amp;quot;Error, I need python 2.6&amp;quot;&lt;br /&gt;
... else:&lt;br /&gt;
...    from my_module import twoPointSixCode&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* http://stackoverflow.com/questions/446052/python-best-way-to-check-for-python-version-in-program-that-uses-new-language-fe&lt;br /&gt;
* http://stackoverflow.com/questions/1093322/how-do-i-check-what-version-of-python-is-running-my-script&lt;br /&gt;
&lt;br /&gt;
=== [http://docs.python.org/library/struct.html Struct - Binary Data Record Layout] ===&lt;br /&gt;
&lt;br /&gt;
Format Characters:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Format	C Type		Python type 	Standard size&lt;br /&gt;
x	pad byte	no value	  	 &lt;br /&gt;
c	char		str of len 1	1	 &lt;br /&gt;
b	signed char	integer		1&lt;br /&gt;
B	unsigned char	integer 	1&lt;br /&gt;
?	_Bool		bool 		1&lt;br /&gt;
h	short		integer 	2&lt;br /&gt;
H	unsigned short 	integer 	2&lt;br /&gt;
i	int		integer 	4&lt;br /&gt;
I	unsigned int 	integer 	4&lt;br /&gt;
l	long		integer 	4&lt;br /&gt;
L	unsigned long	integer		4&lt;br /&gt;
q	long long	integer		8&lt;br /&gt;
Q	unsigned long long    integer	8&lt;br /&gt;
f	float		float		4&lt;br /&gt;
d	double		float		8&lt;br /&gt;
s	char[]		string&lt;br /&gt;
p	char[]		string&lt;br /&gt;
P	void *		integer&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 H  # two byte unassigned number&lt;br /&gt;
 I  # four byte unassigned number&lt;br /&gt;
 &amp;lt;  # standard size and in little-endian byte order&lt;br /&gt;
&lt;br /&gt;
 import struct&lt;br /&gt;
 data = struct.pack(&#039;&amp;lt;IIIHH&#039;, 1, 2, 3, 4, 5)&lt;br /&gt;
 # data = &#039;\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x04\x00\x05\x00&#039;&lt;br /&gt;
 &lt;br /&gt;
 fields = struct.unpack(&#039;&amp;lt;IIIHH&#039;, data)&lt;br /&gt;
 # fields = (1L, 2L, 3L, 4, 5)&lt;br /&gt;
 # using splice: fields = struct.unpack(&#039;&amp;lt;IIIHH&#039;, data[start:start+16])&lt;br /&gt;
 &lt;br /&gt;
 f1, f2, f3, f4, f5 = fields&lt;br /&gt;
 &lt;br /&gt;
 hex(f1)  # hex a field:&lt;br /&gt;
 #  &#039;0x1L&#039;&lt;br /&gt;
&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; struct.pack(&amp;quot;&amp;lt;5sh&amp;quot;, &amp;quot;helloo&amp;quot;, 11)&lt;br /&gt;
 &#039;hello\x0b\x00&#039;&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; struct.unpack(&amp;quot;&amp;lt;5sh&amp;quot;, &#039;hello\x0b\x00&#039;)&lt;br /&gt;
 (&#039;hello&#039;, 11)&lt;br /&gt;
&lt;br /&gt;
=== pdb interactive debugger ===&lt;br /&gt;
&lt;br /&gt;
 # uncomment the following to use the interactive debugger:&lt;br /&gt;
 # import pdb; pdb.set_trace()&lt;br /&gt;
&lt;br /&gt;
=== [http://docs.python.org/library/telnetlib.html Telnet] ===&lt;br /&gt;
&lt;br /&gt;
create:&lt;br /&gt;
 class telnetlib.Telnet([host[, port[, timeout]]])&lt;br /&gt;
&lt;br /&gt;
Note: The instance is initially not connected by default; the open() method must be used to establish a connection. Alternatively, the host name and optional port number can be passed to the constructor, to, in which case the connection to the server will be established before the constructor returns.&lt;br /&gt;
&lt;br /&gt;
open if not initially done so:&lt;br /&gt;
 Telnet.open(host[, port[, timeout]])&lt;br /&gt;
&lt;br /&gt;
Functions:&lt;br /&gt;
 Telnet.read_until(expected[, timeout])   # Read until a given string, expected, is encountered or until timeout seconds have passed.&lt;br /&gt;
                                          # on timeout return whatever is in queue, possibly empty string&lt;br /&gt;
 Telnet.close()         # close connection&lt;br /&gt;
 Telnet.read_all()      # Read all data until EOF; block until connection closed.&lt;br /&gt;
 Telnet.write(buffer)   # Write a string to the socket, doubling any IAC characters. This can block if the connection is blocked.&lt;br /&gt;
 Telnet.expect(list[, timeout])  # Read until one from a list of a regular expressions matches.&lt;br /&gt;
                        # Return a tuple of three items: the index in the list of matches; the match object; and the text read to match.&lt;br /&gt;
&lt;br /&gt;
Read until end of line:&lt;br /&gt;
 line = tn.read_until(&amp;quot;\n&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import getpass&lt;br /&gt;
import sys&lt;br /&gt;
import telnetlib&lt;br /&gt;
&lt;br /&gt;
HOST = &amp;quot;localhost&amp;quot;&lt;br /&gt;
user = raw_input(&amp;quot;Enter your remote account: &amp;quot;)&lt;br /&gt;
password = getpass.getpass()&lt;br /&gt;
&lt;br /&gt;
tn = telnetlib.Telnet(HOST)&lt;br /&gt;
&lt;br /&gt;
tn.read_until(&amp;quot;login: &amp;quot;)&lt;br /&gt;
tn.write(user + &amp;quot;\n&amp;quot;)&lt;br /&gt;
if password:&lt;br /&gt;
    tn.read_until(&amp;quot;Password: &amp;quot;)&lt;br /&gt;
    tn.write(password + &amp;quot;\n&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
tn.write(&amp;quot;ls\n&amp;quot;)&lt;br /&gt;
tn.write(&amp;quot;exit\n&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
print tn.read_all()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
&lt;br /&gt;
import sys&lt;br /&gt;
import telnetlib&lt;br /&gt;
&lt;br /&gt;
HOST = &amp;quot;216.119.193.252&amp;quot;&lt;br /&gt;
USER = &amp;quot;admin&amp;quot;&lt;br /&gt;
PASS = &amp;quot;@lt12345&amp;quot;&lt;br /&gt;
&lt;br /&gt;
tn = telnetlib.Telnet(HOST)&lt;br /&gt;
&lt;br /&gt;
tn.read_until(&amp;quot;login: &amp;quot;)&lt;br /&gt;
tn.write(USER + &amp;quot;\n&amp;quot;)&lt;br /&gt;
tn.read_until(&amp;quot;Password: &amp;quot;)&lt;br /&gt;
tn.write(PASS + &amp;quot;\n&amp;quot;)&lt;br /&gt;
tn.read_until(&amp;quot;# &amp;quot;)&lt;br /&gt;
&lt;br /&gt;
tn.write(&amp;quot;terminal length 0\n&amp;quot;)&lt;br /&gt;
tn.read_until(&amp;quot;# &amp;quot;)&lt;br /&gt;
&lt;br /&gt;
tn.write(&amp;quot;show running-config\n&amp;quot;)&lt;br /&gt;
configlines = tn.read_until(&amp;quot;# &amp;quot;)&lt;br /&gt;
&lt;br /&gt;
tn.write(&amp;quot;exit\n&amp;quot;)&lt;br /&gt;
tn.read_all()&lt;br /&gt;
&lt;br /&gt;
print(configlines)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== SSH ===&lt;br /&gt;
&lt;br /&gt;
Cheap method:&lt;br /&gt;
 os.system(&#039;ssh user@server command&#039;)&lt;br /&gt;
&lt;br /&gt;
SecureShell - PythonInfo Wiki - http://wiki.python.org/moin/SecureShell&lt;br /&gt;
: There are several ways to use Secure Shell (SSH) in Python&lt;br /&gt;
* pyssh - http://pyssh.sourceforge.net/&lt;br /&gt;
* paramiko - Paramiko is a native Python implementation of SSH. - http://www.lag.net/paramiko/&lt;br /&gt;
* conch - conch is another native implementation of SSH and part of the Twisted Matrix project - http://twistedmatrix.com/projects/conch &lt;br /&gt;
* SSH wrapper - Some tools just wrap around existing ssh/sftp implementations&lt;br /&gt;
** keyphrene - http://www.keyphrene.com/products/org.keyphrene/&lt;br /&gt;
** keyphrene SSH wrapper - http://membres.lycos.fr/fredp/python/pyscp.html&lt;br /&gt;
* Fabric - http://docs.fabfile.org/en/1.4.0/index.html&lt;br /&gt;
* pexpect - Noah.org - http://www.noah.org/wiki/Pexpect&lt;br /&gt;
&lt;br /&gt;
SFTP:&lt;br /&gt;
* SFTP in Python: Really Simple SSH | The best of Zeth - http://zeth.net/post/332/&lt;br /&gt;
&lt;br /&gt;
pexpect:&lt;br /&gt;
 wget http://pexpect.sourceforge.net/pexpect-2.3.tar.gz&lt;br /&gt;
 tar xzf pexpect-2.3.tar.gz&lt;br /&gt;
 cd pexpect-2.3&lt;br /&gt;
 sudo python ./setup.py install&lt;br /&gt;
&lt;br /&gt;
=== SFTP ===&lt;br /&gt;
&lt;br /&gt;
SFTP in Python? (platform independent) - Stack Overflow - http://stackoverflow.com/questions/432385/sftp-in-python-platform-independent&lt;br /&gt;
&lt;br /&gt;
paramiko: ssh2 protocol for python - http://www.lag.net/paramiko/&lt;br /&gt;
&lt;br /&gt;
 pip install paramiko&lt;br /&gt;
&lt;br /&gt;
 mkdir -p ~/.src ; cd ~/.src&lt;br /&gt;
 wget http://www.lag.net/paramiko/download/paramiko-1.7.7.1.zip&lt;br /&gt;
 unzip paramiko-1.7.7.1.zip&lt;br /&gt;
 cd paramiko-1.7.7.1&lt;br /&gt;
 python setup.py install&lt;br /&gt;
&lt;br /&gt;
SFTP Methods:&lt;br /&gt;
* chdir&lt;br /&gt;
* chmod&lt;br /&gt;
* chown&lt;br /&gt;
* close&lt;br /&gt;
* file&lt;br /&gt;
* from_transport&lt;br /&gt;
* get&lt;br /&gt;
* get_channel&lt;br /&gt;
* getcwd&lt;br /&gt;
* listdir&lt;br /&gt;
* listdir_attr&lt;br /&gt;
* logger&lt;br /&gt;
* lstat&lt;br /&gt;
* mkdir&lt;br /&gt;
* normalize&lt;br /&gt;
* open&lt;br /&gt;
* put&lt;br /&gt;
* readlink&lt;br /&gt;
* remove&lt;br /&gt;
* rename&lt;br /&gt;
* request_number&lt;br /&gt;
* rmdir&lt;br /&gt;
* sock&lt;br /&gt;
* stat&lt;br /&gt;
* symlink&lt;br /&gt;
* truncate&lt;br /&gt;
* ultra_debug&lt;br /&gt;
* unlink&lt;br /&gt;
* utime&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import paramiko&lt;br /&gt;
&lt;br /&gt;
host = &amp;quot;THEHOST.com&amp;quot;                    #hard-coded&lt;br /&gt;
port = 22&lt;br /&gt;
transport = paramiko.Transport((host, port))&lt;br /&gt;
&lt;br /&gt;
password = &amp;quot;THEPASSWORD&amp;quot;                #hard-coded&lt;br /&gt;
username = &amp;quot;THEUSERNAME&amp;quot;                #hard-coded&lt;br /&gt;
transport.connect(username = username, password = password)&lt;br /&gt;
&lt;br /&gt;
sftp = paramiko.SFTPClient.from_transport(transport)&lt;br /&gt;
&lt;br /&gt;
import sys&lt;br /&gt;
path = &#039;./THETARGETDIRECTORY/&#039; + sys.argv[1]    #hard-coded&lt;br /&gt;
localpath = sys.argv[1]&lt;br /&gt;
sftp.put(localpath, path)&lt;br /&gt;
&lt;br /&gt;
sftp.close()&lt;br /&gt;
transport.close()&lt;br /&gt;
print &#039;Upload done.&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
VMware Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
&lt;br /&gt;
import paramiko&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
host = &amp;quot;sftp2.engx.vmware.com&amp;quot;&lt;br /&gt;
port = 443&lt;br /&gt;
transport = paramiko.Transport((host, port))&lt;br /&gt;
&lt;br /&gt;
username = &amp;quot;xxxx&amp;quot;&lt;br /&gt;
password = &amp;quot;xxx&amp;quot;&lt;br /&gt;
transport.connect(username = username, password = password)&lt;br /&gt;
&lt;br /&gt;
sftp = paramiko.SFTPClient.from_transport(transport)&lt;br /&gt;
&lt;br /&gt;
print dir(sftp)&lt;br /&gt;
&lt;br /&gt;
print sftp.chdir(&amp;quot;build-uploader&amp;quot;)&lt;br /&gt;
print sftp.listdir()&lt;br /&gt;
&lt;br /&gt;
sftp.close()&lt;br /&gt;
transport.close()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== paramiko ===&lt;br /&gt;
&lt;br /&gt;
See [[Python/paramiko]]&lt;br /&gt;
&lt;br /&gt;
=== [http://docs.python.org/library/getpass.html Get Password] ===&lt;br /&gt;
&lt;br /&gt;
Prompt for password:&lt;br /&gt;
 getpass.getpass(prompt=&#039;Password: &#039;)&lt;br /&gt;
&lt;br /&gt;
 import getpass&lt;br /&gt;
 user = raw_input(&amp;quot;Enter your remote account: &amp;quot;)&lt;br /&gt;
 password = getpass.getpass()&lt;br /&gt;
&lt;br /&gt;
=== [http://docs.python.org/library/configparser.html ini files] ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ini_filename = &#039;my.ini&#039;&lt;br /&gt;
&lt;br /&gt;
import ConfigParser&lt;br /&gt;
parser = ConfigParser.SafeConfigParser()&lt;br /&gt;
parser.read(ini_filename)&lt;br /&gt;
&lt;br /&gt;
sections = parser.sections() # get sections&lt;br /&gt;
for section in sections:&lt;br /&gt;
  print &amp;quot;[&amp;quot; + section + &amp;quot;]&amp;quot;&lt;br /&gt;
  for name, value in parser.items(section):&lt;br /&gt;
    print name + &amp;quot; = &amp;quot; + value&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if parser.has_option(section, option):&lt;br /&gt;
  print( parser.get(section, option) )&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To have the option names not convert to lower case:&lt;br /&gt;
 parser.optionxform = str&lt;br /&gt;
&lt;br /&gt;
Ignore section: [http://stackoverflow.com/questions/2885190/using-pythons-configparser-to-read-a-file-without-section-name]&lt;br /&gt;
 ini_str = &#039;[root]\n&#039; + open(ini_path, &#039;r&#039;).read()&lt;br /&gt;
 ini_fp = StringIO.StringIO(ini_str)&lt;br /&gt;
 config = ConfigParser.RawConfigParser()&lt;br /&gt;
 config.readfp(ini_fp)&lt;br /&gt;
&lt;br /&gt;
Get option:&lt;br /&gt;
 config.has_option(&#039;root&#039;, &#039;some_key&#039;)&lt;br /&gt;
 config.get(&#039;root&#039;, &#039;some_key&#039;)&lt;br /&gt;
&lt;br /&gt;
 config.items(&#039;root&#039;)  # list of Key Value tuples&lt;br /&gt;
&lt;br /&gt;
=== optparse - Option Parser ===&lt;br /&gt;
&lt;br /&gt;
[http://docs.python.org/library/optparse.html - Option Parser&lt;br /&gt;
&lt;br /&gt;
Note: Deprecated since version 2.7: The optparse module is deprecated and will not be developed further; development will continue with the argparse module.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import optparse&lt;br /&gt;
parser = optparse.OptionParser()&lt;br /&gt;
&lt;br /&gt;
parser.add_option(&#039;--name&#039;, default=None)&lt;br /&gt;
&lt;br /&gt;
parser.add_option(&lt;br /&gt;
    &#039;-l&#039;, &#039;--loglevel&#039;,&lt;br /&gt;
    help=&#039;Log Level (default: info)&#039;,&lt;br /&gt;
    default=&amp;quot;info&amp;quot;, action=&#039;store&#039;, type=&#039;string&#039;)&lt;br /&gt;
&lt;br /&gt;
(options, args) = parser.parse_args()&lt;br /&gt;
&lt;br /&gt;
# if no parameters passed show help&lt;br /&gt;
if len(sys.argv) == 1:&lt;br /&gt;
    parser.print_help()&lt;br /&gt;
    sys.exit(1)&lt;br /&gt;
&lt;br /&gt;
# if a stand alone parameter passed, override option&lt;br /&gt;
if args:&lt;br /&gt;
  options.target = args[0]&lt;br /&gt;
&lt;br /&gt;
# show option:&lt;br /&gt;
print(options.loglevel)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: Order is important when listing add_options!&lt;br /&gt;
&lt;br /&gt;
Pretty Description:&lt;br /&gt;
 parser = optparse.OptionParser(description=&amp;quot;Purpose: to do something&amp;quot;)&lt;br /&gt;
 # or&lt;br /&gt;
 parser.description = &amp;quot;Purpose: to do something&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Parse arguments:&lt;br /&gt;
 (options, args) = parser.parse_args()&lt;br /&gt;
Note: If you like, you can pass a custom argument list to parse_args(), but that’s rarely necessary: by default it uses sys.argv[1:].&lt;br /&gt;
&lt;br /&gt;
Change Usage Message:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
usage = &amp;quot;%prog [options]&amp;quot;  # default message&lt;br /&gt;
# Usage: &amp;lt;prog&amp;gt; [options]&amp;quot;  # where &amp;lt;prog&amp;gt; is replaced with the script name&lt;br /&gt;
&lt;br /&gt;
parser = OptionParser(usage=usage)&lt;br /&gt;
# or&lt;br /&gt;
parser.usage = usage  # default message&lt;br /&gt;
# or&lt;br /&gt;
parser.set_usage(usage)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Remove option: (does not remove default value from &#039;options&#039; variable!!! - stupid!)&lt;br /&gt;
 parser.remove_option(&#039;--loglevel&#039;)&lt;br /&gt;
&lt;br /&gt;
Modify an option: (changes are saved to parser automatically, unless in an option group)&lt;br /&gt;
 option = parser.get_option(&#039;--loglevel&#039;)&lt;br /&gt;
 option.help = &#039;something else&#039;&lt;br /&gt;
 option.default = &#039;debug&#039;&lt;br /&gt;
&lt;br /&gt;
 # or&lt;br /&gt;
 parser.remove_option(&amp;quot;--loglevel&amp;quot;)&lt;br /&gt;
 parser.add_option(&amp;quot;--loglevel&amp;quot;, help=&amp;quot;something else&amp;quot;, default=&amp;quot;info&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Modify an option in an option group:&lt;br /&gt;
 opt_group = parser.get_option_group(&amp;quot;--loglevel&amp;quot;)&lt;br /&gt;
 opt_group.remove_option(&amp;quot;--loglevel&amp;quot;)&lt;br /&gt;
 opt_group.add_option(&amp;quot;--loglevel&amp;quot;, help=&amp;quot;something else&amp;quot;, default=&amp;quot;info&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Types: &amp;quot;string&amp;quot;, &amp;quot;int&amp;quot;, &amp;quot;long&amp;quot;, &amp;quot;choice&amp;quot;, &amp;quot;float&amp;quot; and &amp;quot;complex&amp;quot; [http://docs.python.org/library/optparse.html#optparse-standard-option-types]&lt;br /&gt;
Defaults:&lt;br /&gt;
* Default actions is &#039;store&#039;.&lt;br /&gt;
* Default type is &#039;string&#039;.&lt;br /&gt;
* Default dest is the long name of the parameter (or short name if no long name provided)&lt;br /&gt;
* Default value is None&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from optparse import OptionParser&lt;br /&gt;
[...]&lt;br /&gt;
parser = OptionParser()&lt;br /&gt;
&lt;br /&gt;
# string&lt;br /&gt;
parser.add_option(&amp;quot;-f&amp;quot;, &amp;quot;--file&amp;quot;, dest=&amp;quot;filename&amp;quot;,&lt;br /&gt;
                  help=&amp;quot;write report to FILE&amp;quot;, metavar=&amp;quot;FILE&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
# boolean - action is what to do when flag found&lt;br /&gt;
parser.add_option(&amp;quot;-q&amp;quot;, &amp;quot;--quiet&amp;quot;,&lt;br /&gt;
                  action=&amp;quot;store_true&amp;quot;, dest=&amp;quot;verbose&amp;quot;, default=False,&lt;br /&gt;
                  help=&amp;quot;don&#039;t print status messages to stdout&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
# integer&lt;br /&gt;
parser.add_option(&lt;br /&gt;
    &amp;quot;-m&amp;quot;, &amp;quot;--minutes&amp;quot;,&lt;br /&gt;
    help=&amp;quot;Minutes (default: 60)&amp;quot;,&lt;br /&gt;
    default=60, type=&#039;int&#039;)&lt;br /&gt;
&lt;br /&gt;
(options, args) = parser.parse_args()&lt;br /&gt;
&lt;br /&gt;
print &amp;quot;Filename: &amp;quot; + options.filename&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
fake handling of required option:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if not option.filename:&lt;br /&gt;
    parser.print_help()&lt;br /&gt;
    parser.error(&amp;quot;filename is required&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
change default usage:&lt;br /&gt;
  parser = OptionParser(usage=&amp;quot;Usage: %prog [args] arg1 arg2&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Really ugly way to print help usage  :-(&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def Usage():&lt;br /&gt;
    pname = sys.argv[0]&lt;br /&gt;
    cmd=&#039;%s -h&#039; % (pname)&lt;br /&gt;
    os.system(cmd)&lt;br /&gt;
&lt;br /&gt;
if (len(sys.argv) &amp;lt; 2):&lt;br /&gt;
    Usage()&lt;br /&gt;
    sys.exit(1)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Groups:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#  OptionGroup(parser, title, description=None)&lt;br /&gt;
group = OptionGroup(parser, &amp;quot;Dangerous Options&amp;quot;,&lt;br /&gt;
                    &amp;quot;Caution: use these options at your own risk.  &amp;quot;&lt;br /&gt;
                    &amp;quot;It is believed that some of them bite.&amp;quot;)&lt;br /&gt;
group.add_option(&amp;quot;-g&amp;quot;, action=&amp;quot;store_true&amp;quot;, help=&amp;quot;Group option.&amp;quot;)&lt;br /&gt;
parser.add_option_group(group)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hide an option:&lt;br /&gt;
* Option.help&lt;br /&gt;
: &amp;quot;Help text to print for this option when listing all available options after the user supplies a help option (such as --help). If no help text is supplied, the option will be listed without help text. To hide this option, use the special value optparse.SUPPRESS_HELP.&amp;quot;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
parser.add_option(&amp;quot;--secret&amp;quot;, help=SUPPRESS_HELP)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Issues with Option Parser:&lt;br /&gt;
* No handling for positional arguments&lt;br /&gt;
* No adding help for positional arguments&lt;br /&gt;
* No handling for required field&lt;br /&gt;
&lt;br /&gt;
=== argparse ===&lt;br /&gt;
&lt;br /&gt;
argparse - http://docs.python.org/library/argparse.html&lt;br /&gt;
&lt;br /&gt;
argparse — Parser for command-line options, arguments and sub-commands&lt;br /&gt;
&lt;br /&gt;
NOTE: MUCH MORE POWERFUL THAN OPTION PARSER!&lt;br /&gt;
&lt;br /&gt;
Note: New in version 2.7.&lt;br /&gt;
&lt;br /&gt;
Installation on &amp;lt;= 2.6&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Install argparse: - http://code.google.com/p/argparse/&lt;br /&gt;
# REQUIRES SETUPTOOLS&lt;br /&gt;
mkdir -p ~/.src ; cd ~/.src&lt;br /&gt;
wget http://argparse.googlecode.com/files/argparse-1.2.1.tar.gz&lt;br /&gt;
tar -zvxf argparse-1.2.1.tar.gz&lt;br /&gt;
cd argparse-1.2.1&lt;br /&gt;
sudo python setup.py install&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The argparse module makes it easy to write user-friendly command-line interfaces. The program defines what arguments it requires, and argparse will figure out how to parse those out of sys.argv. The argparse module also automatically generates help and usage messages and issues errors when users give the program invalid arguments.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import argparse&lt;br /&gt;
&lt;br /&gt;
parser = argparse.ArgumentParser(description=&#039;Process some integers.&#039;)&lt;br /&gt;
parser.add_argument(&#039;integers&#039;, metavar=&#039;N&#039;, type=int, nargs=&#039;+&#039;,&lt;br /&gt;
                   help=&#039;an integer for the accumulator&#039;)&lt;br /&gt;
parser.add_argument(&#039;--sum&#039;, dest=&#039;accumulate&#039;, action=&#039;store_const&#039;,&lt;br /&gt;
                   const=sum, default=max,&lt;br /&gt;
                   help=&#039;sum the integers (default: find the max)&#039;)&lt;br /&gt;
&lt;br /&gt;
args = parser.parse_args()&lt;br /&gt;
print args.accumulate(args.integers)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import argparse&lt;br /&gt;
&lt;br /&gt;
argparser = demoproject.util.argparse.ArgumentParser(&lt;br /&gt;
    usage=&#039;Kick off demoproject benchmarks.&#039;)&lt;br /&gt;
argparser.add_argument(&lt;br /&gt;
    &#039;--card&#039;,&lt;br /&gt;
    help=&#039;What cards to run on.  Depends on Jenkins NODE_LABEL environment&#039;&lt;br /&gt;
        &#039;variable for correct mappings.&#039;)&lt;br /&gt;
argparser.add_argument(&lt;br /&gt;
    &#039;--suite&#039;, metavar=&#039;SUITE&#039;,&lt;br /&gt;
    help=&#039;Specify the appropriate benchmark suite as defined in &#039;&lt;br /&gt;
        &#039;the benchmark ini file.  Defaults to standard_perf&#039;,&lt;br /&gt;
    default=&#039;standard_perf&#039;)&lt;br /&gt;
args = argparser.parse_args()&lt;br /&gt;
&lt;br /&gt;
print args.card&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Remove an argument: [http://stackoverflow.com/questions/32807319/disable-remove-argument-in-argparse]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def remove_options(parser, options):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot; remove_options(parser, [&#039;--some-option&#039;, &#039;--some-option2&#039;]) &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    for option in options:&lt;br /&gt;
        for action in parser._actions:&lt;br /&gt;
            if vars(action)[&#039;option_strings&#039;][0] == option:&lt;br /&gt;
                parser._handle_conflict_resolve(None,[(option,action)])&lt;br /&gt;
                break&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [http://docs.python.org/library/commands.html commands] ===&lt;br /&gt;
&lt;br /&gt;
35.16. commands — Utilities for running commands — Python v2.7.1 documentation - http://docs.python.org/library/commands.html&lt;br /&gt;
&lt;br /&gt;
Note: Deprecated since version 2.6: The commands module has been removed in Python 3.0. Use the subprocess module instead.&lt;br /&gt;
&lt;br /&gt;
The commands module contains wrapper functions for os.popen() which take a system command as a string and return any output generated by the command and, optionally, the exit status.&lt;br /&gt;
&lt;br /&gt;
Get status and output:&lt;br /&gt;
 status, output = commands.getstatusoutput(cmd)&lt;br /&gt;
&lt;br /&gt;
Get output ignoring status:&lt;br /&gt;
 output = commands.getoutput(cmd)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
NOTE: DO NOT USE getstatus() AS IT DOES NOT DO WHAT YOU THINK IT DOES!&lt;br /&gt;
 status = commands.getstatus(file)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import commands&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; commands.getstatusoutput(&#039;ls /bin/ls&#039;)&lt;br /&gt;
(0, &#039;/bin/ls&#039;)&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; commands.getstatusoutput(&#039;cat /bin/junk&#039;)&lt;br /&gt;
(256, &#039;cat: /bin/junk: No such file or directory&#039;)&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; commands.getstatusoutput(&#039;/bin/junk&#039;)&lt;br /&gt;
(256, &#039;sh: /bin/junk: not found&#039;)&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; commands.getoutput(&#039;ls /bin/ls&#039;)&lt;br /&gt;
&#039;/bin/ls&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; commands.getstatus(&#039;/bin/ls&#039;)&lt;br /&gt;
&#039;-rwxr-xr-x  1 root        13352 Oct 14  1994 /bin/ls&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [http://docs.python.org/library/_winreg.html Windows Registry] ===&lt;br /&gt;
&lt;br /&gt;
Note: The _winreg module has been renamed to winreg in Python 3.0.&lt;br /&gt;
&lt;br /&gt;
* 32.3. winreg – Windows registry access — Python v3.2 documentation - http://docs.python.org/py3k/library/winreg.html&lt;br /&gt;
* 34.3. _winreg – Windows registry access — Python v2.7.1 documentation - http://docs.python.org/library/_winreg.html&lt;br /&gt;
&lt;br /&gt;
Read from registry:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from _winreg import *&lt;br /&gt;
key = OpenKey(HKEY_LOCAL_MACHINE, r&#039;Software\Microsoft\Outlook Express&#039;, 0, KEY_ALL_ACCESS)&lt;br /&gt;
QueryValueEx(key, &amp;quot;InstallRoot&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Write to registry:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
keyVal = r&#039;Software\Microsoft\Internet Explorer\Main&#039;&lt;br /&gt;
try:&lt;br /&gt;
    key = OpenKey(HKEY_CURRENT_USER, keyVal, 0, KEY_ALL_ACCESS)&lt;br /&gt;
except:&lt;br /&gt;
    key = CreateKey(HKEY_CURRENT_USER, keyVal)&lt;br /&gt;
SetValueEx(key, &amp;quot;Start Page&amp;quot;, 0, REG_SZ, &amp;quot;http://www.blog.pythonlibrary.org/&amp;quot;)&lt;br /&gt;
CloseKey(key)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Enumerate registry keys:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from _winreg import EnumKey, HKEY_USERS&lt;br /&gt;
 &lt;br /&gt;
try:&lt;br /&gt;
    i = 0&lt;br /&gt;
    while True:&lt;br /&gt;
        subkey = EnumKey(HKEY_USERS, i)&lt;br /&gt;
        print subkey&lt;br /&gt;
        i += 1&lt;br /&gt;
except WindowsError:&lt;br /&gt;
    # WindowsError: [Errno 259] No more data is available    &lt;br /&gt;
    pass&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Another enumeration example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# File: winreg-example-1.py&lt;br /&gt;
&lt;br /&gt;
import _winreg&lt;br /&gt;
&lt;br /&gt;
explorer = _winreg.OpenKey(&lt;br /&gt;
    _winreg.HKEY_CURRENT_USER,&lt;br /&gt;
    &amp;quot;Software\\Microsoft\\Windows\\CurrentVersion\\Explorer&amp;quot;&lt;br /&gt;
    )&lt;br /&gt;
&lt;br /&gt;
# list values owned by this registry key&lt;br /&gt;
try:&lt;br /&gt;
    i = 0&lt;br /&gt;
    while 1:&lt;br /&gt;
        name, value, type = _winreg.EnumValue(explorer, i)&lt;br /&gt;
        print repr(name),&lt;br /&gt;
        i += 1&lt;br /&gt;
except WindowsError:&lt;br /&gt;
    print&lt;br /&gt;
&lt;br /&gt;
value, type = _winreg.QueryValueEx(explorer, &amp;quot;Logon User Name&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
print&lt;br /&gt;
print &amp;quot;user is&amp;quot;, repr(value)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Enable Remote Desktop Example: (by Kenneth)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from _winreg import *&lt;br /&gt;
key = OpenKey(HKEY_LOCAL_MACHINE, r&#039;SYSTEM\CurrentControlSet\Control\Terminal Server&#039;, 0, KEY_ALL_ACCESS)&lt;br /&gt;
SetValueEx(key, &amp;quot;fDenyTSConnections&amp;quot;, 0, REG_DWORD, 0)&lt;br /&gt;
ValueTypeTuple = QueryValueEx(key, &amp;quot;fDenyTSConnections&amp;quot;)   # (0, 4)&lt;br /&gt;
print(&amp;quot;Please reboot the system to complete the changes&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* Python’s _winreg: Editing the Windows Registry « The Mouse Vs. The Python - http://www.blog.pythonlibrary.org/2010/03/20/pythons-_winreg-editing-the-windows-registry/&lt;br /&gt;
&lt;br /&gt;
=== JSON ===&lt;br /&gt;
&lt;br /&gt;
JSON - http://docs.python.org/library/json.html&lt;br /&gt;
&lt;br /&gt;
ENCODING TO JSON STRING (type str)&lt;br /&gt;
&lt;br /&gt;
 import json&lt;br /&gt;
 json.dumps([&#039;foo&#039;, {&#039;bar&#039;: (&#039;baz&#039;, None, 1.0, 2)}])&lt;br /&gt;
 # &#039;[&amp;quot;foo&amp;quot;, {&amp;quot;bar&amp;quot;: [&amp;quot;baz&amp;quot;, null, 1.0, 2]}]&#039;&lt;br /&gt;
&lt;br /&gt;
compact encoding:&lt;br /&gt;
 import json&lt;br /&gt;
 json.dumps([1,2,3,{&#039;4&#039;: 5, &#039;6&#039;: 7}], separators=(&#039;,&#039;,&#039;:&#039;))&lt;br /&gt;
 # &#039;[1,2,3,{&amp;quot;4&amp;quot;:5,&amp;quot;6&amp;quot;:7}]&#039;&lt;br /&gt;
&lt;br /&gt;
Pretty printing:&lt;br /&gt;
 import json&lt;br /&gt;
 print json.dumps({&#039;4&#039;: 5, &#039;6&#039;: 7}, sort_keys=True, indent=4)&lt;br /&gt;
 # {&lt;br /&gt;
 #     &amp;quot;4&amp;quot;: 5,&lt;br /&gt;
 #     &amp;quot;6&amp;quot;: 7&lt;br /&gt;
 # }&lt;br /&gt;
&lt;br /&gt;
DECODING JSON STRING TO PYTHON LIST OR DICTIONARY OBJECT&lt;br /&gt;
&lt;br /&gt;
 import json&lt;br /&gt;
 json.loads(&#039;[&amp;quot;foo&amp;quot;, {&amp;quot;bar&amp;quot;:[&amp;quot;baz&amp;quot;, null, 1.0, 2]}]&#039;)&lt;br /&gt;
 # [u&#039;foo&#039;, {u&#039;bar&#039;: [u&#039;baz&#039;, None, 1.0, 2]}]&lt;br /&gt;
&lt;br /&gt;
Load from file:&lt;br /&gt;
 f = open(filename)&lt;br /&gt;
 j = json.load(f)&lt;br /&gt;
 print j[&amp;quot;kind&amp;quot;]  # &amp;quot;dual-controller-adapter&amp;quot;&lt;br /&gt;
 #{&lt;br /&gt;
 #   &amp;quot;kind&amp;quot;: &amp;quot;dual-controller-adapter&amp;quot;,&lt;br /&gt;
 #}&lt;br /&gt;
&lt;br /&gt;
From Command Line:&lt;br /&gt;
 echo &#039;{&amp;quot;foo&amp;quot;: &amp;quot;lorem&amp;quot;, &amp;quot;bar&amp;quot;: &amp;quot;ipsum&amp;quot;}&#039; | python -mjson.tool&lt;br /&gt;
&lt;br /&gt;
 # get value&lt;br /&gt;
 echo &#039;{&amp;quot;test&amp;quot;:1,&amp;quot;test2&amp;quot;:2}&#039; | python -c &#039;import sys,json;data=json.loads(sys.stdin.read()); print data[&amp;quot;test&amp;quot;]&#039;&lt;br /&gt;
&lt;br /&gt;
 # read large file&lt;br /&gt;
 python -c &amp;quot;import json;f=open(&#039;file.json&#039;);data=json.load(f);print json.dumps(data,indent=2)&amp;quot;&lt;br /&gt;
 python -c &amp;quot;import json;print json.dumps(json.load(open(&#039;file.json&#039;)),indent=2)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Load from web:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import httplib&lt;br /&gt;
import json&lt;br /&gt;
&lt;br /&gt;
def get_http_json(server, path):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot; This performs an HTTP GET against a server and path and returns the&lt;br /&gt;
        resulting page data.&lt;br /&gt;
&lt;br /&gt;
        server The server we&#039;re hitting, e.g. demo.com&lt;br /&gt;
        path   The path we&#039;re hitting, e.g. api/part/MA12345/&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    connection = httplib.HTTPConnection(server)&lt;br /&gt;
    try:&lt;br /&gt;
        url = &#039;http://%s/%s&#039; % (server, path)&lt;br /&gt;
        print &#039;Querying url %s&#039; % url&lt;br /&gt;
        connection.request(&#039;GET&#039;, url)&lt;br /&gt;
        response = connection.getresponse()&lt;br /&gt;
        if response.status == httplib.OK:&lt;br /&gt;
            return json.loads(response.read())&lt;br /&gt;
        else:&lt;br /&gt;
            print &#039;Unable to get %s. %s %s&#039; % (url, response.reason,&lt;br /&gt;
                    response.status)&lt;br /&gt;
            return None&lt;br /&gt;
    finally:&lt;br /&gt;
        connection.close()&lt;br /&gt;
&lt;br /&gt;
j = get_http_json(server, path)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pretty printing from the command line:&lt;br /&gt;
 echo &#039;{&amp;quot;json&amp;quot;:&amp;quot;obj&amp;quot;}&#039; | python -mjson.tool&lt;br /&gt;
 #{&lt;br /&gt;
 #   &amp;quot;json&amp;quot;: &amp;quot;obj&amp;quot;&lt;br /&gt;
 #}&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* 18.2. json — JSON encoder and decoder — Python v2.7.1 documentation - http://docs.python.org/library/json.html&lt;br /&gt;
&lt;br /&gt;
=== Sockets ===&lt;br /&gt;
&lt;br /&gt;
See [[Python/Sockets]]&lt;br /&gt;
&lt;br /&gt;
=== [http://docs.python.org/library/base64.html base64] ===&lt;br /&gt;
&lt;br /&gt;
 import base64&lt;br /&gt;
&lt;br /&gt;
Encode:&lt;br /&gt;
 encoded = base64.b64encode(&#039;data to be encoded&#039;)&lt;br /&gt;
&lt;br /&gt;
Decode:&lt;br /&gt;
 base64.b64decode(encoded)&lt;br /&gt;
&lt;br /&gt;
=== daemonize ===&lt;br /&gt;
&lt;br /&gt;
Creating a daemon the Python way « Python recipes « ActiveState Code - http://code.activestate.com/recipes/278731-creating-a-daemon-the-python-way/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import os&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
try:&lt;br /&gt;
    pid = os.fork()&lt;br /&gt;
except OSError, e:&lt;br /&gt;
    raise Exception, &amp;quot;%s [%d]&amp;quot; % (e.strerror, e.errno)&lt;br /&gt;
&lt;br /&gt;
if (pid != 0):  # parent&lt;br /&gt;
    os._exit(0)&lt;br /&gt;
&lt;br /&gt;
# create new process session&lt;br /&gt;
os.setsid()&lt;br /&gt;
&lt;br /&gt;
# redirect stdin, stdout, stderr&lt;br /&gt;
os.open(&#039;/dev/null&#039;, os.O_RDWR)&lt;br /&gt;
os.dup2(0, 1)&lt;br /&gt;
os.dup2(0, 2)&lt;br /&gt;
&lt;br /&gt;
#... tasks ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
My Solution:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import os&lt;br /&gt;
import sys&lt;br /&gt;
import signal&lt;br /&gt;
import syslog&lt;br /&gt;
&lt;br /&gt;
HUP = False&lt;br /&gt;
&lt;br /&gt;
def log(msg):&lt;br /&gt;
    syslog.syslog(str(msg))&lt;br /&gt;
syslog.openlog(&#039;[WATER]&#039;)&lt;br /&gt;
&lt;br /&gt;
def kill_signal_handler(signal, frame):&lt;br /&gt;
    log(&amp;quot;Being killed off: {0} {1}&amp;quot;.format(signal, frame))&lt;br /&gt;
    log(&amp;quot;Shutting Down!&amp;quot;)&lt;br /&gt;
    sys.exit(0)&lt;br /&gt;
signal.signal(signal.SIGTERM, kill_signal_handler)&lt;br /&gt;
signal.signal(signal.SIGALRM, kill_signal_handler)&lt;br /&gt;
&lt;br /&gt;
def hup_signal_handler(signal, frame):&lt;br /&gt;
    global HUP&lt;br /&gt;
    log(&amp;quot;Signal reload received: {0} {1}&amp;quot;.format(signal, frame))&lt;br /&gt;
    HUP=True&lt;br /&gt;
signal.signal(signal.SIGHUP, hup_signal_handler)&lt;br /&gt;
&lt;br /&gt;
def main_loop():&lt;br /&gt;
    global HUP&lt;br /&gt;
&lt;br /&gt;
    while True:&lt;br /&gt;
        #  ... handle HUP=True ...&lt;br /&gt;
&lt;br /&gt;
        # ... main code ...&lt;br /&gt;
&lt;br /&gt;
        # wait 60 seconds before we start the next loop&lt;br /&gt;
        time.sleep(60)  # signals will interrupt this&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
    log(&amp;quot;Starting Daemon...&amp;quot;)&lt;br /&gt;
    child_id = os.fork()&lt;br /&gt;
    if child_id:&lt;br /&gt;
        log(&amp;quot;Daemonized!&amp;quot;)&lt;br /&gt;
        sys.exit(0)&lt;br /&gt;
    os.setsid()&lt;br /&gt;
    # redirect stdin, stdout, stderr&lt;br /&gt;
    os.open(&#039;/dev/null&#039;, os.O_RDWR)&lt;br /&gt;
    os.dup2(0, 1)&lt;br /&gt;
    os.dup2(0, 2)&lt;br /&gt;
&lt;br /&gt;
    # write pid&lt;br /&gt;
    with open(&amp;quot;water.pid&amp;quot;, &amp;quot;w&amp;quot;) as f:&lt;br /&gt;
        f.write(str(os.getpid()))&lt;br /&gt;
&lt;br /&gt;
    while True:&lt;br /&gt;
        try:&lt;br /&gt;
            main_loop()&lt;br /&gt;
        except Exception as e:&lt;br /&gt;
            log(&amp;quot;Critical Failure Caught: %s&amp;quot; % str(e))&lt;br /&gt;
            log(&amp;quot;Critical Failure - Restarting!&amp;quot;)&lt;br /&gt;
            time.sleep(30)&lt;br /&gt;
            #raise e&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 ln -s /opt/pyton27/bin/python pyton-water&lt;br /&gt;
 ./python-water water.py&lt;br /&gt;
 killall python-water&lt;br /&gt;
&lt;br /&gt;
==== fork ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import os&lt;br /&gt;
import sys&lt;br /&gt;
import time&lt;br /&gt;
&lt;br /&gt;
child_id = os.fork()&lt;br /&gt;
if child_id:&lt;br /&gt;
  print &amp;quot;parent exiting&amp;quot;&lt;br /&gt;
  sys.exit(0)&lt;br /&gt;
&lt;br /&gt;
while True:&lt;br /&gt;
    time.sleep(3)&lt;br /&gt;
    print &amp;quot;child&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For windows, to hide the console, see [[#Hide Console]]&lt;br /&gt;
&lt;br /&gt;
=== csv ===&lt;br /&gt;
&lt;br /&gt;
13.1. csv — CSV File Reading and Writing — Python v2.7.2 documentation - http://docs.python.org/library/csv.html&lt;br /&gt;
&lt;br /&gt;
Read:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import csv&lt;br /&gt;
spamReader = csv.reader(open(&#039;eggs.csv&#039;, &#039;rb&#039;), delimiter=&#039; &#039;, quotechar=&#039;|&#039;)&lt;br /&gt;
for row in spamReader:&lt;br /&gt;
  print &#039;, &#039;.join(row)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Write:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import csv&lt;br /&gt;
spamWriter = csv.writer(open(&#039;eggs.csv&#039;, &#039;wb&#039;), delimiter=&#039; &#039;,&lt;br /&gt;
    quotechar=&#039;|&#039;, quoting=csv.QUOTE_MINIMAL)&lt;br /&gt;
spamWriter.writerow([&#039;Spam&#039;] * 5 + [&#039;Baked Beans&#039;])&lt;br /&gt;
spamWriter.writerow([&#039;Spam&#039;, &#039;Lovely Spam&#039;, &#039;Wonderful Spam&#039;])&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== SQLite ===&lt;br /&gt;
&lt;br /&gt;
11.13. sqlite3 — DB-API 2.0 interface for SQLite databases — Python v2.7.2 documentation - http://docs.python.org/library/sqlite3.html&lt;br /&gt;
&lt;br /&gt;
sqlite3 - New in version 2.5.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import sqlite3&lt;br /&gt;
&lt;br /&gt;
conn = sqlite3.connect(&#039;/tmp/example&#039;)&lt;br /&gt;
&lt;br /&gt;
c = conn.cursor()&lt;br /&gt;
&lt;br /&gt;
# Create table&lt;br /&gt;
c.execute(&#039;&#039;&#039;create table stocks&lt;br /&gt;
(date text, trans text, symbol text,&lt;br /&gt;
 qty real, price real)&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
# Insert a row of data&lt;br /&gt;
c.execute(&amp;quot;&amp;quot;&amp;quot;insert into stocks&lt;br /&gt;
          values (&#039;2006-01-05&#039;,&#039;BUY&#039;,&#039;RHAT&#039;,100,35.14)&amp;quot;&amp;quot;&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
# Show affected row count&lt;br /&gt;
print c.rowcount&lt;br /&gt;
&lt;br /&gt;
# Save (commit) the changes&lt;br /&gt;
conn.commit()&lt;br /&gt;
&lt;br /&gt;
# We can also close the cursor if we are done with it&lt;br /&gt;
c.close()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
parameter substitution:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Never do this -- insecure!&lt;br /&gt;
symbol = &#039;IBM&#039;&lt;br /&gt;
c.execute(&amp;quot;... where symbol = &#039;%s&#039;&amp;quot; % symbol)&lt;br /&gt;
&lt;br /&gt;
# Do this instead&lt;br /&gt;
t = (symbol,)&lt;br /&gt;
c.execute(&#039;select * from stocks where symbol=?&#039;, t)&lt;br /&gt;
c.execute(&#039;select * from stocks where symbol=?&#039;, (symbol,))&lt;br /&gt;
&lt;br /&gt;
# Larger example&lt;br /&gt;
for t in [(&#039;2006-03-28&#039;, &#039;BUY&#039;, &#039;IBM&#039;, 1000, 45.00),&lt;br /&gt;
          (&#039;2006-04-05&#039;, &#039;BUY&#039;, &#039;MSOFT&#039;, 1000, 72.00),&lt;br /&gt;
          (&#039;2006-04-06&#039;, &#039;SELL&#039;, &#039;IBM&#039;, 500, 53.00),&lt;br /&gt;
         ]:&lt;br /&gt;
    c.execute(&#039;insert into stocks values (?,?,?,?,?)&#039;, t)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
select results:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
c = conn.cursor()&lt;br /&gt;
c.execute(&#039;select * from stocks order by price&#039;)&lt;br /&gt;
&lt;br /&gt;
for row in c:&lt;br /&gt;
  print row  # row is a tuple&lt;br /&gt;
&lt;br /&gt;
# OR (but not both)&lt;br /&gt;
&lt;br /&gt;
rows = c.fetchall()    # rows is list of tuples&lt;br /&gt;
print len(rows)&lt;br /&gt;
for row in rows:&lt;br /&gt;
  print row&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Show which version of sqlite3: [http://zetcode.com/db/sqlitepythontutorial/]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/python&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&lt;br /&gt;
import sqlite3 as lite&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
con = None&lt;br /&gt;
&lt;br /&gt;
try:&lt;br /&gt;
    con = lite.connect(&#039;test.db&#039;)&lt;br /&gt;
&lt;br /&gt;
    cur = con.cursor()&lt;br /&gt;
    cur.execute(&#039;SELECT SQLITE_VERSION()&#039;)&lt;br /&gt;
&lt;br /&gt;
    data = cur.fetchone()&lt;br /&gt;
&lt;br /&gt;
    print &amp;quot;SQLite version: %s&amp;quot; % data&lt;br /&gt;
&lt;br /&gt;
except lite.Error, e:&lt;br /&gt;
&lt;br /&gt;
    print &amp;quot;Error %s:&amp;quot; % e.args[0]&lt;br /&gt;
    sys.exit(1)&lt;br /&gt;
&lt;br /&gt;
finally:&lt;br /&gt;
&lt;br /&gt;
    if con:&lt;br /&gt;
        con.close()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Or simply: [http://stackoverflow.com/questions/1545479/force-python-to-forego-native-sqlite3-and-use-the-installed-latest-sqlite3-ver]&lt;br /&gt;
 # echo -e &amp;quot;import sqlite3\nprint sqlite3.sqlite_version_info&amp;quot; | python&lt;br /&gt;
 (3, 3, 6)&lt;br /&gt;
&lt;br /&gt;
=== MySQL Database ===&lt;br /&gt;
&lt;br /&gt;
Ubuntu packages:&lt;br /&gt;
* python-mysqldb - Python interface to MySQL&lt;br /&gt;
* python-mysql.connector - pure Python implementation of MySQL Client/Server protocol&lt;br /&gt;
&lt;br /&gt;
 apt-get install python-mysqldb&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; import _mysql&lt;br /&gt;
&lt;br /&gt;
 apt-get install python-mysql.connector&lt;br /&gt;
 &lt;br /&gt;
PIP:&lt;br /&gt;
* https://pypi.python.org/pypi/MySQL-python&lt;br /&gt;
* https://pypi.python.org/pypi/mysqlclient&lt;br /&gt;
&lt;br /&gt;
 pip install MySQL-python&lt;br /&gt;
&lt;br /&gt;
 pip install mysqlclient&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
_mysql - http://mysql-python.sourceforge.net/MySQLdb.html&lt;br /&gt;
&lt;br /&gt;
 apt-get install python-mysqldb&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import _mysql&lt;br /&gt;
&lt;br /&gt;
db=_mysql.connect(host=&amp;quot;localhost&amp;quot;,user=&amp;quot;user&amp;quot;,&lt;br /&gt;
                  passwd=&amp;quot;pass&amp;quot;,db=&amp;quot;db&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
db.query(&amp;quot;&amp;quot;&amp;quot;SELECT spam, eggs, sausage FROM breakfast&lt;br /&gt;
         WHERE price &amp;lt; 5&amp;quot;&amp;quot;&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
r=db.store_result()&lt;br /&gt;
# ...or...&lt;br /&gt;
r=db.use_result()&lt;br /&gt;
&lt;br /&gt;
row = r.fetch_row()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== couchdb ===&lt;br /&gt;
&lt;br /&gt;
Getting started with couchdb-python — couchdb-python v0.8 documentation - http://packages.python.org/CouchDB/getting-started.html&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
couch = couchdb.Server(&#039;http://127.0.0.1:5984/&#039;)&lt;br /&gt;
&lt;br /&gt;
# database&lt;br /&gt;
db = couch.create(&#039;test&#039;) # create new&lt;br /&gt;
db = couch[&#039;mydb&#039;] # or get existing&lt;br /&gt;
&lt;br /&gt;
# print databases:&lt;br /&gt;
for db in couch:&lt;br /&gt;
  print db&lt;br /&gt;
&lt;br /&gt;
doc = {&#039;foo&#039;: &#039;bar&#039;}&lt;br /&gt;
doc_id, doc_rev = db.save(doc)&lt;br /&gt;
# (u&#039;9278f7691c3421227a9f8436540008f9&#039;, u&#039;1-4c6114c65e295552ab1019e2b046b10e&#039;)&lt;br /&gt;
# note: this also updates doc with _rev and _id&lt;br /&gt;
doc = db[&#039;9278f7691c3421227a9f8436540008f9&#039;]&lt;br /&gt;
&lt;br /&gt;
# better to create a document using an id you want, instead of the randomly generated one&lt;br /&gt;
db[doc.id] = doc  # this will write immediately to the database&lt;br /&gt;
&lt;br /&gt;
# print all docs:&lt;br /&gt;
for id in db:&lt;br /&gt;
  print id&lt;br /&gt;
&lt;br /&gt;
# delete doc&lt;br /&gt;
db.delete(doc)&lt;br /&gt;
&lt;br /&gt;
# delete database&lt;br /&gt;
couch.delete(&#039;test&#039;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Search database:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# show all records&lt;br /&gt;
map_fun = &#039;&#039;&#039;function(doc) { emit(doc.name, null); }&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
# row = &amp;lt;Row id=u&#039;12341234123412341234&#039;, key=None, value=None&amp;gt;&lt;br /&gt;
# emit(key, value) - returns the values for key and value&lt;br /&gt;
&lt;br /&gt;
map_fun = &#039;&#039;&#039;&lt;br /&gt;
function(doc) {&lt;br /&gt;
  if (doc.username == &#039;virt-01&#039;)&lt;br /&gt;
     emit(doc.username, null);&lt;br /&gt;
}&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
# row = &amp;lt;Row id=u&#039;12341234123412341234&#039;, key=None, value=None&amp;gt;&lt;br /&gt;
for row in db.query(map_fun):&lt;br /&gt;
  print row.id&lt;br /&gt;
&lt;br /&gt;
for row in db.query(map_fun, descending=True):&lt;br /&gt;
  print row.id&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
couchdb-python - CouchDB Python Library - Google Project Hosting - http://code.google.com/p/couchdb-python/&lt;br /&gt;
&lt;br /&gt;
Installation:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir -p ~/.src ; cd ~/.src&lt;br /&gt;
wget http://pypi.python.org/packages/source/C/CouchDB/CouchDB-0.8.tar.gz#md5=e32b39e459e1fa2586ea252712a11a59&lt;br /&gt;
tar -zvxf CouchDB-0.8.tar.gz&lt;br /&gt;
cd CouchDB-0.8&lt;br /&gt;
python setup.py install&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Test:&lt;br /&gt;
 echo &amp;quot;import couchdb&amp;quot; | python&lt;br /&gt;
&lt;br /&gt;
=== nose ===&lt;br /&gt;
&lt;br /&gt;
nose: nose extends unittest to make testing easier&lt;br /&gt;
&lt;br /&gt;
nose : Python Package Index - http://pypi.python.org/pypi/nose&lt;br /&gt;
&lt;br /&gt;
Install:&lt;br /&gt;
 mkdir -p ~/.src ; cd ~/.src&lt;br /&gt;
 wget http://pypi.python.org/packages/source/n/nose/nose-1.1.2.tar.gz#md5=144f237b615e23f21f6a50b2183aa817&lt;br /&gt;
 tar -zvxf nose-1.1.2.tar.gz&lt;br /&gt;
 cd nose-1.1.2&lt;br /&gt;
 sudo python setup.py install&lt;br /&gt;
&lt;br /&gt;
skeleton:&lt;br /&gt;
 mkdir skeleton&lt;br /&gt;
 cd skeleton&lt;br /&gt;
 mkdir bin NAME tests docs&lt;br /&gt;
 touch NAME/__init__.py&lt;br /&gt;
 touch tests/__init__.py&lt;br /&gt;
 touch tests/NAME_tests.py&lt;br /&gt;
&lt;br /&gt;
nose test skeleton:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# tests/NAME_tests.py&lt;br /&gt;
from nose.tools import *&lt;br /&gt;
import klib&lt;br /&gt;
&lt;br /&gt;
def setup():&lt;br /&gt;
    print &amp;quot;SETUP!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
def teardown():&lt;br /&gt;
    print &amp;quot;TEAR DOWN!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
def test_basic():&lt;br /&gt;
    print &amp;quot;I RAN!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# def test_something_else():&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
 nosetests&lt;br /&gt;
&lt;br /&gt;
See Also:&lt;br /&gt;
* [[#doctest]]&lt;br /&gt;
* [[#unittest]]&lt;br /&gt;
&lt;br /&gt;
=== pydoc ===&lt;br /&gt;
&lt;br /&gt;
25.1. pydoc — Documentation generator and online help system — Python v2.7.2 documentation - http://docs.python.org/library/pydoc.html&lt;br /&gt;
&lt;br /&gt;
pydoc - The pydoc module automatically generates documentation from Python modules.&lt;br /&gt;
&lt;br /&gt;
pydoc - same as &#039;import [library], help([library])&#039;&lt;br /&gt;
 $ pydoc [library]&lt;br /&gt;
&lt;br /&gt;
Note: lists some special &#039;module metadata variables&#039; separately (e.g. version, author).&lt;br /&gt;
&lt;br /&gt;
special pydoc recognized metadata sections:&lt;br /&gt;
 __version__&lt;br /&gt;
 __author__&lt;br /&gt;
 __credits__&lt;br /&gt;
 __date__&lt;br /&gt;
&lt;br /&gt;
==== pydoc function module ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Help on package klib:&lt;br /&gt;
&lt;br /&gt;
NAME&lt;br /&gt;
    klib - This is the name&lt;br /&gt;
&lt;br /&gt;
FILE&lt;br /&gt;
    /root/klib/klib/__init__.py&lt;br /&gt;
&lt;br /&gt;
DESCRIPTION&lt;br /&gt;
    These are module doc strings&lt;br /&gt;
        that give helpful details&lt;br /&gt;
&lt;br /&gt;
PACKAGE CONTENTS&lt;br /&gt;
    markone&lt;br /&gt;
&lt;br /&gt;
FUNCTIONS&lt;br /&gt;
    func1()&lt;br /&gt;
        This is a doc string&lt;br /&gt;
        for func1&lt;br /&gt;
&lt;br /&gt;
DATA&lt;br /&gt;
    PI = 3.141&lt;br /&gt;
    __all__ = [&#039;func1&#039;, &#039;PI&#039;]&lt;br /&gt;
    __author__ = &#039;Kenneth &amp;lt;kenneth@oeey.com&amp;gt;&#039;&lt;br /&gt;
    __copyright__ = &#039;Copyright 2007, The Project&#039;&lt;br /&gt;
    __credits__ = &#039;Credits go to me&#039;&lt;br /&gt;
    __date__ = &#039;26 February 2001&#039;&lt;br /&gt;
    __email__ = &#039;ken@oeey.com&#039;&lt;br /&gt;
    __license__ = &#039;GPL&#039;&lt;br /&gt;
    __maintainer__ = &#039;Ken&#039;&lt;br /&gt;
    __status__ = &#039;Production&#039;&lt;br /&gt;
    __version__ = &#039;$Revision: 83492 $&#039;&lt;br /&gt;
&lt;br /&gt;
VERSION&lt;br /&gt;
    83492&lt;br /&gt;
&lt;br /&gt;
DATE&lt;br /&gt;
    26 February 2001&lt;br /&gt;
&lt;br /&gt;
AUTHOR&lt;br /&gt;
    Kenneth &amp;lt;kenneth@oeey.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
CREDITS&lt;br /&gt;
    Credits go to me&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Source:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
This is the name&lt;br /&gt;
&lt;br /&gt;
These are module doc strings&lt;br /&gt;
    that give helpful details&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#__version__ = &amp;quot;1.0&amp;quot;&lt;br /&gt;
__version__ = &amp;quot;$Revision: 83492 $&amp;quot;&lt;br /&gt;
__author__ = &amp;quot;Kenneth &amp;lt;kenneth@oeey.com&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
__date__ = &amp;quot;26 February 2001&amp;quot;&lt;br /&gt;
__credits__ = &amp;quot;Credits go to me&amp;quot;&lt;br /&gt;
&lt;br /&gt;
__all__ = [&#039;func1&#039;, &#039;PI&#039;]&lt;br /&gt;
&lt;br /&gt;
PI = 3.141&lt;br /&gt;
&lt;br /&gt;
__copyright__ = &#039;hello license&#039;&lt;br /&gt;
__license__ = &amp;quot;GPL&amp;quot;&lt;br /&gt;
__copyright__ = &amp;quot;Copyright 2007, The Project&amp;quot;&lt;br /&gt;
__maintainer__ = &amp;quot;Ken&amp;quot;&lt;br /&gt;
__email__ = &amp;quot;ken@oeey.com&amp;quot;&lt;br /&gt;
__status__ = &amp;quot;Production&amp;quot;&lt;br /&gt;
&lt;br /&gt;
def func1():&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    This is a doc string&lt;br /&gt;
    for func1&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== pydoc class module ====&lt;br /&gt;
&lt;br /&gt;
Sample:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Help on module class_pydoc:&lt;br /&gt;
&lt;br /&gt;
NAME&lt;br /&gt;
    class_pydoc - This is the name&lt;br /&gt;
&lt;br /&gt;
FILE&lt;br /&gt;
    /root/class_pydoc.py&lt;br /&gt;
&lt;br /&gt;
DESCRIPTION&lt;br /&gt;
    These are module doc strings&lt;br /&gt;
        that give helpful details&lt;br /&gt;
&lt;br /&gt;
CLASSES&lt;br /&gt;
    Toad&lt;br /&gt;
&lt;br /&gt;
    class Toad&lt;br /&gt;
     |  doc string for object&lt;br /&gt;
     |&lt;br /&gt;
     |  Methods defined here:&lt;br /&gt;
     |&lt;br /&gt;
     |  __init___(self, name)&lt;br /&gt;
     |      Constructor&lt;br /&gt;
     |&lt;br /&gt;
     |  instance_function(self)&lt;br /&gt;
     |      Instance Function&lt;br /&gt;
     |&lt;br /&gt;
     |  ----------------------------------------------------------------------&lt;br /&gt;
     |  Class methods defined here:&lt;br /&gt;
     |&lt;br /&gt;
     |  class_function(cls) from __builtin__.classobj&lt;br /&gt;
     |      Class Function&lt;br /&gt;
     |&lt;br /&gt;
     |  ----------------------------------------------------------------------&lt;br /&gt;
     |  Data and other attributes defined here:&lt;br /&gt;
     |&lt;br /&gt;
     |  my_class_attribute = &#039;sample class attribute&#039;&lt;br /&gt;
&lt;br /&gt;
DATA&lt;br /&gt;
    PI = 3.141&lt;br /&gt;
    __author__ = &#039;Kenneth &amp;lt;kenneth@oeey.com&amp;gt;&#039;&lt;br /&gt;
    __copyright__ = &#039;Copyright 2007, The Project&#039;&lt;br /&gt;
    __credits__ = &#039;Credits go to me&#039;&lt;br /&gt;
    __date__ = &#039;26 February 2001&#039;&lt;br /&gt;
    __email__ = &#039;ken@oeey.com&#039;&lt;br /&gt;
    __license__ = &#039;GPL&#039;&lt;br /&gt;
    __maintainer__ = &#039;Ken&#039;&lt;br /&gt;
    __status__ = &#039;Production&#039;&lt;br /&gt;
    __version__ = &#039;1.0&#039;&lt;br /&gt;
&lt;br /&gt;
VERSION&lt;br /&gt;
    1.0&lt;br /&gt;
&lt;br /&gt;
DATE&lt;br /&gt;
    26 February 2001&lt;br /&gt;
&lt;br /&gt;
AUTHOR&lt;br /&gt;
    Kenneth &amp;lt;kenneth@oeey.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
CREDITS&lt;br /&gt;
    Credits go to me&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Code:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
This is the name&lt;br /&gt;
&lt;br /&gt;
These are module doc strings&lt;br /&gt;
    that give helpful details&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
__version__ = &amp;quot;1.0&amp;quot;&lt;br /&gt;
#__version__ = &amp;quot;$Revision: 83492 $&amp;quot;&lt;br /&gt;
__author__ = &amp;quot;Kenneth &amp;lt;kenneth@oeey.com&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
__date__ = &amp;quot;26 February 2001&amp;quot;&lt;br /&gt;
__credits__ = &amp;quot;Credits go to me&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#__all__ = [&#039;func1&#039;, &#039;PI&#039;]&lt;br /&gt;
&lt;br /&gt;
PI = 3.141&lt;br /&gt;
&lt;br /&gt;
__copyright__ = &#039;hello license&#039;&lt;br /&gt;
__license__ = &amp;quot;GPL&amp;quot;&lt;br /&gt;
__copyright__ = &amp;quot;Copyright 2007, The Project&amp;quot;&lt;br /&gt;
__maintainer__ = &amp;quot;Ken&amp;quot;&lt;br /&gt;
__email__ = &amp;quot;ken@oeey.com&amp;quot;&lt;br /&gt;
__status__ = &amp;quot;Production&amp;quot;&lt;br /&gt;
&lt;br /&gt;
class Toad:&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot; doc string for object &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    my_class_attribute = &#039;sample class attribute&#039;&lt;br /&gt;
&lt;br /&gt;
    def __init___(self, name):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot; Constructor &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    def instance_function(self):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot; Instance Function &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    @classmethod&lt;br /&gt;
    def class_function(cls):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot; Class Function &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== username ===&lt;br /&gt;
&lt;br /&gt;
User ID:&lt;br /&gt;
 os.getuid()&lt;br /&gt;
&lt;br /&gt;
User Name:&lt;br /&gt;
 # fails it stdin piped to program&lt;br /&gt;
 os.getlogin()&lt;br /&gt;
&lt;br /&gt;
User Name:&lt;br /&gt;
 import sys&lt;br /&gt;
 import pwd&lt;br /&gt;
 def get_username():&lt;br /&gt;
     return pwd.getpwuid( os.getuid() )[ 0 ]&lt;br /&gt;
&lt;br /&gt;
Environment:&lt;br /&gt;
 os.environ[&#039;USER&#039;]&lt;br /&gt;
&lt;br /&gt;
=== hostname ===&lt;br /&gt;
&lt;br /&gt;
 import socket&lt;br /&gt;
 print(socket.gethostname())&lt;br /&gt;
&lt;br /&gt;
 os.uname()[1]&lt;br /&gt;
&lt;br /&gt;
 hostname = os.system(&#039;hostname&#039;)&lt;br /&gt;
&lt;br /&gt;
=== Networking ===&lt;br /&gt;
&lt;br /&gt;
==== Get Hostname ====&lt;br /&gt;
&lt;br /&gt;
 import socket&lt;br /&gt;
 print(socket.gethostname())&lt;br /&gt;
&lt;br /&gt;
==== Convert hostname to ip address ====&lt;br /&gt;
&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; socket.gethostbyaddr(&#039;demo&#039;)&lt;br /&gt;
 (&#039;demo.oeey.com&#039;, [], [&#039;10.10.10.10&#039;])&lt;br /&gt;
&lt;br /&gt;
/usr/local/bin/whatip: (or nametoip)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
# whatip - convert hostname to ip address&lt;br /&gt;
# author: Kenneth Burgener &amp;lt;kenneth@oeey.com&amp;gt; (FEB 2012)&lt;br /&gt;
#&lt;br /&gt;
&lt;br /&gt;
import socket&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
if len(sys.argv) != 2:&lt;br /&gt;
  print &amp;quot;Convert Hostname to IP Address&amp;quot;&lt;br /&gt;
  print &amp;quot;Usage: %s HOSTNAME&amp;quot; % sys.argv[0].split(&#039;/&#039;)[-1]&lt;br /&gt;
  sys.exit(1)&lt;br /&gt;
&lt;br /&gt;
hostname = sys.argv[1]&lt;br /&gt;
try:&lt;br /&gt;
  result = socket.gethostbyaddr(hostname)&lt;br /&gt;
  print result[2][0]&lt;br /&gt;
except (socket.gaierror, socket.herror) as e:&lt;br /&gt;
  print &amp;quot;Error: Unable to resolve &#039;%s&#039;&amp;quot; % hostname&lt;br /&gt;
  sys.exit(1)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Get Public IP Address ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)&lt;br /&gt;
s.connect((&amp;quot;gmail.com&amp;quot;,80))&lt;br /&gt;
print(s.getsockname()[0])&lt;br /&gt;
s.close()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
networking - Finding local IP addresses using Python&#039;s stdlib - Stack Overflow - http://stackoverflow.com/questions/166506/finding-local-ip-addresses-using-pythons-stdlib&lt;br /&gt;
&lt;br /&gt;
==== Python Network Server ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/python           # This is server.py file&lt;br /&gt;
&lt;br /&gt;
import socket               # Import socket module&lt;br /&gt;
&lt;br /&gt;
s = socket.socket()         # Create a socket object&lt;br /&gt;
host = socket.gethostname() # Get local machine name&lt;br /&gt;
port = 12345                # Reserve a port for your service.&lt;br /&gt;
s.bind((host, port))        # Bind to the port&lt;br /&gt;
&lt;br /&gt;
s.listen(5)                 # Now wait for client connection.&lt;br /&gt;
while True:&lt;br /&gt;
   c, addr = s.accept()     # Establish connection with client.&lt;br /&gt;
   print &#039;Got connection from&#039;, addr&lt;br /&gt;
   c.send(&#039;Thank you for connecting&#039;)&lt;br /&gt;
   c.close()                # Close the connection&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Source: http://www.tutorialspoint.com/python/python_networking.htm&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* 17.2. socket — Low-level networking interface — Python v2.7.5 documentation - http://docs.python.org/2/library/socket.html&lt;br /&gt;
&lt;br /&gt;
==== Python Network Client ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/python           # This is client.py file&lt;br /&gt;
&lt;br /&gt;
import socket               # Import socket module&lt;br /&gt;
&lt;br /&gt;
s = socket.socket()         # Create a socket object&lt;br /&gt;
host = socket.gethostname() # Get local machine name&lt;br /&gt;
port = 12345                # Reserve a port for your service.&lt;br /&gt;
&lt;br /&gt;
s.connect((host, port))&lt;br /&gt;
print s.recv(1024)&lt;br /&gt;
s.close                     # Close the socket when done&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Source: http://www.tutorialspoint.com/python/python_networking.htm&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* 17.2. socket — Low-level networking interface — Python v2.7.5 documentation - http://docs.python.org/2/library/socket.html&lt;br /&gt;
&lt;br /&gt;
=== Run Library Module as Script ===&lt;br /&gt;
&lt;br /&gt;
Run python with -m option:&lt;br /&gt;
 -m mod : run library module as a script (terminates option list)&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
 cat [json_file] | python -m json.tool&lt;br /&gt;
 # same as:&lt;br /&gt;
 cat [json_file] | python /opt/python26/lib/python2.6/json/tool.py&lt;br /&gt;
&lt;br /&gt;
Good for when library is buried deep in the library directories&lt;br /&gt;
&lt;br /&gt;
=== Hex ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hex(10)  # print integer as hex string&lt;br /&gt;
&#039;0xa&#039;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; sys.hexversion  # python version as integer&lt;br /&gt;
33817584&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hex(sys.hexversion)  # python version as hex&lt;br /&gt;
&#039;0x20403f0&#039;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; print &amp;quot;0x%08x&amp;quot; % sys.hexversion  # python version as hex&lt;br /&gt;
&#039;0x20403f0&#039;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; int(&#039;0xa&#039;, 16)  # hex string to integer&lt;br /&gt;
10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; int(&#039;0a&#039;, 16)  # hex string to integer&lt;br /&gt;
10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; int(&#039;0xa&#039;, 0)  # hex string to integer auto detected du to &#039;0x&#039;&lt;br /&gt;
10&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Binary ===&lt;br /&gt;
&lt;br /&gt;
Integer to Binary String with Negative Number Support: (2&#039;s complement)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# source: http://www.gossamer-threads.com/lists/python/python/645216&lt;br /&gt;
def bin(x):&lt;br /&gt;
    if x &amp;lt; -32768 or x &amp;gt; 65535:&lt;br /&gt;
        raise Exception(&amp;quot;Out of Range Error: %d&amp;quot; % x)&lt;br /&gt;
    if x &amp;lt; 0:&lt;br /&gt;
        x = 65535 + x + 1&lt;br /&gt;
    bin_str = &#039;&#039;&lt;br /&gt;
    bin_str += &#039;&#039;.join(x &amp;amp; (1 &amp;lt;&amp;lt; i) and &#039;1&#039; or &#039;0&#039; for i in range(15, 11, -1))&lt;br /&gt;
    bin_str += &#039; &#039;&lt;br /&gt;
    bin_str += &#039;&#039;.join(x &amp;amp; (1 &amp;lt;&amp;lt; i) and &#039;1&#039; or &#039;0&#039; for i in range(11, 7, -1))&lt;br /&gt;
    bin_str += &#039; &#039;&lt;br /&gt;
    bin_str += &#039;&#039;.join(x &amp;amp; (1 &amp;lt;&amp;lt; i) and &#039;1&#039; or &#039;0&#039; for i in range(7, 3, -1))&lt;br /&gt;
    bin_str += &#039; &#039;&lt;br /&gt;
    bin_str += &#039;&#039;.join(x &amp;amp; (1 &amp;lt;&amp;lt; i) and &#039;1&#039; or &#039;0&#039; for i in range(3, -1, -1))&lt;br /&gt;
    return bin_str&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Integer to Binary String:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# source: http://www.gossamer-threads.com/lists/python/python/645216&lt;br /&gt;
def bin(x):&lt;br /&gt;
    if x &amp;lt; 0 or x &amp;gt; 65535:&lt;br /&gt;
        raise Exception(&amp;quot;Out of Range Error: %d&amp;quot; % x)&lt;br /&gt;
    bin_str = &#039;&#039;&lt;br /&gt;
    bin_str = &#039;&#039;.join(x &amp;amp; (1 &amp;lt;&amp;lt; i) and &#039;1&#039; or &#039;0&#039; for i in range(15, 7, -1))&lt;br /&gt;
    bin_str = bin_str + &#039; &#039;&lt;br /&gt;
    bin_str = bin_str + &#039;&#039;.join(x &amp;amp; (1 &amp;lt;&amp;lt; i) and &#039;1&#039; or &#039;0&#039; for i in range(7, -1, -1))&lt;br /&gt;
    return bin_str&lt;br /&gt;
&lt;br /&gt;
print bin(0)      # &#039;00000000 00000000&#039;&lt;br /&gt;
print bin(1)      # &#039;00000000 00000001&#039;&lt;br /&gt;
print bin(255)    # &#039;00000000 11111111&#039;&lt;br /&gt;
print bin(256)    # &#039;00000001 00000000&#039;&lt;br /&gt;
print bin(43690)  # &#039;10101010 10101010&#039;&lt;br /&gt;
print bin(65535)  # &#039;11111111 11111111&#039;&lt;br /&gt;
print bin(65536)  # &#039;00000000 00000000&#039; - rolled over to next set!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Integer to Binary:&lt;br /&gt;
 bin(170)  # &#039;0b10101010&#039;&lt;br /&gt;
&lt;br /&gt;
Binary to Integer:&lt;br /&gt;
 int(&#039;10101010&#039;, 2)  # 170&lt;br /&gt;
&lt;br /&gt;
=== bitwise ===&lt;br /&gt;
&lt;br /&gt;
See [[#Binary]]&lt;br /&gt;
&lt;br /&gt;
BitwiseOperators - Python Wiki - http://wiki.python.org/moin/BitwiseOperators&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
The Operators:&lt;br /&gt;
&lt;br /&gt;
x &amp;lt;&amp;lt; y&lt;br /&gt;
    Returns x with the bits shifted to the left by y places (and new bits on the right-hand-side are zeros). This is the same as multiplying x by 2**y. &lt;br /&gt;
x &amp;gt;&amp;gt; y&lt;br /&gt;
    Returns x with the bits shifted to the right by y places. This is the same as //&#039;ing x by 2**y. &lt;br /&gt;
x &amp;amp; y&lt;br /&gt;
    AND - Does a &amp;quot;bitwise and&amp;quot;. Each bit of the output is 1 if the corresponding bit of x AND of y is 1, otherwise it&#039;s 0. &lt;br /&gt;
x | y&lt;br /&gt;
    OR - Does a &amp;quot;bitwise or&amp;quot;. Each bit of the output is 0 if the corresponding bit of x AND of y is 0, otherwise it&#039;s 1. &lt;br /&gt;
~ x&lt;br /&gt;
    Returns the complement of x - the number you get by switching each 1 for a 0 and each 0 for a 1. This is the same as -x - 1. &lt;br /&gt;
x ^ y&lt;br /&gt;
    XOR - Does a &amp;quot;bitwise exclusive or&amp;quot;. Each bit of the output is the same as the corresponding bit in x if that bit in y is 0, and it&#039;s the complement of the bit in x if that bit in y is 1. &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Script Path ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
    # Change directory to where this script lives so we can find relative&lt;br /&gt;
    # paths from here regardless of where the working directory was when we&lt;br /&gt;
    # ran the script.&lt;br /&gt;
    # APP_DIR = os.path.dirname(sys.argv[0])&lt;br /&gt;
    APP_DIR = os.path.dirname(os.path.abspath(sys.argv[0))&lt;br /&gt;
    if APP_DIR:&lt;br /&gt;
        os.chdir(APP_DIR)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 normpath(path)  # Normalize path, eliminating double slashes, etc.&lt;br /&gt;
 abspath(path)   # Return an absolute path&lt;br /&gt;
&lt;br /&gt;
Path to a module: [http://stackoverflow.com/questions/247770/retrieving-python-module-path] (couldn&#039;t fine a_module)&lt;br /&gt;
 import a_module&lt;br /&gt;
 import os&lt;br /&gt;
 path = os.path.dirname(a_module.__file__)&lt;br /&gt;
&lt;br /&gt;
Path to module: [http://stackoverflow.com/questions/50499/in-python-how-do-i-get-the-path-and-name-of-the-file-that-is-currently-executin]&lt;br /&gt;
 import inspect, os&lt;br /&gt;
 print inspect.getfile(inspect.currentframe()) # script filename (usually with path)&lt;br /&gt;
 print os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) # script directory&lt;br /&gt;
&lt;br /&gt;
Even better:&lt;br /&gt;
 print os.path.realpath(__file__)&lt;br /&gt;
 print os.path.dirname(__file__)&lt;br /&gt;
 print os.path.basename(__file__)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
references:&lt;br /&gt;
* http://stackoverflow.com/questions/595305/python-path-of-script&lt;br /&gt;
&lt;br /&gt;
keywords: scriptpath script path program path pathname&lt;br /&gt;
&lt;br /&gt;
=== Singleton ===&lt;br /&gt;
&lt;br /&gt;
GLOBAL OBJECT!&lt;br /&gt;
&lt;br /&gt;
None is a singleton (Python only has one copy of None in the interpreter).&lt;br /&gt;
&lt;br /&gt;
Make your own singleton:&lt;br /&gt;
&lt;br /&gt;
override the new method like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Singleton(object):&lt;br /&gt;
    _instance = None&lt;br /&gt;
    def __new__(cls, *args, **kwargs):&lt;br /&gt;
        if not cls._instance:&lt;br /&gt;
            cls._instance = super(Singleton, cls).__new__(&lt;br /&gt;
                                cls, *args, **kwargs)&lt;br /&gt;
        return cls._instance&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
if __name__ == &#039;__main__&#039;:&lt;br /&gt;
    s1=Singleton()&lt;br /&gt;
    s2=Singleton()&lt;br /&gt;
    if(id(s1)==id(s2)):&lt;br /&gt;
        print &amp;quot;Same&amp;quot;&lt;br /&gt;
    else:&lt;br /&gt;
        print &amp;quot;Different&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Using decorator -implementation from PEP318? Implementing the singleton pattern with a decorator:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def singleton(cls):&lt;br /&gt;
    instances = {}&lt;br /&gt;
    def getinstance():&lt;br /&gt;
        if cls not in instances:&lt;br /&gt;
            instances[cls] = cls()&lt;br /&gt;
        return instances[cls]&lt;br /&gt;
    return getinstance&lt;br /&gt;
&lt;br /&gt;
@singleton&lt;br /&gt;
class MyClass:&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Python and the Singleton Pattern - Stack Overflow - http://stackoverflow.com/questions/42558/python-and-the-singleton-pattern&lt;br /&gt;
&lt;br /&gt;
=== XML ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from xml.dom.minidom import parse, parseString&lt;br /&gt;
&lt;br /&gt;
dom1 = parse(&#039;c:\\temp\\mydata.xml&#039;) # parse an XML file by name&lt;br /&gt;
&lt;br /&gt;
datasource = open(&#039;c:\\temp\\mydata.xml&#039;)&lt;br /&gt;
dom2 = parse(datasource)   # parse an open file&lt;br /&gt;
&lt;br /&gt;
dom3 = parseString(&#039;&amp;lt;myxml&amp;gt;Some data&amp;lt;empty/&amp;gt; some more data&amp;lt;/myxml&amp;gt;&#039;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pretty Print: [http://stackoverflow.com/questions/749796/pretty-printing-xml-in-python]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import xml.dom.minidom&lt;br /&gt;
&lt;br /&gt;
xml = xml.dom.minidom.parse(xml_fname) # or xml.dom.minidom.parseString(xml_string)&lt;br /&gt;
pretty_xml_as_string = xml.toprettyxml()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pretty Print with etree [http://stackoverflow.com/questions/749796/pretty-printing-xml-in-python]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import lxml.etree as etree&lt;br /&gt;
&lt;br /&gt;
x = etree.parse(&amp;quot;filename&amp;quot;)&lt;br /&gt;
print etree.tostring(x, pretty_print = True)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* 19.7. xml.dom.minidom — Lightweight DOM implementation — Python v2.7.3 documentation - http://docs.python.org/library/xml.dom.minidom.html&lt;br /&gt;
* Pretty printing XML in python - Stack Overflow - http://stackoverflow.com/questions/749796/pretty-printing-xml-in-python&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
Simply don&#039;t include self.output.startElement and self.output.endElement for elements you don&#039;t want:&lt;br /&gt;
&lt;br /&gt;
simple_filter_parser.py: (my version of [http://freegeographytools.com/2010/removin-time-data-out-of-a-gpx-or-kml-file-to-make-it-work-right-in-google-earth])&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# this parses out the time element of a gpx for Google Earth&lt;br /&gt;
import os&lt;br /&gt;
import sys&lt;br /&gt;
import optparse&lt;br /&gt;
import fnmatch&lt;br /&gt;
from sys import argv&lt;br /&gt;
import xml.sax, xml.sax.saxutils&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
class my_filter_xml(xml.sax.ContentHandler):&lt;br /&gt;
    def __init__(self, outfile, verbose=False):&lt;br /&gt;
        self.output = xml.sax.saxutils.XMLGenerator(outfile, &#039;utf-8&#039;)&lt;br /&gt;
        self.indent = 0&lt;br /&gt;
        self.ignore = False&lt;br /&gt;
        self.output.startDocument()&lt;br /&gt;
&lt;br /&gt;
    def startElement(self, name, attrs):&lt;br /&gt;
        print &amp;quot; &amp;quot; * self.indent + &amp;quot;start: &amp;quot; + name&lt;br /&gt;
        if attrs.keys():&lt;br /&gt;
            keys = &amp;quot; &amp;quot; * (self.indent + 2) + &amp;quot;attrs:&amp;quot;&lt;br /&gt;
            for key in attrs.keys():&lt;br /&gt;
                keys = keys + &amp;quot; &amp;quot; + key + &amp;quot;=&amp;quot; + attrs[key]&lt;br /&gt;
            print keys&lt;br /&gt;
        self.indent = self.indent + 2&lt;br /&gt;
        #self.output.startElement(name, {})&lt;br /&gt;
        if name == &amp;quot;time&amp;quot;:&lt;br /&gt;
            self.ignore = True&lt;br /&gt;
        #if not self.ignore:&lt;br /&gt;
        self.output.startElement(name, attrs)&lt;br /&gt;
&lt;br /&gt;
    def characters(self, ch):&lt;br /&gt;
        if ch.strip():&lt;br /&gt;
            print &amp;quot; &amp;quot; * self.indent + &amp;quot;ch: &amp;quot; + ch.strip()&lt;br /&gt;
            if not self.ignore:&lt;br /&gt;
                self.output.characters(ch)&lt;br /&gt;
        else:&lt;br /&gt;
            if not self.ignore:&lt;br /&gt;
                self.output.characters(&amp;quot;\n&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    def endElement(self, name):&lt;br /&gt;
        self.indent = self.indent - 2&lt;br /&gt;
        print &amp;quot; &amp;quot; * self.indent + &amp;quot;/end: &amp;quot; + name&lt;br /&gt;
        #if not self.ignore:&lt;br /&gt;
        self.output.endElement(name)&lt;br /&gt;
        if name == &amp;quot;time&amp;quot;:&lt;br /&gt;
            self.ignore = False&lt;br /&gt;
&lt;br /&gt;
if __name__ == &#039;__main__&#039;:&lt;br /&gt;
    source = open(&amp;quot;tracks.gpx&amp;quot;)&lt;br /&gt;
    dest = open(&amp;quot;tracks_out.gpx&amp;quot;, &#039;w+&#039;)&lt;br /&gt;
    xml.sax.parse(source, my_filter_xml(dest, True))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
fixdescriptor.py:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import os&lt;br /&gt;
import sys&lt;br /&gt;
import optparse&lt;br /&gt;
import fnmatch&lt;br /&gt;
from sys import argv&lt;br /&gt;
import xml.sax, xml.sax.saxutils&lt;br /&gt;
&lt;br /&gt;
class fix_descriptor(xml.sax.ContentHandler):&lt;br /&gt;
    def __init__(self, outfile, verbose=False):&lt;br /&gt;
        self._outfile = outfile&lt;br /&gt;
        self._verbose = verbose&lt;br /&gt;
        self.output = xml.sax.saxutils.XMLGenerator(outfile, &#039;utf-8&#039;)&lt;br /&gt;
        self._filter = [ &#039;payload&#039;,&lt;br /&gt;
                         &#039;payloads&#039;,&lt;br /&gt;
                         &#039;file-list&#039;,&lt;br /&gt;
                         &#039;file&#039;,&lt;br /&gt;
                         &#039;checksum&#039; ]&lt;br /&gt;
        self._keep = [ &#039;vib&#039;,&lt;br /&gt;
                       &#039;maintenance-mode&#039; ]&lt;br /&gt;
        self._inside = None&lt;br /&gt;
&lt;br /&gt;
    def startElement(self, name, attrs):&lt;br /&gt;
        # Certain elements are kept unchanged&lt;br /&gt;
        if name in self._keep:&lt;br /&gt;
            if self._verbose:&lt;br /&gt;
                print &#039;%s element start found&#039; % (name)&lt;br /&gt;
            self.output.startElement(name, {})&lt;br /&gt;
            if name == &#039;maintenance-mode&#039;:&lt;br /&gt;
                if self._verbose:&lt;br /&gt;
                    print &#039;inside maintenance-mode&#039;&lt;br /&gt;
                self._inside = name&lt;br /&gt;
            return&lt;br /&gt;
        # Other elements are filtered (removed)&lt;br /&gt;
        elif name in self._filter:&lt;br /&gt;
            if self._verbose:&lt;br /&gt;
                print &#039;%s element start found&#039; % (name)&lt;br /&gt;
            self._inside = name&lt;br /&gt;
            return&lt;br /&gt;
        self.output.startElement(name, attrs)&lt;br /&gt;
&lt;br /&gt;
    def characters(self, ch):&lt;br /&gt;
        if self._inside == &#039;maintenance-mode&#039;:&lt;br /&gt;
            if self._verbose:&lt;br /&gt;
                print &#039;new content for maintenance-mode&#039;&lt;br /&gt;
            self.output.characters(&#039;false&#039;)&lt;br /&gt;
        elif self._inside not in self._filter:&lt;br /&gt;
            self.output.characters(ch)&lt;br /&gt;
&lt;br /&gt;
    def endElement(self, name):&lt;br /&gt;
        # If it&#039;s not a checksum element, only print it&lt;br /&gt;
        if name in self._filter + self._keep:&lt;br /&gt;
            self._inside = None&lt;br /&gt;
            if self._verbose:&lt;br /&gt;
                print &#039;%s element end found&#039; % (name)&lt;br /&gt;
            if name in self._filter:&lt;br /&gt;
                return&lt;br /&gt;
        self.output.endElement(name)&lt;br /&gt;
&lt;br /&gt;
if __name__ == &#039;__main__&#039;:&lt;br /&gt;
    #&lt;br /&gt;
    parser = optparse.OptionParser(usage=&#039;%prog ...&#039;)&lt;br /&gt;
    parser.add_option(&#039;-v&#039;, &#039;--verbose&#039;,&lt;br /&gt;
                       action=&#039;store_true&#039;, default=False,&lt;br /&gt;
                       help=&#039;Print more information.&#039;)&lt;br /&gt;
    parser.add_option(&#039;--input-xml&#039;,&lt;br /&gt;
                       type=&#039;str&#039;, default=&#039;descriptor.xml&#039;,&lt;br /&gt;
                       help=&#039;Name of input XML [default: %default]&#039;)&lt;br /&gt;
    parser.add_option(&#039;--output-xml&#039;,&lt;br /&gt;
                       type=&#039;str&#039;, default=&#039;fixed_descriptor.xml&#039;,&lt;br /&gt;
                       help=&#039;Name of output XML [default: %default]&#039;)&lt;br /&gt;
    opts, args = parser.parse_args(argv[1:])&lt;br /&gt;
    source = open(opts.input_xml)&lt;br /&gt;
    dest = open(opts.output_xml, &#039;w+&#039;)&lt;br /&gt;
    xml.sax.parse(source, fix_descriptor(dest, opts.verbose))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--&lt;br /&gt;
&lt;br /&gt;
Simple read and output parsing:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import os&lt;br /&gt;
import sys&lt;br /&gt;
import optparse&lt;br /&gt;
import fnmatch&lt;br /&gt;
from sys import argv&lt;br /&gt;
import xml.sax, xml.sax.saxutils&lt;br /&gt;
&lt;br /&gt;
class fix_descriptor(xml.sax.ContentHandler):&lt;br /&gt;
    def __init__(self, outfile, verbose=False):&lt;br /&gt;
        self._outfile = outfile&lt;br /&gt;
        self._verbose = verbose&lt;br /&gt;
        self.output = xml.sax.saxutils.XMLGenerator(outfile, &#039;utf-8&#039;)&lt;br /&gt;
        self._inside = None&lt;br /&gt;
&lt;br /&gt;
    def startElement(self, name, attrs):&lt;br /&gt;
        # attrs.items() is a list of tuples (name, value)&lt;br /&gt;
        print &amp;quot;start:&amp;quot;, name, &amp;quot;/&amp;quot;, attrs.items()&lt;br /&gt;
        self.output.startElement(name, attrs)&lt;br /&gt;
&lt;br /&gt;
    def characters(self, ch):&lt;br /&gt;
        print &amp;quot;char:&amp;quot;, self._inside, &amp;quot;/&amp;quot;, ch&lt;br /&gt;
        self.output.characters(ch)&lt;br /&gt;
&lt;br /&gt;
    def endElement(self, name):&lt;br /&gt;
        print &amp;quot;end:&amp;quot;, name&lt;br /&gt;
        self.output.endElement(name)&lt;br /&gt;
&lt;br /&gt;
if __name__ == &#039;__main__&#039;:&lt;br /&gt;
    parser = optparse.OptionParser(usage=&#039;%prog ...&#039;)&lt;br /&gt;
    parser.add_option(&#039;-v&#039;, &#039;--verbose&#039;,&lt;br /&gt;
                       action=&#039;store_true&#039;, default=False,&lt;br /&gt;
                       help=&#039;Print more information.&#039;)&lt;br /&gt;
    parser.add_option(&#039;--input-xml&#039;,&lt;br /&gt;
                       type=&#039;str&#039;, default=&#039;descriptor.xml&#039;,&lt;br /&gt;
                       help=&#039;Name of input XML [default: %default]&#039;)&lt;br /&gt;
    parser.add_option(&#039;--output-xml&#039;,&lt;br /&gt;
                       type=&#039;str&#039;, default=&#039;fixed_descriptor.xml&#039;,&lt;br /&gt;
                       help=&#039;Name of output XML [default: %default]&#039;)&lt;br /&gt;
    opts, args = parser.parse_args(argv[1:])&lt;br /&gt;
    source = open(opts.input_xml)&lt;br /&gt;
    dest = open(opts.output_xml, &#039;w+&#039;)&lt;br /&gt;
    xml.sax.parse(source, fix_descriptor(dest, opts.verbose))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Unicode ===&lt;br /&gt;
&lt;br /&gt;
Unicode string:&lt;br /&gt;
 u&#039;Hello World !&#039;&lt;br /&gt;
&lt;br /&gt;
Raw Unicode string:&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; ur&#039;Hello\u0020World !&#039;&lt;br /&gt;
 u&#039;Hello World !&#039;&lt;br /&gt;
&lt;br /&gt;
Convert:&lt;br /&gt;
 u = u&#039;hello\xe4&#039;&lt;br /&gt;
 str(u)  # UnicodeEncodeError: &#039;ascii&#039; codec can&#039;t encode character u&#039;\xe4&#039; in position 5: ordinal not in range(128)&lt;br /&gt;
 s = u.encode(&#039;utf8&#039;)  # &#039;s&#039; is now type str&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* Introduction to Unicode Strings - http://docs.python.org/tutorial/introduction.html#unicode-strings&lt;br /&gt;
&lt;br /&gt;
=== Zip ===&lt;br /&gt;
&lt;br /&gt;
See [[Python/Zip]]&lt;br /&gt;
&lt;br /&gt;
=== signals ===&lt;br /&gt;
&lt;br /&gt;
 signal.SIGTERM  : kill  [pid]&lt;br /&gt;
 signal.SIGALRM  : kill -ALRM  [pid]&lt;br /&gt;
 signal.SIGHUP   : kill -HUP  [pid]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import signal, os&lt;br /&gt;
&lt;br /&gt;
def handler(signum, frame):&lt;br /&gt;
    print &#039;Signal handler called with signal&#039;, signum&lt;br /&gt;
    raise IOError(&amp;quot;Couldn&#039;t open device!&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
# Set the signal handler and a 5-second alarm&lt;br /&gt;
signal.signal(signal.SIGALRM, handler)&lt;br /&gt;
signal.alarm(5)&lt;br /&gt;
&lt;br /&gt;
# This open() may hang indefinitely&lt;br /&gt;
fd = os.open(&#039;/dev/ttyS0&#039;, os.O_RDWR)&lt;br /&gt;
&lt;br /&gt;
signal.alarm(0)          # Disable the alarm&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: use signal.SIGTERM to handle &amp;quot;kill&amp;quot; command&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* 17.4. signal — Set handlers for asynchronous events — Python v2.7.5 documentation - http://docs.python.org/2/library/signal.html&lt;br /&gt;
&lt;br /&gt;
==== Ctrl+C ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
import signal&lt;br /&gt;
import sys&lt;br /&gt;
def signal_handler(signal, frame):&lt;br /&gt;
        print &#039;You pressed Ctrl+C!&#039;&lt;br /&gt;
        sys.exit(0)&lt;br /&gt;
signal.signal(signal.SIGINT, signal_handler)&lt;br /&gt;
print &#039;Press Ctrl+C&#039;&lt;br /&gt;
&lt;br /&gt;
# linux only:&lt;br /&gt;
signal.pause()&lt;br /&gt;
&lt;br /&gt;
# windows alternative:&lt;br /&gt;
#import time&lt;br /&gt;
#time.sleep(60)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* control - How do I capture SIGINT in Python? - Stack Overflow - http://stackoverflow.com/questions/1112343/how-do-i-capture-sigint-in-python&lt;br /&gt;
&lt;br /&gt;
==== Non-blocking raw_input for Python ====&lt;br /&gt;
&lt;br /&gt;
Non-blocking raw_input for Python:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# source: http://www.garyrobinson.net/2009/10/non-blocking-raw_input-for-python.html&lt;br /&gt;
&lt;br /&gt;
import signal&lt;br /&gt;
&lt;br /&gt;
class AlarmException(Exception):&lt;br /&gt;
    pass&lt;br /&gt;
&lt;br /&gt;
def alarmHandler(signum, frame):&lt;br /&gt;
    raise AlarmException&lt;br /&gt;
&lt;br /&gt;
def nonBlockingRawInput(prompt=&#039;&#039;, timeout=20):&lt;br /&gt;
    signal.signal(signal.SIGALRM, alarmHandler)&lt;br /&gt;
    signal.alarm(timeout)&lt;br /&gt;
    try:&lt;br /&gt;
        text = raw_input(prompt)&lt;br /&gt;
        signal.alarm(0)&lt;br /&gt;
        return text&lt;br /&gt;
    except AlarmException:&lt;br /&gt;
        print &#039;\nPrompt timeout. Continuing...&#039;&lt;br /&gt;
    signal.signal(signal.SIGALRM, signal.SIG_IGN)&lt;br /&gt;
    return &#039;&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== email ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import smtplib&lt;br /&gt;
import email.mime.text&lt;br /&gt;
&lt;br /&gt;
msg_text = &amp;quot;Hello World&amp;quot;&lt;br /&gt;
msg = email.mime.text.MIMEText(msg_text)&lt;br /&gt;
&lt;br /&gt;
# me == the sender&#039;s email address&lt;br /&gt;
# you == the recipient&#039;s email address&lt;br /&gt;
msg[&#039;Subject&#039;] = &#039;The contents of %s&#039; % textfile&lt;br /&gt;
msg[&#039;From&#039;] = me&lt;br /&gt;
msg[&#039;To&#039;] = you&lt;br /&gt;
&lt;br /&gt;
# Send the message via our own SMTP server, but don&#039;t include the&lt;br /&gt;
# envelope header.&lt;br /&gt;
s = smtplib.SMTP(&#039;localhost&#039;)&lt;br /&gt;
s.sendmail(me, [you], msg.as_string())&lt;br /&gt;
s.quit()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
my nagios fake /bin/mail:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
&lt;br /&gt;
import smtplib&lt;br /&gt;
import email.mime.text&lt;br /&gt;
import optparse&lt;br /&gt;
import os&lt;br /&gt;
import sys&lt;br /&gt;
import pwd&lt;br /&gt;
&lt;br /&gt;
os.system(&#039;logger mail called&#039;)&lt;br /&gt;
&lt;br /&gt;
parser = optparse.OptionParser()&lt;br /&gt;
parser.add_option(&lt;br /&gt;
    &#039;-s&#039;, &#039;--subject&#039;,&lt;br /&gt;
    help=&#039;Subject&#039;,&lt;br /&gt;
    default=&amp;quot;&amp;quot;)&lt;br /&gt;
parser.add_option(&lt;br /&gt;
    &#039;-t&#039;, &#039;--to&#039;,&lt;br /&gt;
    help=&#039;To&#039;,&lt;br /&gt;
    dest=&amp;quot;send_to&amp;quot;,&lt;br /&gt;
    default=None)&lt;br /&gt;
parser.add_option(&lt;br /&gt;
    &#039;-f&#039;, &#039;--from&#039;,&lt;br /&gt;
    help=&#039;From&#039;,&lt;br /&gt;
    dest=&amp;quot;send_from&amp;quot;,&lt;br /&gt;
    default=None)&lt;br /&gt;
parser.add_option(&lt;br /&gt;
    &#039;-S&#039;, &#039;--server&#039;,&lt;br /&gt;
    help=&#039;server&#039;,&lt;br /&gt;
    default=&amp;quot;prime&amp;quot;)&lt;br /&gt;
(options, args) = parser.parse_args()&lt;br /&gt;
&lt;br /&gt;
def get_username():&lt;br /&gt;
    return pwd.getpwuid( os.getuid() )[ 0 ]&lt;br /&gt;
&lt;br /&gt;
if options.send_to:&lt;br /&gt;
    send_to = options.send_to&lt;br /&gt;
else:&lt;br /&gt;
    if len(args) == 1:&lt;br /&gt;
        send_to = args[0]&lt;br /&gt;
    else:&lt;br /&gt;
        parser.print_help()&lt;br /&gt;
        sys.exit(1)&lt;br /&gt;
&lt;br /&gt;
if options.send_from:&lt;br /&gt;
    send_from = options.send_from&lt;br /&gt;
else:&lt;br /&gt;
    username = get_username()&lt;br /&gt;
    hostname = os.uname()[1]&lt;br /&gt;
    send_from = username + &amp;quot;@&amp;quot; + hostname&lt;br /&gt;
&lt;br /&gt;
msg_text = sys.stdin.read()&lt;br /&gt;
msg = email.mime.text.MIMEText(msg_text)&lt;br /&gt;
&lt;br /&gt;
msg[&#039;Subject&#039;] = options.subject&lt;br /&gt;
msg[&#039;From&#039;] = send_from&lt;br /&gt;
msg[&#039;To&#039;] = send_to&lt;br /&gt;
&lt;br /&gt;
s = smtplib.SMTP(options.server)&lt;br /&gt;
s.sendmail(send_from, [send_to], msg.as_string())&lt;br /&gt;
s.quit()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Authenticated (with gmail):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import smtplib&lt;br /&gt;
import email.mime.text&lt;br /&gt;
&lt;br /&gt;
# from_email = &amp;quot;kenneth@demo.oeey.com&amp;quot;&lt;br /&gt;
# to_email = &amp;quot;kenneth@demo.oeey.com&amp;quot;&lt;br /&gt;
from_email = &amp;quot;Kenneth Burgener &amp;lt;kenneth@demo.oeey.com&amp;gt;&amp;quot;&lt;br /&gt;
to_emails = [&amp;quot;Kenneth Burgener &amp;lt;kenneth@demo.oeey.com&amp;gt;&amp;quot;, &amp;quot;Kenneth Cell &amp;lt;xxx@xxx.com&amp;gt;&amp;quot;]&lt;br /&gt;
&lt;br /&gt;
msg_text = &amp;quot;hello world&amp;quot;&lt;br /&gt;
msg = email.mime.text.MIMEText(msg_text)&lt;br /&gt;
msg[&#039;Subject&#039;] = &#039;Test text&#039;&lt;br /&gt;
msg[&#039;From&#039;] = from_email&lt;br /&gt;
# msg[&#039;To&#039;] = to_email&lt;br /&gt;
msg[&#039;To&#039;] = &amp;quot;, &amp;quot;.join(to_emails)&lt;br /&gt;
# s = smtplib.SMTP(&#039;localhost&#039;)&lt;br /&gt;
print &amp;quot;sending...&amp;quot;&lt;br /&gt;
s = smtplib.SMTP_SSL(&#039;smtp.gmail.com&#039;, &#039;465&#039;)&lt;br /&gt;
s.login(&#039;xxx&#039;, &#039;xxx&#039;)&lt;br /&gt;
# s.sendmail(from_email, [to_email], msg.as_string())&lt;br /&gt;
s.sendmail(from_email, to_emails, msg.as_string())&lt;br /&gt;
s.quit()&lt;br /&gt;
print &amp;quot;sent!&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Source: &lt;br /&gt;
* 20.12. smtplib — SMTP protocol client — Python v2.7.5 documentation - http://docs.python.org/2/library/smtplib.html&lt;br /&gt;
* 18.1.11. email: Examples — Python v2.7.5 documentation - http://docs.python.org/2/library/email-examples.html&lt;br /&gt;
&lt;br /&gt;
=== pprint ===&lt;br /&gt;
&lt;br /&gt;
8.18. pprint — Data pretty printer — Python v2.7.5 documentation - http://docs.python.org/2/library/pprint.html&lt;br /&gt;
&lt;br /&gt;
 import pprint&lt;br /&gt;
 pprint.pprint(myVar)&lt;br /&gt;
&lt;br /&gt;
 import pprint&lt;br /&gt;
 pp = pprint.PrettyPrinter(indent=4)&lt;br /&gt;
 pp.pprint(myVar)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Note: Useless on objects!&lt;br /&gt;
&lt;br /&gt;
Dump object:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def dumpobject(obj):&lt;br /&gt;
    print &amp;quot;&amp;lt;&amp;lt;&amp;lt;---&amp;quot;&lt;br /&gt;
    print type(obj), obj.__class__.__name__&lt;br /&gt;
    for attr in dir(obj):&lt;br /&gt;
        if attr[0] == &amp;quot;_&amp;quot;: continue  # ignore under/dunder properties&lt;br /&gt;
        if str(type(getattr(obj, attr))) == &amp;quot;&amp;lt;type &#039;instancemethod&#039;&amp;gt;&amp;quot;:&lt;br /&gt;
            print attr, &amp;quot;: METHOD&amp;quot;&lt;br /&gt;
        else:&lt;br /&gt;
            print attr, &amp;quot;:&amp;quot;, type(getattr(obj, attr)), &amp;quot;:&amp;quot;, getattr(obj, attr)&lt;br /&gt;
    print &amp;quot;END ---&amp;gt;&amp;gt;&amp;gt;&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Curses ===&lt;br /&gt;
&lt;br /&gt;
Curses Programming with Python — Python v3.3.2 documentation - http://docs.python.org/3/howto/curses.html&lt;br /&gt;
&lt;br /&gt;
&amp;quot;The curses library supplies a terminal-independent screen-painting and keyboard-handling facility for text-based terminals; such terminals include VT100s, the Linux console, and the simulated terminal provided by various programs. Display terminals support various control codes to perform common operations such as moving the cursor, scrolling the screen, and erasing areas. Different terminals use widely differing codes, and often have their own minor quirks.&lt;br /&gt;
&lt;br /&gt;
In a world of graphical displays, one might ask “why bother”? It’s true that character-cell display terminals are an obsolete technology, but there are niches in which being able to do fancy things with them are still valuable. One niche is on small-footprint or embedded Unixes that don’t run an X server. Another is tools such as OS installers and kernel configurators that may have to run before any graphical support is available.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
Thread from Utah Python User&#039;s Group mailing list:&lt;br /&gt;
&lt;br /&gt;
-&lt;br /&gt;
&lt;br /&gt;
Hello, I am trying to learn more about curses in python for a desktop application. Does anybody have any recommendations on tutorials or documentation? &lt;br /&gt;
&lt;br /&gt;
-Corban&lt;br /&gt;
&lt;br /&gt;
-&lt;br /&gt;
&lt;br /&gt;
We&#039;ve use urwid at work. Seems to be a good approach if you aren&#039;t already tied to something. Learning curve can be a bit steep (well, compared to what you&#039;d think it should be). Good luck!&lt;br /&gt;
&lt;br /&gt;
 http://excess.org/urwid/&lt;br /&gt;
&lt;br /&gt;
Gabriel Gunderson&lt;br /&gt;
&lt;br /&gt;
-&lt;br /&gt;
&lt;br /&gt;
This video series looks pretty good:&lt;br /&gt;
&lt;br /&gt;
http://www.youtube.com/user/pythoncursestutorial?feature=watch&lt;br /&gt;
&lt;br /&gt;
Official HOWTOs from the python.org site:&lt;br /&gt;
&lt;br /&gt;
http://docs.python.org/2/howto/curses.html&lt;br /&gt;
http://docs.python.org/3/howto/curses.html&lt;br /&gt;
&lt;br /&gt;
As Gabe mentioned, there are other libraries that provide similar or&lt;br /&gt;
greater functionality, so if you aren&#039;t doing this specifically to&lt;br /&gt;
learn curses, it&#039;s worth at least looking at a few of them to compare.&lt;br /&gt;
&lt;br /&gt;
There&#039;s a brief comparison of three possibilities here:&lt;br /&gt;
&lt;br /&gt;
http://stackoverflow.com/questions/8349085/python-ncurses-cdk-urwid-difference&lt;br /&gt;
&lt;br /&gt;
Daniel Fackrell&lt;br /&gt;
&lt;br /&gt;
-&lt;br /&gt;
&lt;br /&gt;
Here&#039;s another option that looks promising:&lt;br /&gt;
&lt;br /&gt;
https://pypi.python.org/pypi/blessings/&lt;br /&gt;
&lt;br /&gt;
Daniel Fackrell&lt;br /&gt;
&lt;br /&gt;
=== dialog ===&lt;br /&gt;
&lt;br /&gt;
pythondialog - http://pythondialog.sourceforge.net/&lt;br /&gt;
: &amp;quot;pythondialog is a Python wrapper for the dialog utility originally written by Savio Lam, and later rewritten by Thomas E. Dickey. Its purpose is to provide an easy to use, pythonic and comprehensive Python interface to dialog. This allows one to make simple text-mode user interfaces on Unix-like systems (including Linux). &amp;quot;&lt;br /&gt;
&lt;br /&gt;
Note: The latest versions (2.12 and later) only support Python 3; users who really want to stick to Python 2 should use version 2.11 for now.&lt;br /&gt;
&lt;br /&gt;
Install:&lt;br /&gt;
 # latest:&lt;br /&gt;
 # wget http://sourceforge.net/projects/pythondialog/files/latest/download?source=dlp&lt;br /&gt;
&lt;br /&gt;
 wget http://sourceforge.net/projects/pythondialog/files/pythondialog/2.11/python2-pythondialog-2.11.tar.gz/download&lt;br /&gt;
 tar -zvxf python2-pythondialog-2.11.tar.gz&lt;br /&gt;
 cd pythondialog-2.11&lt;br /&gt;
&lt;br /&gt;
 import dialog&lt;br /&gt;
 d = dialog.Dialog()&lt;br /&gt;
 if d.yesno(&amp;quot;Continue?&amp;quot;) == d.DIALOG_OK:&lt;br /&gt;
  print &amp;quot;Continuing...&amp;quot;&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
My solution&lt;br /&gt;
&lt;br /&gt;
kiloforce / dialog / source / — Bitbucket - https://bitbucket.org/kiloforce/dialog&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot; Wrapper for Linux &#039;dialog&#039; command &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
__author__ = &amp;quot;Kenneth Burgener &amp;lt;kenneth@k.ttak.org&amp;gt;&amp;quot;&lt;br /&gt;
__copyright__ = &amp;quot;(c) 2013&amp;quot;&lt;br /&gt;
__date__ = &amp;quot;$Sep 27, 2013$&amp;quot;&lt;br /&gt;
__version__ = &amp;quot;1.0&amp;quot;&lt;br /&gt;
__credits__ = r&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
XXXXXXXXXXXXXXXXXX&lt;br /&gt;
X Dialog Wrapper #&lt;br /&gt;
##################&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
import subprocess&lt;br /&gt;
import time&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
class Dialog():&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot; Python wrapper for Linux &#039;dialog&#039; command&lt;br /&gt;
&lt;br /&gt;
    dialog - display dialog boxes from shell scripts&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import dialog&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dlg = dialog.Dialog()&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; rc = dlg.msgbox(&#039;hello world&#039;)&lt;br /&gt;
&lt;br /&gt;
    Return codes:&lt;br /&gt;
        YES = 0&lt;br /&gt;
        OK = 0&lt;br /&gt;
        EXIT = 0&lt;br /&gt;
        NO = 1&lt;br /&gt;
        CANCEL = 1&lt;br /&gt;
        ESC = 255&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    YES = 0&lt;br /&gt;
    OK = 0&lt;br /&gt;
    EXIT = 0&lt;br /&gt;
    NO = 1&lt;br /&gt;
    CANCEL = 1&lt;br /&gt;
    ESC = 255&lt;br /&gt;
&lt;br /&gt;
    def __init__(self):&lt;br /&gt;
        rc = self._exe(&#039;which dialog &amp;gt; /dev/null&#039;)[0]&lt;br /&gt;
        if rc != 0:&lt;br /&gt;
            print &amp;quot;Error: failed to find Linux dialog command&amp;quot;&lt;br /&gt;
            sys.exit(1)&lt;br /&gt;
&lt;br /&gt;
    def _exe(self, cmd, strip=True):&lt;br /&gt;
        p = subprocess.Popen(cmd, shell=True, stderr=subprocess.PIPE)&lt;br /&gt;
        output = &amp;quot;\n&amp;quot;.join(p.stderr.readlines())&lt;br /&gt;
        if strip:&lt;br /&gt;
            output = output.strip()&lt;br /&gt;
        rc = p.wait()&lt;br /&gt;
        return (rc, output)&lt;br /&gt;
&lt;br /&gt;
    def rc_to_str(self, rc):&lt;br /&gt;
        if rc == 0:&lt;br /&gt;
            return &amp;quot;YES&amp;quot;&lt;br /&gt;
        elif rc == 1:&lt;br /&gt;
            return &amp;quot;NO&amp;quot;&lt;br /&gt;
        elif rc == 255:&lt;br /&gt;
            return &amp;quot;ESX&amp;quot;&lt;br /&gt;
        else:&lt;br /&gt;
            raise Exception(&amp;quot;Unknown return code: %s&amp;quot; % rc)&lt;br /&gt;
&lt;br /&gt;
    def clear(self):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Clear screen&lt;br /&gt;
&lt;br /&gt;
        Example:&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt; dialog.clear()&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        rc, output = self._exe(&#039;clear&#039;)&lt;br /&gt;
        assert rc in (0,), &amp;quot;clear rc&amp;quot;&lt;br /&gt;
        return rc&lt;br /&gt;
&lt;br /&gt;
    def msgbox(self, msg):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Simple message box&lt;br /&gt;
&lt;br /&gt;
        @param msg (str) = display message&lt;br /&gt;
        @return: rc (int)&lt;br /&gt;
&lt;br /&gt;
        Example:&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt; rc = dialog.msgbox(&#039;hello world&#039;)&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        rc, output = self._exe(&#039;dialog --msgbox &amp;quot;{msg}&amp;quot; 0 0&#039;.format(msg=msg))&lt;br /&gt;
        assert rc in (self.YES, self.ESC), &amp;quot;msgbox rc&amp;quot;&lt;br /&gt;
        return rc&lt;br /&gt;
&lt;br /&gt;
    def yesno(self, msg):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Yes/No dialog&lt;br /&gt;
&lt;br /&gt;
        @param msg (str) = display message&lt;br /&gt;
        @return: rc (int)&lt;br /&gt;
&lt;br /&gt;
        Example:&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt; rc = dialog.yesno(&#039;continue&#039;)&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        rc, output = self._exe(&#039;dialog --yesno &amp;quot;{msg}&amp;quot; 0 0&#039;.format(msg=msg))&lt;br /&gt;
        assert rc in (self.YES, self.NO, self.ESC), &amp;quot;yesno rc&amp;quot;&lt;br /&gt;
        return rc&lt;br /&gt;
&lt;br /&gt;
    def infobox(self, msg):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Dialog that does not wait for user&#039;s response&lt;br /&gt;
        (do your own pause)&lt;br /&gt;
&lt;br /&gt;
        @param msg (str) = display message&lt;br /&gt;
        @return: rc (int) always zero&lt;br /&gt;
&lt;br /&gt;
        Example:&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt; for i in range(10):&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt;   dialog.infobox(&#039;counting: &#039; + str(i))&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt;   time.sleep(3)&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        rc, output = self._exe(&#039;dialog --infobox &amp;quot;{msg}&amp;quot; 0 0&#039;.format(msg=msg))&lt;br /&gt;
        assert rc in (self.YES,), &amp;quot;infobox rc&amp;quot;&lt;br /&gt;
        return rc&lt;br /&gt;
&lt;br /&gt;
    def inputbox(self, msg):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Get user input&lt;br /&gt;
&lt;br /&gt;
        @param msg (str) = display message&lt;br /&gt;
        @return: rc (int), output (str/None)&lt;br /&gt;
&lt;br /&gt;
        Example:&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt; rc, output = dialog.inputbox(&#039;name:&#039;)&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        rc, output = self._exe(&#039;dialog --inputbox &amp;quot;{msg}&amp;quot; 0 0&#039;.format(msg=msg))&lt;br /&gt;
        assert rc in (self.YES, self.NO, self.ESC), &amp;quot;inputbox rc&amp;quot;&lt;br /&gt;
        if not output:&lt;br /&gt;
            output = None&lt;br /&gt;
        return rc, output&lt;br /&gt;
&lt;br /&gt;
    def textbox(self, filename):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Display a file&lt;br /&gt;
&lt;br /&gt;
        @param filename (str) = file to display&lt;br /&gt;
        @return: rc (int)&lt;br /&gt;
&lt;br /&gt;
        Example:&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt; dialog.textbox(&#039;/etc/passwd&#039;)&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        rc, output = self._exe(&#039;dialog --textbox {filename} 0 0&#039;.format(filename=filename))&lt;br /&gt;
        assert rc in (self.YES, self.ESC), &amp;quot;textbox rc&amp;quot;&lt;br /&gt;
        return rc&lt;br /&gt;
&lt;br /&gt;
    def menu(self, msg, item_list):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Single selection checkbox menu&lt;br /&gt;
&lt;br /&gt;
        @param msg (str) = display message&lt;br /&gt;
        @param item_list (str list) = list of items to display&lt;br /&gt;
        @return: rc (int), selection (int/None)&lt;br /&gt;
&lt;br /&gt;
        Example:&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt; rc, selection = dialog.menu(&#039;Select multiple options:&#039;,&lt;br /&gt;
        ...     (&#039;option 1&#039;, &#039;option 2&#039;))&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        item_str = &amp;quot;&amp;quot;&lt;br /&gt;
        for i in range(len(item_list)):&lt;br /&gt;
            item_str += &amp;quot; &amp;quot; + str(i+1) + &amp;quot; \&amp;quot;&amp;quot; + item_list[i] + &amp;quot;\&amp;quot;&amp;quot;&lt;br /&gt;
        rc, output = self._exe(&#039;dialog --menu &amp;quot;{msg}&amp;quot; 0 0 0 {item_str}&#039;.format(msg=msg, item_str=item_str))&lt;br /&gt;
        if output:&lt;br /&gt;
            selection = int(output)&lt;br /&gt;
        else:&lt;br /&gt;
            selection = None&lt;br /&gt;
        assert rc in (self.YES, self.NO, self.ESC), &amp;quot;menu rc&amp;quot;&lt;br /&gt;
        return rc, selection&lt;br /&gt;
&lt;br /&gt;
    def checklist(self, msg, item_list, checked_list=None):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Multiple selection checkbox menu&lt;br /&gt;
&lt;br /&gt;
        @param msg (str) = display message&lt;br /&gt;
        @param item_list (str list) = list of items&lt;br /&gt;
        @param checked_list (int list) = default items to check&lt;br /&gt;
        @return: rc (int), selections (int list/None)&lt;br /&gt;
&lt;br /&gt;
        Example:&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt; rc, selections = dialog.checklist(&#039;Select multiple options:&#039;,&lt;br /&gt;
        ...     (&#039;option 1&#039;, &#039;option 2&#039;)&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        item_str = &amp;quot;&amp;quot;&lt;br /&gt;
        assert type(item_list) in (type(None), type(()), type([])), &amp;quot;checklist: item_list must be a list&amp;quot;&lt;br /&gt;
        assert type(checked_list) in (type(None), type(()), type([])), &amp;quot;checklist: checked_list must be a list&amp;quot;&lt;br /&gt;
        for i in range(len(item_list)):&lt;br /&gt;
            item_str += &amp;quot; &amp;quot; + str(i+1) + &amp;quot; \&amp;quot;&amp;quot; + item_list[i] + &amp;quot;\&amp;quot;&amp;quot;&lt;br /&gt;
            if checked_list and i+1 in checked_list:&lt;br /&gt;
                item_str += &amp;quot; on&amp;quot;&lt;br /&gt;
            else:&lt;br /&gt;
                item_str += &amp;quot; off&amp;quot;&lt;br /&gt;
        rc, output = self._exe(&#039;dialog --checklist &amp;quot;{msg}&amp;quot; 0 0 0 {item_str}&#039;.format(msg=msg, item_str=item_str))&lt;br /&gt;
        print item_str&lt;br /&gt;
        selections = []&lt;br /&gt;
        for choice in output.split(&#039;&amp;quot;&#039;):&lt;br /&gt;
            if choice.strip():&lt;br /&gt;
                selections.append(int(choice))&lt;br /&gt;
        if selections:&lt;br /&gt;
            selections = tuple(selections)&lt;br /&gt;
        else:&lt;br /&gt;
            selections = None&lt;br /&gt;
        assert rc in (self.YES, self.NO, self.ESC), &amp;quot;checklist rc&amp;quot;&lt;br /&gt;
        return rc, selections&lt;br /&gt;
&lt;br /&gt;
    def radiolist(self, msg, item_list, checked_item=None):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Single selection radio menu, with default&lt;br /&gt;
&lt;br /&gt;
        @param msg (str) = display message&lt;br /&gt;
        @param item_list (str list) = list of items&lt;br /&gt;
        @param checked_item (int) = default item to select&lt;br /&gt;
        @return: rc (int), selection (int)&lt;br /&gt;
&lt;br /&gt;
        Example:&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt; rc, selection = dialog.radiolist(&#039;Select one option:&#039;,&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt;     (&#039;option 1&#039;, &#039;option 2&#039;), 2)&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        item_str = &amp;quot;&amp;quot;&lt;br /&gt;
        for i in range(len(item_list)):&lt;br /&gt;
            item_str += &amp;quot; &amp;quot; + str(i+1) + &amp;quot; \&amp;quot;&amp;quot; + item_list[i] + &amp;quot;\&amp;quot;&amp;quot;&lt;br /&gt;
            if checked_item and i+1 == int(checked_item):&lt;br /&gt;
                item_str += &amp;quot; on&amp;quot;&lt;br /&gt;
            else:&lt;br /&gt;
                item_str += &amp;quot; off&amp;quot;&lt;br /&gt;
        rc, selection = self._exe(&#039;dialog --radiolist &amp;quot;{msg}&amp;quot; 0 0 0 {item_str}&#039;.format(msg=msg, item_str=item_str))&lt;br /&gt;
        if not selection:&lt;br /&gt;
            selection = None&lt;br /&gt;
        assert rc in (self.YES, self.NO, self.ESC), &amp;quot;radiolist rc&amp;quot;&lt;br /&gt;
        return rc, selection&lt;br /&gt;
&lt;br /&gt;
    def gauge(self, msg, percent):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Progress bar (does not wait for user&#039;s input)&lt;br /&gt;
&lt;br /&gt;
        @param msg (str) = display message&lt;br /&gt;
        @param percent (int) = progress&lt;br /&gt;
        @return: rc (int) always zero&lt;br /&gt;
&lt;br /&gt;
        Example:&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt; for i in range(0, 100+1, 2):&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt;   dialog.gauge(&#039;Progress:&#039;, i)&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt;   time.sleep(.1)&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        rc, output = self._exe(&#039;echo {percent} | dialog --gauge &amp;quot;{msg}&amp;quot; 0 0&#039;.format(percent=percent, msg=msg))&lt;br /&gt;
        assert rc in (self.YES,), &amp;quot;guage rc&amp;quot;&lt;br /&gt;
        return rc&lt;br /&gt;
&lt;br /&gt;
    def progress(self, msg, percent):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Alias for self.guage()&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        return self.gauge(msg=msg, percent=percent)&lt;br /&gt;
&lt;br /&gt;
    def form(self, msg, item_list):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Multiple item entry form&lt;br /&gt;
&lt;br /&gt;
        @param msg (str) = display message&lt;br /&gt;
        @param item_list (str list) = list of items&lt;br /&gt;
        @return: rc (int), answers (str list)&lt;br /&gt;
&lt;br /&gt;
        Example:&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt; rc, answers = dialog.form(&#039;Enter details&#039;,&lt;br /&gt;
        ...     (&#039;first name&#039;, &#039;last name&#039;))&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        item_str = &amp;quot;&amp;quot;&lt;br /&gt;
        name_len = 1&lt;br /&gt;
        for i in range(len(item_list)):&lt;br /&gt;
            if len(item_list[i])+3 &amp;gt; name_len:&lt;br /&gt;
                name_len = len(item_list[i])+3&lt;br /&gt;
        for i in range(len(item_list)):&lt;br /&gt;
            item_str += &amp;quot; \&amp;quot;&amp;quot; + item_list[i] + &amp;quot;:\&amp;quot; &amp;quot; + str(i+1) + &amp;quot; 1 \&amp;quot;\&amp;quot; &amp;quot; + str(i+1) +\&lt;br /&gt;
                &amp;quot; &amp;quot; + str(name_len) + &amp;quot; 40 0&amp;quot;&lt;br /&gt;
        rc, answers = self._exe(&#039;dialog --form &amp;quot;{msg}&amp;quot; 0 0 0 {item_str}&#039;.format(msg=msg, item_str=item_str),&lt;br /&gt;
                                strip=False)&lt;br /&gt;
        answers = answers.split(&#039;\n\n&#039;)&lt;br /&gt;
        if not answers:&lt;br /&gt;
            answers = None&lt;br /&gt;
        assert rc in (self.YES, self.NO, self.ESC), &amp;quot;form rc&amp;quot;&lt;br /&gt;
        return rc, answers&lt;br /&gt;
&lt;br /&gt;
    def test(self):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Test features&lt;br /&gt;
&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt; import dialog&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt; dlg = dialog.Dialog()&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt; dlg.test()&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
        def wait_user(msg):&lt;br /&gt;
            self.msgbox(&amp;quot;%s&amp;quot; % msg)&lt;br /&gt;
&lt;br /&gt;
        # rc_to_str&lt;br /&gt;
        wait_user(&amp;quot;Testing return code...&amp;quot;)&lt;br /&gt;
        print self.rc_to_str(self.YES)  # YES&lt;br /&gt;
        print self.rc_to_str(self.NO)  # NO&lt;br /&gt;
        print self.rc_to_str(self.ESC)  # ESX&lt;br /&gt;
        try:&lt;br /&gt;
            print self.rc_to_str(111)  # exception&lt;br /&gt;
            raise Exception(&amp;quot;Did not throw exception&amp;quot;)&lt;br /&gt;
        except Exception as rc:&lt;br /&gt;
            pass&lt;br /&gt;
&lt;br /&gt;
        # msgbox&lt;br /&gt;
        wait_user(&amp;quot;Testing msgbox...&amp;quot;)&lt;br /&gt;
        rc = self.msgbox(&amp;quot;msgbox&amp;quot;)&lt;br /&gt;
        if rc not in (self.YES, self.ESC):&lt;br /&gt;
            raise Exception(&amp;quot;Unknown return code for msgbox: %s&amp;quot; % rc)&lt;br /&gt;
&lt;br /&gt;
        # yesno&lt;br /&gt;
        wait_user(&amp;quot;Testing yesno...&amp;quot;)&lt;br /&gt;
        rc = self.yesno(&amp;quot;yesno&amp;quot;)&lt;br /&gt;
        if rc not in (self.YES, self.NO, self.ESC):&lt;br /&gt;
            raise Exception(&amp;quot;Unknown return code for yesno: %s&amp;quot; % rc)&lt;br /&gt;
&lt;br /&gt;
        # infobox&lt;br /&gt;
        wait_user(&amp;quot;Testing infobox...&amp;quot;)&lt;br /&gt;
        rc = self.infobox(&amp;quot;infobox sleep 1 sec&amp;quot;)&lt;br /&gt;
        if rc not in (self.YES,):&lt;br /&gt;
            raise Exception(&amp;quot;Unknown return code for infobox %s&amp;quot; % rc)&lt;br /&gt;
        time.sleep(1)&lt;br /&gt;
&lt;br /&gt;
        # inputbox&lt;br /&gt;
        wait_user(&amp;quot;Testing inputbox...&amp;quot;)&lt;br /&gt;
        rc, output = self.inputbox(&amp;quot;inputbox&amp;quot;)&lt;br /&gt;
        if rc not in (self.YES, self.NO, self.ESC):&lt;br /&gt;
            raise Exception(&amp;quot;Unknown return code for inputbox: %s&amp;quot; % rc)&lt;br /&gt;
        wait_user(&amp;quot;Result: %s&amp;quot; % output)&lt;br /&gt;
&lt;br /&gt;
        # textbox&lt;br /&gt;
        wait_user(&amp;quot;Testing textbox...&amp;quot;)&lt;br /&gt;
        rc = self.textbox(&amp;quot;/etc/passwd&amp;quot;)&lt;br /&gt;
        if rc not in (self.YES, self.ESC):&lt;br /&gt;
            raise Exception(&amp;quot;Unknown return code for textbox: %s&amp;quot; % rc)&lt;br /&gt;
&lt;br /&gt;
        # menu&lt;br /&gt;
        wait_user(&amp;quot;Testing menu...&amp;quot;)&lt;br /&gt;
        rc, selection = self.menu(&amp;quot;menu&amp;quot;, (&amp;quot;option 1&amp;quot;, &amp;quot;option 2&amp;quot;))&lt;br /&gt;
        if rc not in (self.YES, self.NO, self.ESC):&lt;br /&gt;
            raise Exception(&amp;quot;Unknown return code for menu: %s&amp;quot; % rc)&lt;br /&gt;
        wait_user(&amp;quot;Result: %s&amp;quot; % selection)&lt;br /&gt;
&lt;br /&gt;
        # checklist&lt;br /&gt;
        wait_user(&amp;quot;Testing checklist...&amp;quot;)&lt;br /&gt;
        rc, selection = self.checklist(&amp;quot;menu&amp;quot;, [&amp;quot;option 1&amp;quot;, &amp;quot;option 2&amp;quot;])&lt;br /&gt;
        if rc not in (self.YES, self.NO, self.ESC):&lt;br /&gt;
            raise Exception(&amp;quot;Unknown return code for checklist: %s&amp;quot; % rc)&lt;br /&gt;
        wait_user(&amp;quot;Result: %s&amp;quot; % str(selection))&lt;br /&gt;
        wait_user(&amp;quot;Testing checklist with default selection...&amp;quot;)&lt;br /&gt;
        rc, selection = self.checklist(&amp;quot;menu&amp;quot;, [&amp;quot;option 1&amp;quot;, &amp;quot;option 2&amp;quot;], [1, 2])&lt;br /&gt;
        if rc not in (self.YES, self.NO, self.ESC):&lt;br /&gt;
            raise Exception(&amp;quot;Unknown return code for checklist: %s&amp;quot; % rc)&lt;br /&gt;
        wait_user(&amp;quot;Result: %s&amp;quot; % str(selection))&lt;br /&gt;
&lt;br /&gt;
        # radiolist&lt;br /&gt;
        wait_user(&amp;quot;Testing radiolist...&amp;quot;)&lt;br /&gt;
        rc, selection = self.radiolist(&amp;quot;menu&amp;quot;, [&amp;quot;option 1&amp;quot;, &amp;quot;option 2&amp;quot;])&lt;br /&gt;
        if rc not in (self.YES, self.NO, self.ESC):&lt;br /&gt;
            raise Exception(&amp;quot;Unknown return code for radiolist: %s&amp;quot; % rc)&lt;br /&gt;
        wait_user(&amp;quot;Result: %s&amp;quot; % str(selection))&lt;br /&gt;
        wait_user(&amp;quot;Testing radiolist with default selection...&amp;quot;)&lt;br /&gt;
        rc, selection = self.radiolist(&amp;quot;menu&amp;quot;, [&amp;quot;option 1&amp;quot;, &amp;quot;option 2&amp;quot;], 2)&lt;br /&gt;
        if rc not in (self.YES, self.NO, self.ESC):&lt;br /&gt;
            raise Exception(&amp;quot;Unknown return code for radiolist: %s&amp;quot; % rc)&lt;br /&gt;
        wait_user(&amp;quot;Result: %s&amp;quot; % str(selection))&lt;br /&gt;
&lt;br /&gt;
        # guage&lt;br /&gt;
        wait_user(&amp;quot;Testing guage...&amp;quot;)&lt;br /&gt;
        for i in range(4+1):&lt;br /&gt;
            rc = self.gauge(&amp;quot;test guage&amp;quot;, i*25)&lt;br /&gt;
            # rc = self.progress(&amp;quot;test progress&amp;quot;, i*25)&lt;br /&gt;
            if rc not in (self.YES,):&lt;br /&gt;
                raise Exception(&amp;quot;Unknown return code for guage: %s&amp;quot; % rc)&lt;br /&gt;
            time.sleep(1)&lt;br /&gt;
&lt;br /&gt;
        # form&lt;br /&gt;
        wait_user(&amp;quot;Testing form...&amp;quot;)&lt;br /&gt;
        rc, answers = self.form(&amp;quot;form&amp;quot;, [&amp;quot;option 1&amp;quot;, &amp;quot;option 2&amp;quot;])&lt;br /&gt;
        if rc not in (self.YES, self.NO, self.ESC):&lt;br /&gt;
            raise Exception(&amp;quot;Unknown return code for form: %s&amp;quot; % rc)&lt;br /&gt;
        wait_user(&amp;quot;Result: %s&amp;quot; % str(answers))&lt;br /&gt;
&lt;br /&gt;
        # done with test, cleanup&lt;br /&gt;
        wait_user(&amp;quot;Done with tests...&amp;quot;)&lt;br /&gt;
        self.clear()&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
    # dialog = Dialog()&lt;br /&gt;
    # dialog.test()&lt;br /&gt;
    pass&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Busy Loop and Thread.yield() ===&lt;br /&gt;
&lt;br /&gt;
&amp;quot;I want to tell my Python threads to yield, and so avoid hogging the CPU unnecessarily. In Java, you could do that using the Thread.yield() function&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Solution:&lt;br /&gt;
 time.sleep(0)&lt;br /&gt;
 time.sleep(0.00001)&lt;br /&gt;
 time.sleep(epsilon)&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* multithreading - In there something similar to Java&#039;s Thread.yield() in Python? Does that even make sense? - Stack Overflow - http://stackoverflow.com/questions/1908206/in-there-something-similar-to-javas-thread-yield-in-python-does-that-even-ma&lt;br /&gt;
* multithreading - How does a threading.Thread yield the rest of its quantum in Python? - Stack Overflow - http://stackoverflow.com/questions/787803/how-does-a-threading-thread-yield-the-rest-of-its-quantum-in-python&lt;br /&gt;
&lt;br /&gt;
=== USB ===&lt;br /&gt;
&lt;br /&gt;
Programming with PyUSB 1.0 - http://pyusb.sourceforge.net/docs/1.0/tutorial.html&lt;br /&gt;
&lt;br /&gt;
PyUSB - http://pyusb.sourceforge.net/&lt;br /&gt;
&lt;br /&gt;
 git clone https://github.com/walac/pyusb&lt;br /&gt;
&lt;br /&gt;
 import usb.core&lt;br /&gt;
 dev = usb.core.find()&lt;br /&gt;
&lt;br /&gt;
 # find our device&lt;br /&gt;
 dev = usb.core.find(idVendor=0xfffe, idProduct=0x0001)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&#039;&#039;&#039;Dealing with multiple identical devices&#039;&#039;&#039; - Sometimes you may have two identical devices connected to the computer. How can you differentiate them? Device objects come with two additional attributes which are not part of the USB Spec, but are very useful: bus and address attributes. First of all, it is worth to say that these attributes come from the backend and a backend is free to not support them, in which case they are set to None. That said, these attributes represent the bus number and bus address of the device and, as you might already have imagined, can be used to differentiate two devices with the same idVendor and idProduct attributes.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Tkinter ===&lt;br /&gt;
&lt;br /&gt;
Python GUI Bitcoin: [http://bitcoin.stackexchange.com/questions/10594/simplest-way-of-obtaining-mtgox-exchange-rate-via-an-api]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import json&lt;br /&gt;
import urllib2&lt;br /&gt;
from Tkinter import *&lt;br /&gt;
&lt;br /&gt;
url=&#039;http://api.bitcoincharts.com/v1/markets.json&#039;&lt;br /&gt;
req=urllib2.Request(url)&lt;br /&gt;
response=urllib2.urlopen(req).read()&lt;br /&gt;
output=json.loads(response)&lt;br /&gt;
&lt;br /&gt;
mtusd_price = output[-10][&#039;avg&#039;]&lt;br /&gt;
mteur_price = output[31][&#039;avg&#039;]&lt;br /&gt;
mtgbp_price = output[44][&#039;avg&#039;]&lt;br /&gt;
&lt;br /&gt;
MTUSD= &#039;USD&#039; + &#039; &#039; + str(mtusd_price)&lt;br /&gt;
MTEUR= &#039;EUR&#039; + &#039; &#039; + str(mteur_price)&lt;br /&gt;
MTGBP = &#039;GBP&#039; + &#039; &#039; + str(mtgbp_price)&lt;br /&gt;
&lt;br /&gt;
root= Tk()&lt;br /&gt;
root.title(&amp;quot;Bitcoin Price&amp;quot;)&lt;br /&gt;
root.geometry(&amp;quot;250x100&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
USD = Label(root, text=MTUSD)&lt;br /&gt;
EUR = Label(root, text=MTEUR)&lt;br /&gt;
GBP = Label(root, text=MTGBP)&lt;br /&gt;
USD.pack()&lt;br /&gt;
EUR.pack()&lt;br /&gt;
GBP.pack()&lt;br /&gt;
mainloop()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== ctypes ===&lt;br /&gt;
&lt;br /&gt;
&amp;quot;ctypes is a foreign function library for Python. It provides C compatible data types, and allows calling functions in DLLs or shared libraries. It can be used to wrap these libraries in pure Python.&amp;quot;&lt;br /&gt;
:-- 15.17. ctypes — A foreign function library for Python — Python v2.7.7 documentation - https://docs.python.org/2/library/ctypes.html&lt;br /&gt;
&lt;br /&gt;
Use &amp;quot;c scope&amp;quot; to build a database of symbols to see what options are available.&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
testlib.c&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void myprint(void);&lt;br /&gt;
&lt;br /&gt;
void myprint()&lt;br /&gt;
{&lt;br /&gt;
    printf(&amp;quot;hello world\n&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Compile:&lt;br /&gt;
 gcc -shared -Wl,-soname,testlib -o testlib.so -fPIC testlib.c&lt;br /&gt;
&lt;br /&gt;
testlibwrapper.py&lt;br /&gt;
&lt;br /&gt;
Python:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import ctypes&lt;br /&gt;
&lt;br /&gt;
testlib = ctypes.CDLL(&#039;/full/path/to/testlib.so&#039;)&lt;br /&gt;
testlib.myprint()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Source: python - ctypes - Beginner - Stack Overflow - http://stackoverflow.com/questions/5081875/ctypes-beginner&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
nzjrs&#039;s Gists - https://gist.github.com/nzjrs&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int sum(double *x,int n)&lt;br /&gt;
{&lt;br /&gt;
  int i;&lt;br /&gt;
  double counter;&lt;br /&gt;
  counter = 0;&lt;br /&gt;
  for(i=0;i&amp;lt;n;i++)&lt;br /&gt;
    {&lt;br /&gt;
      counter=counter+x[i];&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
  return counter;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -c sum.c&lt;br /&gt;
gcc -shared -o sum.so sum.o&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from ctypes import *&lt;br /&gt;
my_sum=CDLL(&#039;sum.so&#039;)&lt;br /&gt;
a=numpy.array(range(10),dtype=float)&lt;br /&gt;
my_sum.sum(a.ctypes.data_as(c_void_p),int(10))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
a=(c_double*10)()&lt;br /&gt;
for i in range(10):&lt;br /&gt;
   a[i]=i&lt;br /&gt;
my_sum.sum(a,int(10))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Source: Ctypes — Numerical Computing with Sage v6.2 - http://www.sagemath.org/doc/numerical_sage/ctypes.html&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
=== Warnings ===&lt;br /&gt;
&lt;br /&gt;
 if sys.version_info &amp;gt;= (1, 0, 0):&lt;br /&gt;
   warnings.warn(&amp;quot;Danger Will Robinson: trying Phi on untested Python 3.0!&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
=== enum ===&lt;br /&gt;
&lt;br /&gt;
Python 3: https://docs.python.org/3/library/enum.html&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from enum import Enum&lt;br /&gt;
&lt;br /&gt;
# class syntax&lt;br /&gt;
class Color(Enum):&lt;br /&gt;
    RED = 1&lt;br /&gt;
    GREEN = 2&lt;br /&gt;
    BLUE = 3&lt;br /&gt;
&lt;br /&gt;
# functional syntax&lt;br /&gt;
Color = Enum(&#039;Color&#039;, [&#039;RED&#039;, &#039;GREEN&#039;, &#039;BLUE&#039;])&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
Python 2: [http://stackoverflow.com/questions/36932/how-can-i-represent-an-enum-in-python]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Enum(set):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot; Basic enumerated type&lt;br /&gt;
    &lt;br /&gt;
    Example&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt; Animals = phi.Enum([&amp;quot;DOG&amp;quot;, &amp;quot;CAT&amp;quot;, &amp;quot;HORSE&amp;quot;])&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt; Animals.DOG&lt;br /&gt;
        &#039;DOG&#039;&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt; &#039;HORSE&#039; in Animals&lt;br /&gt;
        True&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    def __getattr__(self, name):&lt;br /&gt;
        if name in self:&lt;br /&gt;
            return name&lt;br /&gt;
        raise AttributeError(&amp;quot;Missing Enum property: %s&amp;quot; % name)&lt;br /&gt;
    def __setattr__(self, name, value):  # this makes it read-only&lt;br /&gt;
        raise AttributeError(&amp;quot;Unable to modify Enum property: %s (%s)&amp;quot; % (name, value))&lt;br /&gt;
&lt;br /&gt;
Animals = Enum([&amp;quot;DOG&amp;quot;, &amp;quot;CAT&amp;quot;, &amp;quot;HORSE&amp;quot;])&lt;br /&gt;
&lt;br /&gt;
print(Animals.DOG)  # &#039;DOG&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----------&lt;br /&gt;
&lt;br /&gt;
Alternative:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Stationery:&lt;br /&gt;
    Pen, Pencil, Eraser = range(0, 3)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
One liner:&lt;br /&gt;
 class Enum(tuple): __getattr__ = tuple.index&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; State = Enum([&#039;Unclaimed&#039;, &#039;Claimed&#039;])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; State.Claimed&lt;br /&gt;
1&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; State[1]&lt;br /&gt;
&#039;Claimed&#039;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; State&lt;br /&gt;
(&#039;Unclaimed&#039;, &#039;Claimed&#039;)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; range(len(State))&lt;br /&gt;
[0, 1]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; [(k, State[k]) for k in range(len(State))]&lt;br /&gt;
[(0, &#039;Unclaimed&#039;), (1, &#039;Claimed&#039;)]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; [(k, getattr(State, k)) for k in State]&lt;br /&gt;
[(&#039;Unclaimed&#039;, 0), (&#039;Claimed&#039;, 1)]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Python 3 supports enum natively with the enum.Enum library:&lt;br /&gt;
&lt;br /&gt;
=== pySerial ===&lt;br /&gt;
&lt;br /&gt;
https://pythonhosted.org/pyserial/&lt;br /&gt;
&lt;br /&gt;
&amp;quot;This module encapsulates the access for the serial port. It provides backends for Python running on Windows, OSX, Linux, BSD (possibly any POSIX compliant system) and IronPython. The module named “serial” automatically selects the appropriate backend.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
https://github.com/pyserial/&lt;br /&gt;
&lt;br /&gt;
Intro - https://pythonhosted.org/pyserial/shortintro.html&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import serial&lt;br /&gt;
import time&lt;br /&gt;
&lt;br /&gt;
ser = serial.Serial(&lt;br /&gt;
    port=&#039;COM4&#039;,\&lt;br /&gt;
    baudrate=9600,\&lt;br /&gt;
    parity=serial.PARITY_NONE,\&lt;br /&gt;
    stopbits=serial.STOPBITS_ONE,\&lt;br /&gt;
    bytesize=serial.EIGHTBITS,\&lt;br /&gt;
        timeout=0)&lt;br /&gt;
&lt;br /&gt;
print(&amp;quot;connected to: &amp;quot; + ser.portstr)&lt;br /&gt;
&lt;br /&gt;
#this will store the line&lt;br /&gt;
seq = []&lt;br /&gt;
count = 1&lt;br /&gt;
&lt;br /&gt;
while True:&lt;br /&gt;
    for c in ser.read():&lt;br /&gt;
        seq.append(chr(c)) #convert from ANSII&lt;br /&gt;
        joined_seq = &#039;&#039;.join(str(v) for v in seq) #Make a string from array&lt;br /&gt;
&lt;br /&gt;
        if chr(c) == &#039;\n&#039;:&lt;br /&gt;
            print(&amp;quot;Line &amp;quot; + str(count) + &#039;: &#039; + joined_seq)&lt;br /&gt;
            seq = []&lt;br /&gt;
            count += 1&lt;br /&gt;
            break&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ser.close()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ref: http://stackoverflow.com/questions/16077912/python-serial-how-to-use-the-read-or-readline-function-to-read-more-than-1-char&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
I modified the code to monitor a COM port: (Windows)&lt;br /&gt;
&lt;br /&gt;
Monitor Serial:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import serial, time, sys&lt;br /&gt;
&lt;br /&gt;
logger = open(&amp;quot;serial.txt&amp;quot;, &amp;quot;w&amp;quot;)&lt;br /&gt;
timer = time.time()&lt;br /&gt;
&lt;br /&gt;
def log(msg, head=False):&lt;br /&gt;
    msg = msg.strip()&lt;br /&gt;
    if head:&lt;br /&gt;
      msg = &amp;quot;&amp;gt;&amp;gt;&amp;gt; &amp;quot; + msg&lt;br /&gt;
    logger.write(msg + &amp;quot;\n&amp;quot;)&lt;br /&gt;
    sys.stdout.write(msg + &amp;quot;\n&amp;quot;)&lt;br /&gt;
    newtime = time.time()&lt;br /&gt;
    if newtime &amp;gt; timer + 1:&lt;br /&gt;
        logger.flush()&lt;br /&gt;
        sys.stdout.flush()&lt;br /&gt;
&lt;br /&gt;
while True:&lt;br /&gt;
&lt;br /&gt;
    ser = None&lt;br /&gt;
    try:&lt;br /&gt;
        ser = serial.Serial(&lt;br /&gt;
            port=&#039;COM1&#039;,\&lt;br /&gt;
            baudrate=115200,\&lt;br /&gt;
            parity=serial.PARITY_NONE,\&lt;br /&gt;
            stopbits=serial.STOPBITS_ONE,\&lt;br /&gt;
            bytesize=serial.EIGHTBITS,\&lt;br /&gt;
                timeout=0)&lt;br /&gt;
    except serial.serialutil.SerialException as e:&lt;br /&gt;
        log(str(e), True)&lt;br /&gt;
        time.sleep(1)&lt;br /&gt;
        continue&lt;br /&gt;
&lt;br /&gt;
    log(&amp;quot;Connected to: &amp;quot; + ser.portstr, True)&lt;br /&gt;
    count=1&lt;br /&gt;
&lt;br /&gt;
    try:&lt;br /&gt;
        line = []&lt;br /&gt;
        while True:&lt;br /&gt;
            for c in ser.readline():&lt;br /&gt;
                line.append(c)&lt;br /&gt;
                if c == &amp;quot;\n&amp;quot;:&lt;br /&gt;
                    log(&amp;quot;&amp;quot;.join(line))&lt;br /&gt;
                    line = []&lt;br /&gt;
    except serial.serialutil.SerialException as e:&lt;br /&gt;
        log(str(e), True)&lt;br /&gt;
        time.sleep(1)&lt;br /&gt;
    ser.close()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== MyBool ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; class NewBool(int):&lt;br /&gt;
...    def __new__(cls, value):&lt;br /&gt;
...        return int.__new__(cls, bool(value))&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; y = NewBool(2)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; y == 1&lt;br /&gt;
True&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
https://jfine-python-classes.readthedocs.io/en/latest/subclass-int.html&lt;br /&gt;
&lt;br /&gt;
Also check out the __cmp__&lt;br /&gt;
&lt;br /&gt;
== md5 ==&lt;br /&gt;
&lt;br /&gt;
 import md5&lt;br /&gt;
 md5.new(&amp;quot;Nobody inspects the spammish repetition&amp;quot;).hexdigest()&lt;br /&gt;
 # &#039;bb649c83dd1ea5c9d9dec9a18df0ffe9&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ echo -n &amp;quot;Nobody inspects the spammish repetition&amp;quot; | md5sum&lt;br /&gt;
bb649c83dd1ea5c9d9dec9a18df0ffe9  -&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== External Libraries ==&lt;br /&gt;
&lt;br /&gt;
=== execnet ===&lt;br /&gt;
&lt;br /&gt;
Python Package Index - execnet - https://pypi.python.org/pypi/execnet&lt;br /&gt;
&lt;br /&gt;
Examples - http://codespeak.net/execnet/examples.html&lt;br /&gt;
* basic local and remote communication - http://codespeak.net/execnet/example/test_info.html&lt;br /&gt;
&lt;br /&gt;
Execute source code in subprocess, communicate through a channel:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import execnet&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; gw = execnet.makegateway()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; channel = gw.remote_exec(&amp;quot;channel.send(channel.receive()+1)&amp;quot;)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; channel.send(1)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; channel.receive()&lt;br /&gt;
2&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Compare current working directories&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import execnet, os&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; gw = execnet.makegateway()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; ch = gw.remote_exec(&amp;quot;import os; channel.send(os.getcwd())&amp;quot;)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; res = ch.receive()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; assert res == os.getcwd()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Get information from remote ssh account&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import execnet, os&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; gw = execnet.makegateway(&amp;quot;ssh=codespeak.net&amp;quot;)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; channel = gw.remote_exec(&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
...     import sys, os&lt;br /&gt;
...     channel.send((sys.platform, sys.version_info, os.getpid()))&lt;br /&gt;
... &amp;quot;&amp;quot;&amp;quot;)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; platform, version_info, remote_pid = channel.receive()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; platform&lt;br /&gt;
&#039;linux2&#039;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; version_info&lt;br /&gt;
(2, 4, 2, &#039;final&#039;, 0)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
remote-exec a function (avoiding inlined source part I)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import execnet&lt;br /&gt;
&lt;br /&gt;
def multiplier(channel, factor):&lt;br /&gt;
    while not channel.isclosed():&lt;br /&gt;
        param = channel.receive()&lt;br /&gt;
        channel.send(param * factor)&lt;br /&gt;
&lt;br /&gt;
gw = execnet.makegateway()&lt;br /&gt;
channel = gw.remote_exec(multiplier, factor=10)&lt;br /&gt;
&lt;br /&gt;
for i in range(5):&lt;br /&gt;
    channel.send(i)&lt;br /&gt;
    result = channel.receive()&lt;br /&gt;
    assert result == i * 10&lt;br /&gt;
&lt;br /&gt;
gw.exit()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
remote-exec a module (avoiding inlined source part II)&lt;br /&gt;
:&amp;quot;You can pass a module object to remote_exec in which case its source code will be sent. No dependencies will be transferred so the module must be self-contained or only use modules that are installed on the “other” side. Module code can detect if it is running in a remote_exec situation by checking for the special __name__ attribute.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# content of a module remote1.py&lt;br /&gt;
&lt;br /&gt;
if __name__ == &#039;__channelexec__&#039;:&lt;br /&gt;
    channel.send(&#039;initialization complete&#039;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import execnet, remote1&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; gw = execnet.makegateway()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; ch = gw.remote_exec(remote1)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; print (ch.receive())&lt;br /&gt;
initialization complete&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use a callback instead of receive() and wait for completion&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import execnet&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; gw = execnet.makegateway()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; channel = gw.remote_exec(&amp;quot;for i in range(10): channel.send(i)&amp;quot;)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; l = []&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; channel.setcallback(l.append, endmarker=None)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; channel.waitclose() # waits for closing, i.e. remote exec finish&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; l&lt;br /&gt;
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, None]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
a simple command loop pattern&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# contents of: remotecmd.py&lt;br /&gt;
import os&lt;br /&gt;
&lt;br /&gt;
def simple(arg):&lt;br /&gt;
    return arg + 1&lt;br /&gt;
&lt;br /&gt;
def listdir(path):&lt;br /&gt;
    return os.listdir(path)&lt;br /&gt;
    &lt;br /&gt;
if __name__ == &#039;__channelexec__&#039;:&lt;br /&gt;
    for item in channel:&lt;br /&gt;
        channel.send(eval(item))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import execnet, remotecmd&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; gw = execnet.makegateway()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; ch = gw.remote_exec(remotecmd)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; ch.send(&#039;simple(10)&#039;) # execute func-call remotely&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; ch.receive()&lt;br /&gt;
11&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== evdev ===&lt;br /&gt;
&lt;br /&gt;
Install:&lt;br /&gt;
 apt-get install python-setuptools python-dev&lt;br /&gt;
 easy_install pip&lt;br /&gt;
 pip install evdev&lt;br /&gt;
&lt;br /&gt;
Simple read usage:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from evdev import InputDevice&lt;br /&gt;
from evdev import ecodes&lt;br /&gt;
&lt;br /&gt;
# look for a /dev/input/by-id/usb...kbd or similar&lt;br /&gt;
DEVICE = &amp;quot;/dev/input/by-id/usb-ORTEK_USB_Keyboard_Hub-event-kbd&amp;quot;&lt;br /&gt;
&lt;br /&gt;
dev = InputDevice(DEVICE)&lt;br /&gt;
&lt;br /&gt;
while True:&lt;br /&gt;
    r, w, x = select([dev], [], [], 5)&lt;br /&gt;
    for event in dev.read():&lt;br /&gt;
        if event.type == 1 and event.value == 1:&lt;br /&gt;
            print event.code&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
List LED states:&lt;br /&gt;
 dev.leds()&lt;br /&gt;
 dev.leds(verbose=True)&lt;br /&gt;
&lt;br /&gt;
Inject usage: (does not appear to really work)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from evdev import InputDevice&lt;br /&gt;
from evdev import ecodes&lt;br /&gt;
from evdev import UInput&lt;br /&gt;
&lt;br /&gt;
DEVICE = &amp;quot;/dev/input/by-id/usb-ORTEK_USB_Keyboard_Hub-event-kbd&amp;quot;&lt;br /&gt;
dev = InputDevice(DEVICE)&lt;br /&gt;
&lt;br /&gt;
ui = UInput()&lt;br /&gt;
&lt;br /&gt;
ui.write(ecodes.EV_KEY, ecodes.KEY_4, 1)&lt;br /&gt;
ui.write(ecodes.EV_KEY, ecodes.KEY_4, 0)&lt;br /&gt;
ui.syn()&lt;br /&gt;
&lt;br /&gt;
ui.write(ecodes.EV_KEY, ecodes.KEY_NUMLOCK, 1)&lt;br /&gt;
ui.write(ecodes.EV_KEY, ecodes.KEY_NUMLOCK, 0)&lt;br /&gt;
ui.syn()&lt;br /&gt;
&lt;br /&gt;
ui.close()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Tutorial:&lt;br /&gt;
* evdev documentation — python-evdev 0.4.3 documentation - http://pythonhosted.org/evdev/index.html&lt;br /&gt;
References:&lt;br /&gt;
* python-evdev/doc/tutorial.rst at master · gvalkov/python-evdev · GitHub - https://github.com/gvalkov/python-evdev/blob/master/doc/tutorial.rst&lt;br /&gt;
&lt;br /&gt;
=== ldap-python ===&lt;br /&gt;
&lt;br /&gt;
python-ldap: LDAP client API for Python - http://www.python-ldap.org/&lt;br /&gt;
&lt;br /&gt;
Index of Packages : Python Package Index - https://pypi.python.org/pypi/python-ldap/&lt;br /&gt;
&lt;br /&gt;
 yum install python-devel openldap-devel&lt;br /&gt;
 pip install python-ldap&lt;br /&gt;
&lt;br /&gt;
Articles:&lt;br /&gt;
* Python LDAP Applications: Part 1 - Installing and Configuring the Python-LDAP Library and Binding to an LDAP Directory | Packt Publishing - http://www.packtpub.com/article/installing-and-configuring-the-python-ldap-library-and-binding-to-an-ldap-directory&lt;br /&gt;
&lt;br /&gt;
=== xmmp ===&lt;br /&gt;
&lt;br /&gt;
PDF:&lt;br /&gt;
* XMPP: The Definitive Guide - Oreilly - http://oriolrius.cat/blog/wp-content/uploads/2009/10/Oreilly.XMPP.The.Definitive.Guide.May.2009.pdf&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
xmmp is the Jabber protocol&lt;br /&gt;
&lt;br /&gt;
Best options:&lt;br /&gt;
&lt;br /&gt;
MIT libraries.&lt;br /&gt;
* sleekxmpp (was: sleekxmpp) is pretty popular and is used for examples in Peter Saint-Andre&#039;s XMPP book from O&#039;Reilly. It reportedly works well, and finally got an email list in April 2010, and has a chat room at sleek@conference.jabber.org.&lt;br /&gt;
&lt;br /&gt;
GPL libraries.&lt;br /&gt;
* xmpppy is used by gajim.&lt;br /&gt;
&lt;br /&gt;
LPGL libraries.&lt;br /&gt;
* pyxmpp is pretty good and uses libxml2 internally for xml parsing.&lt;br /&gt;
* pyxmpp2 is the next version of pyxmpp, runs on python 2.7 and 3.2, and removes the libxml2 requirement. Like many, it requires dnspython.&lt;br /&gt;
* jabberpy is the original and still works for a lot of tasks, but is thoroughly unmaintained.&lt;br /&gt;
&lt;br /&gt;
Other libraries.&lt;br /&gt;
* Wokkel, mentioned in another post. That&#039;s a new one for me, based on twisted.&lt;br /&gt;
&lt;br /&gt;
chat - Best python XMPP / Jabber client library? - Stack Overflow - http://stackoverflow.com/questions/1901828/best-python-xmpp-jabber-client-library&lt;br /&gt;
&lt;br /&gt;
=== xmpppy ===&lt;br /&gt;
&lt;br /&gt;
xmpppy: the jabber python project - http://xmpppy.sourceforge.net/&lt;br /&gt;
&lt;br /&gt;
&amp;quot;xmpppy is a Python library that is targeted to provide easy scripting with Jabber. Similar projects are Twisted Words and jabber.py.&lt;br /&gt;
&lt;br /&gt;
This library was not designed from scratch. It inherits some code from jabberpy and have very similar API in many places. Though it is separate project since it have almost completely different architecture and primarily aims to work with jabberd2 - the new Open Source Jabber Server.&lt;br /&gt;
&lt;br /&gt;
xmpppy is distributed under the terms of GNU General Public License and can be freely redistributed without any charge.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 wget http://sourceforge.net/projects/xmpppy/files/xmpppy/0.4.1/xmpppy-0.4.1.tar.gz/download -O xmpppy-0.4.1.tar.gz&lt;br /&gt;
 tar -zvxf xmpppy-0.4.1.tar.gz&lt;br /&gt;
 pip install pydns&lt;br /&gt;
&lt;br /&gt;
--- basic connection ---&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
 &lt;br /&gt;
import xmpp&lt;br /&gt;
 &lt;br /&gt;
user=&amp;quot;username@gmail.com&amp;quot;&lt;br /&gt;
password=&amp;quot;password&amp;quot;&lt;br /&gt;
server=&amp;quot;gmail.com&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
jid = xmpp.JID(user)&lt;br /&gt;
connection = xmpp.Client(server,debug=[])&lt;br /&gt;
connection.connect()&lt;br /&gt;
result = connection.auth(jid.getNode(), password,&amp;quot;LFY-client&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
connection.sendInitPresence()&lt;br /&gt;
 &lt;br /&gt;
while connection.Process(1):&lt;br /&gt;
    pass&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* Use XMPP to Create Your Own Google Talk Client - LINUX For You - http://www.linuxforu.com/2012/06/use-xmpp-to-create-your-own-google-talk-client/&lt;br /&gt;
&lt;br /&gt;
--- basic receive ---&lt;br /&gt;
&lt;br /&gt;
Print messages when received:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
 &lt;br /&gt;
import xmpp&lt;br /&gt;
 &lt;br /&gt;
user=&amp;quot;username@gmail.com&amp;quot;&lt;br /&gt;
password=&amp;quot;password&amp;quot;&lt;br /&gt;
server=&amp;quot;gmail.com&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
def message_handler(connect_object, message_node):&lt;br /&gt;
        message = &amp;quot;Welcome to my first Gtalk Bot :)&amp;quot;&lt;br /&gt;
        connect_object.send( xmpp.Message( message_node.getFrom() ,message))&lt;br /&gt;
 &lt;br /&gt;
jid = xmpp.JID(user)&lt;br /&gt;
connection = xmpp.Client(server)&lt;br /&gt;
connection.connect()&lt;br /&gt;
result = connection.auth(jid.getNode(), password, &amp;quot;LFY-client&amp;quot;)&lt;br /&gt;
connection.RegisterHandler(&#039;message&#039;, message_handler)&lt;br /&gt;
 &lt;br /&gt;
connection.sendInitPresence()&lt;br /&gt;
 &lt;br /&gt;
while connection.Process(1):&lt;br /&gt;
    pass&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* Use XMPP to Create Your Own Google Talk Client - LINUX For You - http://www.linuxforu.com/2012/06/use-xmpp-to-create-your-own-google-talk-client/&lt;br /&gt;
&lt;br /&gt;
--- remote-control shell bot ---&lt;br /&gt;
&lt;br /&gt;
Replace the simple bot’s message_handler() function with this new one:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def message_handler(connect_object,message_node):&lt;br /&gt;
        command = str(message_node.getBody())&lt;br /&gt;
 &lt;br /&gt;
        process = subprocess.Popen(command,shell=True,stdout=subprocess.PIPE, stderr=subprocess.PIPE)&lt;br /&gt;
        message = process.stdout.read()&lt;br /&gt;
        if message==&amp;quot;&amp;quot;:&lt;br /&gt;
            message=process.stderr.read()&lt;br /&gt;
 &lt;br /&gt;
        connect_object.send( xmpp.Message( message_node.getFrom() ,message))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* Use XMPP to Create Your Own Google Talk Client - LINUX For You - http://www.linuxforu.com/2012/06/use-xmpp-to-create-your-own-google-talk-client/&lt;br /&gt;
&lt;br /&gt;
--- roster ---&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import xmpp&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
userID   = &#039;myname@gmail.com&#039; &lt;br /&gt;
password = &#039;mypassword&#039;&lt;br /&gt;
ressource = &#039;Script&#039;&lt;br /&gt;
&lt;br /&gt;
jid  = xmpp.protocol.JID(userID)&lt;br /&gt;
jabber  = xmpp.Client(jid.getDomain(), debug=[])&lt;br /&gt;
&lt;br /&gt;
connection = jabber.connect((&#039;talk.google.com&#039;,5222))&lt;br /&gt;
auth = jabber.auth(jid.getNode(), password, ressource)&lt;br /&gt;
&lt;br /&gt;
jabber.sendInitPresence(requestRoster=1)&lt;br /&gt;
myroster = jabber.getRoster()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To get status, you have to wait for the other clients to send you their status:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
jabber.RegisterHandler(&#039;presence&#039;, myPresenceHandler)&lt;br /&gt;
&lt;br /&gt;
def myPresenceHandler(con, event):&lt;br /&gt;
  fromjid = event.getFrom().getStripped()&lt;br /&gt;
  status = myroster.getStatus(fromjid)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
python - XMPP chat: accessing contacts&#039; status messages with xmppPy&#039;s Roster - Stack Overflow - http://stackoverflow.com/questions/2381597/xmpp-chat-accessing-contacts-status-messages-with-xmpppys-roster&lt;br /&gt;
&lt;br /&gt;
--- full roster script ---&lt;br /&gt;
&lt;br /&gt;
kparal/jabber-roster · GitHub - https://github.com/kparal/jabber-roster&lt;br /&gt;
&lt;br /&gt;
A simple Python tool for listing your Jabber roster contacts. You can use it to easily backup list of your buddies.&lt;br /&gt;
&lt;br /&gt;
This program is maintained, but not further developed. Bugs will be fixed, but no new features will be added. If you want to work on this program, don&#039;t hesitate to contact me, I will gladly assign you to the development team.&lt;br /&gt;
&lt;br /&gt;
 git clone https://github.com/kparal/jabber-roster&lt;br /&gt;
 python jabber_roster.py&lt;br /&gt;
&lt;br /&gt;
https://pypi.python.org/pypi/jabber-roster&lt;br /&gt;
&lt;br /&gt;
--- vcard ---&lt;br /&gt;
&lt;br /&gt;
This information is not in the roster. You will need to query the clients individually and get their vCard by sending this IQ :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;iq from=&#039;stpeter@jabber.org/roundabout&#039;&lt;br /&gt;
    id=&#039;v1&#039;&lt;br /&gt;
    type=&#039;get&#039;&amp;gt;&lt;br /&gt;
  &amp;lt;vCard xmlns=&#039;vcard-temp&#039;/&amp;gt;&lt;br /&gt;
&amp;lt;/iq&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
My solution:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def vcard(disp, jid):&lt;br /&gt;
    msg = xmpp.protocol.Iq()&lt;br /&gt;
    msg.setType(&#039;get&#039;)&lt;br /&gt;
    msg.setTo(jid)&lt;br /&gt;
    qc = msg.addChild(&#039;vCard&#039;)&lt;br /&gt;
    qc.setAttr(&#039;xmlns&#039;, &#039;vcard-temp&#039;)&lt;br /&gt;
    rep = disp.SendAndWaitForResponse(msg)&lt;br /&gt;
    # to see what other fields are available in the XML output:&lt;br /&gt;
    # print rep&lt;br /&gt;
    userid=fname=lname=title=department=region=None&lt;br /&gt;
    for i in rep.getChildren():&lt;br /&gt;
        for j in i.getChildren():&lt;br /&gt;
            if j.getName() == &amp;quot;TITLE&amp;quot;:&lt;br /&gt;
                title = j.getData().encode(&#039;utf-8&#039;)&lt;br /&gt;
            for k in j.getChildren():&lt;br /&gt;
                if k.getName() == &amp;quot;GIVEN&amp;quot;:&lt;br /&gt;
                    fname = k.getData().encode(&#039;utf-8&#039;)&lt;br /&gt;
                if k.getName() == &amp;quot;FAMILY&amp;quot;:&lt;br /&gt;
                    lname = k.getData().encode(&#039;utf-8&#039;)&lt;br /&gt;
                if k.getName() == &amp;quot;ORGUNIT&amp;quot;:&lt;br /&gt;
                    department = k.getData().encode(&#039;utf-8&#039;)&lt;br /&gt;
                if k.getName() == &amp;quot;REGION&amp;quot;:&lt;br /&gt;
                    region = k.getData().encode(&#039;utf-8&#039;)&lt;br /&gt;
    return fname, lname, title, department, region&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* xmpppy - Retrieve gtalk nickname in python xmpp - Stack Overflow - http://stackoverflow.com/questions/4539477/retrieve-gtalk-nickname-in-python-xmpp&lt;br /&gt;
* XEP-0054: vcard-temp - http://xmpp.org/extensions/xep-0054.html&lt;br /&gt;
&lt;br /&gt;
=== google-api-python-client ===&lt;br /&gt;
&lt;br /&gt;
Google APIs Client Library for Python, which includes:&lt;br /&gt;
* google-api-python-client: The core Python library for accessing Google APIs.&lt;br /&gt;
* oauth2client: A Python client library for OAuth 2.0.&lt;br /&gt;
* Sample applications using google-api-python-client and oauth2client &lt;br /&gt;
&lt;br /&gt;
-&lt;br /&gt;
&lt;br /&gt;
https://developers.google.com/api-client-library/python/start/installation&lt;br /&gt;
* Calendar API - Python/Command Line&lt;br /&gt;
&lt;br /&gt;
-&lt;br /&gt;
Download:&lt;br /&gt;
 wget https://code.google.com/p/google-api-python-client/downloads/detail?name=google-api-python-client-1.2.zip&lt;br /&gt;
 wget https://code.google.com/p/google-api-python-client/downloads/detail?name=oauth2client-1.2.zip&lt;br /&gt;
&lt;br /&gt;
Git:&lt;br /&gt;
 git clone https://github.com/google/google-api-python-client&lt;br /&gt;
 git clone https://github.com/google/oauth2client&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* google-api-python-client - Google APIs Client Library for Python - Google Project Hosting - https://code.google.com/p/google-api-python-client/&lt;br /&gt;
&lt;br /&gt;
== Documentation Tools ==&lt;br /&gt;
&lt;br /&gt;
=== pydoc ===&lt;br /&gt;
&lt;br /&gt;
pydoc - http://docs.python.org/library/pydoc.html&lt;br /&gt;
: Documentation generator and online help system&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Doxygen and Doxypy ===&lt;br /&gt;
&lt;br /&gt;
See [[Python/Doxygen]]&lt;br /&gt;
&lt;br /&gt;
=== Sphinx ===&lt;br /&gt;
&lt;br /&gt;
Sphinx - http://sphinx.pocoo.org/&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Sphinx is a tool that makes it easy to create intelligent and beautiful documentation, written by Georg Brandl and licensed under the BSD license.&lt;br /&gt;
&lt;br /&gt;
It was originally created for the new Python documentation, and it has excellent facilities for the documentation of Python projects, but C/C++ is already supported as well, and it is planned to add special support for other languages as well. Of course, this site is also created from reStructuredText sources using Sphinx!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== epydoc ===&lt;br /&gt;
&lt;br /&gt;
epydoc - http://epydoc.sourceforge.net/&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Epydoc is a tool for generating API documentation for Python modules, based on their docstrings. For an example of epydoc&#039;s output, see the API documentation for epydoc itself (html, pdf). A lightweight markup language called epytext can be used to format docstrings, and to add information about specific fields, such as parameters and instance variables. Epydoc also understands docstrings written in reStructuredText, Javadoc, and plaintext. For a more extensive example of epydoc&#039;s output, see the API documentation for Python 2.5. &amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Python 3 ==&lt;br /&gt;
&lt;br /&gt;
=== Python 3 Wall of Superpowers ===&lt;br /&gt;
&lt;br /&gt;
Python 3 Wall of Superpowers - https://python3wos.appspot.com/&lt;br /&gt;
&lt;br /&gt;
&amp;quot;As listed on PyPI - packages in red don&#039;t support python 3, packages in green do. Hopefully one day everything will be greener. &amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== New in Python 3 ===&lt;br /&gt;
&lt;br /&gt;
==== qualnames ====&lt;br /&gt;
&lt;br /&gt;
New in 3.3&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; def f():&lt;br /&gt;
...   def g():&lt;br /&gt;
...     class H: pass&lt;br /&gt;
...     return H&lt;br /&gt;
...   return g&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; H=f()()&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; # 3.3:&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; H&lt;br /&gt;
&amp;lt;class &#039;__main__.f.&amp;lt;locals&amp;gt;.g.&amp;lt;locals&amp;gt;.H&#039;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; H.__qualname__&lt;br /&gt;
&#039;f.&amp;lt;locals&amp;gt;.g.&amp;lt;locals&amp;gt;.H&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; # 2.6:&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; H&lt;br /&gt;
&amp;lt;class __main__.H at 0x2b885044b890&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; H.__qualname__&lt;br /&gt;
AttributeError: class H has no attribute &#039;__qualname__&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Python 2 or Python 3 ==&lt;br /&gt;
&lt;br /&gt;
Python2orPython3 - PythonInfo Wiki - http://wiki.python.org/moin/Python2orPython3&lt;br /&gt;
:Short version: Python 2.x is the status quo, Python 3.x is the shiny new thing.&lt;br /&gt;
:At the time of writing (July 4, 2010), the final 2.7 release is out, with a statement of extended support for this end-of-life release. The 2.x branch will see no new major releases after that. 3.x is under active and continued development, with 3.1 already available and 3.2 due for release around the turn of the year.&lt;br /&gt;
&lt;br /&gt;
Python 2.7.1 Release - http://www.python.org/download/releases/2.7.1/&lt;br /&gt;
&lt;br /&gt;
What’s New In Python 3.0 — Python v3.0.1 documentation - http://docs.python.org/release/3.0.1/whatsnew/3.0.html&lt;br /&gt;
* print() requires parenthesis&lt;br /&gt;
* raw_input() is now input()&lt;br /&gt;
&lt;br /&gt;
== Python for Windows ==&lt;br /&gt;
&lt;br /&gt;
Python for Windows - http://www.python.org/download/windows/&lt;br /&gt;
&lt;br /&gt;
=== Windows IDEs ===&lt;br /&gt;
&lt;br /&gt;
==== PyCharm ====&lt;br /&gt;
&lt;br /&gt;
 http://www.pycharm.com/&lt;br /&gt;
&lt;br /&gt;
=== Hide Console ===&lt;br /&gt;
&lt;br /&gt;
fork() does not work on windows.  So what else can we do?&lt;br /&gt;
&lt;br /&gt;
How to hide console window in python? - http://stackoverflow.com/questions/764631/how-to-hide-console-window-in-python&lt;br /&gt;
* &amp;quot;Simply save it with a .pyw extension. This will prevent the console window from opening. Explanation at the bottom of section [http://docs.python.org/2/tutorial/interpreter.html#executable-python-scripts]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== 32bit vs 64bit ===&lt;br /&gt;
&lt;br /&gt;
IDLE:&lt;br /&gt;
&lt;br /&gt;
32bit:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
C:\Python27&amp;gt;python&lt;br /&gt;
Python 2.7.6 (default, Nov 10 2013, 19:24:18) [MSC v.1500 32 bit (Intel)] on win32&lt;br /&gt;
Type &amp;quot;help&amp;quot;, &amp;quot;copyright&amp;quot;, &amp;quot;credits&amp;quot; or &amp;quot;license&amp;quot; for more information.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
64bit: (note: default path is C:\Python27)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
C:\Python27-64bit&amp;gt;python.exe&lt;br /&gt;
Python 2.7.6 (default, Nov 10 2013, 19:24:24) [MSC v.1500 64 bit (AMD64)] on win32&lt;br /&gt;
Type &amp;quot;help&amp;quot;, &amp;quot;copyright&amp;quot;, &amp;quot;credits&amp;quot; or &amp;quot;license&amp;quot; for more information.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Task Manager:&lt;br /&gt;
 python.exe *32&lt;br /&gt;
&lt;br /&gt;
 python.exe&lt;br /&gt;
&lt;br /&gt;
Platform:&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; import platform&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; platform.python_compiler()&lt;br /&gt;
 &#039;MSC v.1500 32 bit (Intel)&#039;&lt;br /&gt;
&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; import platform&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; platform.python_compiler()&lt;br /&gt;
 &#039;MSC v.1500 64 bit (AMD64)&#039;&lt;br /&gt;
&lt;br /&gt;
Code: [http://stackoverflow.com/questions/2208828/detect-64bit-os-windows-in-python]&lt;br /&gt;
 import struct&lt;br /&gt;
 def is_python_64bit():&lt;br /&gt;
     return (struct.calcsize(&amp;quot;P&amp;quot;) == 8)&lt;br /&gt;
&lt;br /&gt;
=== Stand-Alone Executable ===&lt;br /&gt;
&lt;br /&gt;
==== Python ZIP Application ====&lt;br /&gt;
&lt;br /&gt;
Python can be run from a single bundled zip file - similar to a Java WAR!  Python has been able to (Allow interpreter to execute a zip file http://bugs.python.org/issue1739468)&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Python quietly added a new feature in 2.6 that makes it possible to bundle up a directory full of Python code into a single executable file.&amp;quot; [http://blog.ablepear.com/2012/10/bundling-python-files-into-stand-alone.html]&lt;br /&gt;
&lt;br /&gt;
When a python zip application is executed, it will execute &#039;__main__.py&#039; [http://docs.python.org/using/cmdline.html#interface-options]&lt;br /&gt;
&lt;br /&gt;
 mkdir app&lt;br /&gt;
 touch app/__main__.py&lt;br /&gt;
 cd app&lt;br /&gt;
 zip -r ../app.zip *&lt;br /&gt;
 cd ..&lt;br /&gt;
 python app.zip&lt;br /&gt;
&lt;br /&gt;
Load a resource - The easiest way to find and load a program bundle like this is to use the pkg_resources module. - http://packages.python.org/distribute/pkg_resources.html&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# file: app/__main__.py&lt;br /&gt;
&lt;br /&gt;
import pkg_resources&lt;br /&gt;
&lt;br /&gt;
def main():&lt;br /&gt;
  print(&#039;The rain in Spain falls mainly in the plain.&#039;)&lt;br /&gt;
  print(pkg_resources.resource_string(&#039;resources&#039;, &#039;inFrance.txt&#039;))&lt;br /&gt;
&lt;br /&gt;
if __name__ == &#039;__main__&#039;:&lt;br /&gt;
  main()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now use a bit of UNIX magic to turn app2.zip into an executable:&lt;br /&gt;
 echo &#039;#!/usr/bin/env python&#039; | cat - app2.zip &amp;gt; app2&lt;br /&gt;
 chmod +x app2&lt;br /&gt;
&lt;br /&gt;
&amp;quot;The zip file format is designed to allow a small executable program to be inserted at the front (that&#039;s how self-extracting zip files are created), so this is kosher and doesn&#039;t corrupt the zip file.&amp;quot; [http://blog.ablepear.com/2012/10/bundling-python-files-into-stand-alone.html]&lt;br /&gt;
&lt;br /&gt;
Now you can simply run app2 like any executable.&lt;br /&gt;
 $ ./app2&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* Able Pear Software: Bundling Python files into a stand-alone executable - http://blog.ablepear.com/2012/10/bundling-python-files-into-stand-alone.html&lt;br /&gt;
* PEP 441 -- Improving Python ZIP Application Support - http://www.python.org/dev/peps/pep-0441/&lt;br /&gt;
* Issue 1739468: Allow interpreter to execute a zip file - Python tracker - http://bugs.python.org/issue1739468&lt;br /&gt;
* Package Discovery and Resource Access using pkg_resources — Distribute documentation - http://packages.python.org/distribute/pkg_resources.html&lt;br /&gt;
&lt;br /&gt;
==== Shell Python Loader ====&lt;br /&gt;
&lt;br /&gt;
Came before the Python ZIP Application support.&lt;br /&gt;
&lt;br /&gt;
Python zip exe - Noah.org - http://www.noah.org/wiki/Python_zip_exe&lt;br /&gt;
&lt;br /&gt;
&amp;quot;This takes your Python application and packages it into a single executable shell script. You application can be made of up multiple python scripts. The executable shell script is also compressed, so the resulting script is smaller than the original. This should work on any system that has Python and a Bourne shell (works on Cygwin too). Note that this does not package the Python interpreter into the executable. This packages only you python code into a zip file, but this still allows you to distribute your application as a single shell script that will run on any system with Python installed.  In theory, you could zip the .pyc files, but the byte code is guaranteed to run only on exactly the same version Python interpreter (including minor version). It is safer to just package the .py files.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
First you need to zip all your python files:&lt;br /&gt;
 zip main.zip main.py spam.py eggs.py&lt;br /&gt;
&lt;br /&gt;
zipheader.sh:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/sh&lt;br /&gt;
# This is a self-extracting executable.&lt;br /&gt;
# Execute this like any normal executable.&lt;br /&gt;
# You may need to &amp;quot;chmod a+x&amp;quot; this file.&lt;br /&gt;
# This is a binary ZIP file with a Python loader header.&lt;br /&gt;
#&lt;br /&gt;
# Bourne shell loader:&lt;br /&gt;
PYTHON=$(which python 2&amp;gt;/dev/null)&lt;br /&gt;
if [ ! -x &amp;quot;$PYTHON&amp;quot; ] ; then&lt;br /&gt;
    echo &amp;quot;Python not found!&amp;quot;&lt;br /&gt;
    exit 1&lt;br /&gt;
fi&lt;br /&gt;
exec $PYTHON -c &amp;quot;&lt;br /&gt;
# Python loader:&lt;br /&gt;
import sys, os&lt;br /&gt;
if int(sys.version[0])&amp;lt;2:&lt;br /&gt;
    print &#039;Python version 2.3 final or greater is required.&#039;&lt;br /&gt;
    print &#039;Your version is&#039;, sys.version&lt;br /&gt;
    os._exit(1)&lt;br /&gt;
major = sys.version_info[0]&lt;br /&gt;
minor = sys.version_info[1]&lt;br /&gt;
releaselevel = sys.version_info[3]&lt;br /&gt;
if (major==2 and minor&amp;lt;3) or (major==2 and minor==3 and releaselevel!=&#039;final&#039;):&lt;br /&gt;
    print &#039;Python version 2.3 final or greater is required.&#039;&lt;br /&gt;
    print &#039;Your version is&#039;, sys.version&lt;br /&gt;
    os._exit(1)&lt;br /&gt;
sys.path.insert(0, sys.argv[1])&lt;br /&gt;
del sys.argv[0:1]&lt;br /&gt;
import main&lt;br /&gt;
main.main()&lt;br /&gt;
&amp;quot; $0 $@&lt;br /&gt;
# Zip file:&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Concatinate zipheader.sh with the zip file.&lt;br /&gt;
 cat zipheader.sh main.zip &amp;gt; main&lt;br /&gt;
&lt;br /&gt;
Set main as executable.&lt;br /&gt;
 chmod +x main&lt;br /&gt;
&lt;br /&gt;
&amp;quot;This is an improvement on Joerg Raedler&#039;s Python recipe, [http://code.activestate.com/recipes/215301-binding-main-skript-and-modules-to-one-executable-/ 215301]. The original closes stdin. The herefile in the shell script redirects stdin before python gets a chance to start. This disables raw_input() and anything else that reads sys.stdin. Unfortunately, Raedler&#039;s boot script closes stdin, which is a fairly big limitation. The herefile in the shell script (END_OF_PYTHON_CODE) redirects stdin before python starts; stdin is closed at the end of the herefile. This disables raw_input() and anything else that reads sys.stdin. &amp;quot;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* Python zip exe - Noah.org - http://www.noah.org/wiki/Python_zip_exe&lt;br /&gt;
* Build a compressed self-extracting executable script on UNIX « Python recipes « ActiveState Code - http://code.activestate.com/recipes/497000-build-a-compressed-self-extracting-executable-scri/&lt;br /&gt;
* binding main skript and modules to one executable with python-2.3 under UNIX « Python recipes « ActiveState Code - http://code.activestate.com/recipes/215301-binding-main-skript-and-modules-to-one-executable-/&lt;br /&gt;
&lt;br /&gt;
==== py2exe ====&lt;br /&gt;
&lt;br /&gt;
py2exe - http://www.py2exe.org/&lt;br /&gt;
: &amp;quot;py2exe is a Python Distutils extension which converts Python scripts into executable Windows programs, able to run without requiring a Python installation. &amp;quot;&lt;br /&gt;
&lt;br /&gt;
Tutorial - http://www.py2exe.org/index.cgi/Tutorial&lt;br /&gt;
&lt;br /&gt;
Note: Install the version that matches your version of python&lt;br /&gt;
&lt;br /&gt;
Note: run installer &amp;quot;as administrator&amp;quot;&lt;br /&gt;
&lt;br /&gt;
setup.py&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from distutils.core import setup&lt;br /&gt;
import py2exe&lt;br /&gt;
&lt;br /&gt;
setup(console=[&#039;hello.py&#039;])&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
No console window version: [http://ubuntuforums.org/showthread.php?t=728170] [http://stackoverflow.com/questions/3275293/hiding-console-window-of-python-gui-app-with-py2exe]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from distutils.core import setup&lt;br /&gt;
import py2exe&lt;br /&gt;
&lt;br /&gt;
setup(windows=[&#039;hello.py&#039;])&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Build:&lt;br /&gt;
 python setup.py py2exe&lt;br /&gt;
&lt;br /&gt;
pygame is more complex: http://www.pygame.org/wiki/Pygame2exe&lt;br /&gt;
&lt;br /&gt;
==== py2app ====&lt;br /&gt;
&lt;br /&gt;
==== pyinstaller ====&lt;br /&gt;
&lt;br /&gt;
==== cx_Freeze ====&lt;br /&gt;
&lt;br /&gt;
=== Windows Libraries ===&lt;br /&gt;
&lt;br /&gt;
==== Python for Windows Extensions - PyWin32 ====&lt;br /&gt;
&lt;br /&gt;
Python for Windows Extensions - http://starship.python.net/~skippy/win32/&lt;br /&gt;
* There is a build for each python version and architecture (32bit vs 64bit)&lt;br /&gt;
&lt;br /&gt;
Follow event viewer&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import win32evtlog  # install Python for Windows Extensions - http://starship.python.net/~skippy/win32/&lt;br /&gt;
&lt;br /&gt;
# open event viewer&lt;br /&gt;
server = &amp;quot;localhost&amp;quot;&lt;br /&gt;
source = &amp;quot;System&amp;quot;&lt;br /&gt;
handle = win32evtlog.OpenEventLog(server, source)&lt;br /&gt;
&lt;br /&gt;
# seek to end of log&lt;br /&gt;
flags = win32evtlog.EVENTLOG_BACKWARDS_READ | win32evtlog.EVENTLOG_SEQUENTIAL_READ&lt;br /&gt;
events = win32evtlog.ReadEventLog(handle, flags, 0)&lt;br /&gt;
&lt;br /&gt;
# return to normal reading direction&lt;br /&gt;
flags = win32evtlog.EVENTLOG_FORWARDS_READ | win32evtlog.EVENTLOG_SEQUENTIAL_READ&lt;br /&gt;
win32evtlog.ReadEventLog(handle, flags, 0)  # ignore initial logs&lt;br /&gt;
&lt;br /&gt;
# loop through events&lt;br /&gt;
while True:&lt;br /&gt;
    events = win32evtlog.ReadEventLog(handle, flags, 0)&lt;br /&gt;
    if events:&lt;br /&gt;
        for event in events:&lt;br /&gt;
            data = event.StringInserts&lt;br /&gt;
            if data:&lt;br /&gt;
                # Example: 07/03/14 12:34:35 - MYEVENTSOURCE - 0 - 1 - 4  &amp;quot;HELLO&amp;quot;&lt;br /&gt;
                print event.TimeGenerated, &#039;-&#039;, event.SourceName, &#039;-&#039;, event.EventCategory, &#039;-&#039;, event.EventID, &#039;-&#039;, event.EventType, &#039;-&#039;, &#039;&amp;quot;%s&amp;quot;&#039; % &amp;quot; &amp;quot;.join(data)&lt;br /&gt;
    time.sleep(.5)  # yield cpu&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* PyWin32: Getting Windows Event Logs « The Mouse Vs. The Python - http://www.blog.pythonlibrary.org/2010/07/27/pywin32-getting-windows-event-logs/&lt;br /&gt;
&lt;br /&gt;
==== PyCrypto for Windows ====&lt;br /&gt;
&lt;br /&gt;
Download Install: http://www.voidspace.org.uk/python/modules.shtml#pycrypto&lt;br /&gt;
&lt;br /&gt;
Installation: [http://stackoverflow.com/questions/11405549/how-do-i-install-pycrypto-on-windows]&lt;br /&gt;
 easy_install http://www.voidspace.org.uk/downloads/pycrypto26/pycrypto-2.6.win32-py2.7.exe&lt;br /&gt;
 easy_install http://www.voidspace.org.uk/downloads/pycrypto26/pycrypto-2.6.win-amd64-py2.7.exe&lt;br /&gt;
&lt;br /&gt;
==== Paramiko for Windows ====&lt;br /&gt;
&lt;br /&gt;
# Install PyCrypto (above)&lt;br /&gt;
# pip install paramiko&lt;br /&gt;
&lt;br /&gt;
==== PyGame for Windows ====&lt;br /&gt;
&lt;br /&gt;
Download - http://www.pygame.org/download.shtml&lt;br /&gt;
* http://pygame.org/ftp/pygame-1.9.1.win32-py2.7.msi&lt;br /&gt;
&lt;br /&gt;
== Indentation ==&lt;br /&gt;
&lt;br /&gt;
Python: Myths about Indentation - http://www.secnetix.de/olli/Python/block_indentation.hawk&lt;br /&gt;
:There are quite some prejudices and myths about Python&#039;s indentation rules among people who don&#039;t really know Python. I&#039;ll try to address a few of these concerns on this page. &lt;br /&gt;
*&amp;quot;Whitespace is significant in Python source code.&amp;quot;&lt;br /&gt;
*&amp;quot;Python forces me to use a certain indentation style.&amp;quot;&lt;br /&gt;
*&amp;quot;You cannot safely mix tabs and spaces in Python.&amp;quot;&lt;br /&gt;
*&amp;quot;I just don&#039;t like it.&amp;quot;&lt;br /&gt;
*&amp;quot;How does the compiler parse the indentation?&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== PEP - Python Enhancement Proposals ==&lt;br /&gt;
&lt;br /&gt;
Python Enhancement Proposals (PEPs)&lt;br /&gt;
&lt;br /&gt;
* Index of Python Enhancement Proposals (PEPs) - http://www.python.org/dev/peps/&lt;br /&gt;
&lt;br /&gt;
== Convert Tabs to Spaces ==&lt;br /&gt;
&lt;br /&gt;
Convert tabs to 4 spaces:&lt;br /&gt;
 sed -i &#039;s/\t/    /g&#039;  script.py&lt;br /&gt;
&lt;br /&gt;
== Linting ==&lt;br /&gt;
&lt;br /&gt;
* pep8 - python style guide checker&lt;br /&gt;
* pychecker - more verbose, imports code, slower&lt;br /&gt;
* pylint - most verbose, configurable, &amp;quot;rates&amp;quot; code&lt;br /&gt;
* pyflakes - least verbose (dead/redundant code)&lt;br /&gt;
&lt;br /&gt;
rpmforge:&lt;br /&gt;
 yum install pyflakes pychecker&lt;br /&gt;
 # pylint - not sure which pacakge includes&lt;br /&gt;
&lt;br /&gt;
=== pep8 ===&lt;br /&gt;
&lt;br /&gt;
See [[Python/pep8]]&lt;br /&gt;
&lt;br /&gt;
=== pychecker ===&lt;br /&gt;
&lt;br /&gt;
See [[Python/pychecker]]&lt;br /&gt;
&lt;br /&gt;
=== pylint ===&lt;br /&gt;
&lt;br /&gt;
See [[Python/pylint]]&lt;br /&gt;
&lt;br /&gt;
== PEP8 Style Guidlines ==&lt;br /&gt;
&lt;br /&gt;
PEP 8 -- Style Guide for Python Code - http://www.python.org/dev/peps/pep-0008/&lt;br /&gt;
&lt;br /&gt;
* Use spaces - Use 4 spaces per indentation level.&lt;br /&gt;
* Never mix tabs and spaces.&lt;br /&gt;
* Limit all lines to a maximum of 79 characters.&lt;br /&gt;
* Line wrapping - The preferred way of wrapping long lines is by using Python&#039;s implied line continuation inside parentheses, brackets and braces.  Long lines can be broken over multiple lines by wrapping expressions in parentheses.&lt;br /&gt;
* Encoding - For Python 3.0 and beyond, UTF-8 is preferred over Latin-1, see PEP 3120.&lt;br /&gt;
* Imports should usually be on separate lines&lt;br /&gt;
* Avoid extraneous whitespace in most situations&lt;br /&gt;
* Always use &#039;self&#039; for the first argument to instance methods.&lt;br /&gt;
&lt;br /&gt;
=== PEP8 Style Checker ===&lt;br /&gt;
&lt;br /&gt;
See [[#pep8]]&lt;br /&gt;
&lt;br /&gt;
== Benefits of Python ==&lt;br /&gt;
&lt;br /&gt;
What is the return on investment for this group by learning Python? The list of benefits below sums up what the language has to offer:&lt;br /&gt;
* Python is designed from the ground up to encourage maintainable, readable and reusable code. It has great support for particular paradigms such as object-oriented programming.&lt;br /&gt;
* Python code is usually around a quarter of the length of code generated by C++ or Java - less typing, less debugging and less maintenance.&lt;br /&gt;
* Python does not need to be compiled or linked, which allows for a more iterative programming style and a quicker development cycle.&lt;br /&gt;
* Python is extremely portable. Code can be easily exchanged between Windows, Mac OS and Linux with little to no modification.&lt;br /&gt;
* Python comes with a staggering array of standard libraries and mature third-party projects. Web development, scientific computing, operator system access and network scripting are all supported.&lt;br /&gt;
* Python can talk with many other languages easily. It has support for invoking C and C++ code and can itself be called from libraries written in these languages. &lt;br /&gt;
&lt;br /&gt;
Source: http://quantstart.com/articles/Quant-Reading-List-Python-Programming/ - Quant Reading List Python Programming&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Benefits of Python:&lt;br /&gt;
* Python is available for most operating systems, including Windows, UNIX, Linux, and Mac OS.&lt;br /&gt;
* Python&#039;s clean object-oriented design and extensive support libraries offer two to ten fold the programmer productivity seen with languages like C, C++, C#, Java, VB, and Perl.&lt;br /&gt;
&lt;br /&gt;
Source: Python Development - Benefits of Python - Digital Mesh - http://www.digitalmesh.com/offshore-development-center/python-development/benefits-of-python.html&lt;br /&gt;
&lt;br /&gt;
== Python Package Management ==&lt;br /&gt;
&lt;br /&gt;
=== Install Module ===&lt;br /&gt;
&lt;br /&gt;
Installing Python Modules — Python v2.7.1 documentation - http://docs.python.org/install/index.html&lt;br /&gt;
&lt;br /&gt;
The new standard: Distutils&lt;br /&gt;
 python setup.py install&lt;br /&gt;
&lt;br /&gt;
Download and extract target package, then:&lt;br /&gt;
 sudo python setup.py install&lt;br /&gt;
&lt;br /&gt;
Note: Running setup.py install builds and installs all modules in one run&lt;br /&gt;
&lt;br /&gt;
Help:&lt;br /&gt;
 python setup.py --help&lt;br /&gt;
&lt;br /&gt;
Incremental method:&lt;br /&gt;
 python setup.py build&lt;br /&gt;
 python setup.py install&lt;br /&gt;
 python setup.py build --help   # help&lt;br /&gt;
&lt;br /&gt;
Force rebuild and install:&lt;br /&gt;
 python setup.py build --force    # if have to repeat&lt;br /&gt;
 python setup.py install --force  # if have to repeat&lt;br /&gt;
&lt;br /&gt;
Default installation paths:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Platform	Standard installation location		Default value&lt;br /&gt;
Unix (pure)	prefix/lib/pythonX.Y/site-packages	/usr/local/lib/pythonX.Y/site-packages&lt;br /&gt;
Unix (non-pure)	exec-prefix/lib/pythonX.Y/site-packages	/usr/local/lib/pythonX.Y/site-packages&lt;br /&gt;
Windows		prefix					C:\Python&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alternate install path:&lt;br /&gt;
 python setup.py install --home=&amp;lt;dir&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alternate base folders:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Type of file			Installation Directory	Override option&lt;br /&gt;
pure module distribution	home/lib/python		--install-purelib&lt;br /&gt;
non-pure module distribution	home/lib/python		--install-platlib&lt;br /&gt;
scripts				home/bin		--install-scripts&lt;br /&gt;
data				home/share		--install-data&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Modifying Python’s Search Path:&lt;br /&gt;
 import sys&lt;br /&gt;
 sys.path.append(&#039;/www/python/&#039;)&lt;br /&gt;
&lt;br /&gt;
=== Python Package Index ===&lt;br /&gt;
&lt;br /&gt;
user-submitted Python packages:&lt;br /&gt;
 http://pypi.python.org/pypi&lt;br /&gt;
&lt;br /&gt;
 sudo python setup.py install&lt;br /&gt;
&lt;br /&gt;
Package Site:&lt;br /&gt;
 http://pypi.python.org/pypi/[PACKAGE]&lt;br /&gt;
 http://pypi.python.org/pypi/test&lt;br /&gt;
&lt;br /&gt;
If they are on http://pypi.python.org/:&lt;br /&gt;
 pip install foo&lt;br /&gt;
&lt;br /&gt;
[http://stackoverflow.com/questions/410163/for-python-programmers-is-there-anything-equivalent-to-perls-cpan For Python programmers, is there anything equivalent to Perl&#039;s CPAN? - Stack Overflow]&lt;br /&gt;
&lt;br /&gt;
=== Easy Installation ===&lt;br /&gt;
&lt;br /&gt;
EasyInstall - The PEAK Developers&#039; Center - http://peak.telecommunity.com/DevCenter/EasyInstall&lt;br /&gt;
: Easy Install is a python module (easy_install) bundled with setuptools that lets you automatically download, build, install, and manage Python packages.&lt;br /&gt;
&lt;br /&gt;
CheeseShopTutorial - PythonInfo Wiki - http://wiki.python.org/moin/CheeseShopTutorial&lt;br /&gt;
: EasyInstall (easy_install) gives you a quick and painless way to install packages remotely by connecting to the Package Index or even other websites via HTTP. It is somewhat analogous to the CPAN and PEAR tools for Perl and PHP, respectively.&lt;br /&gt;
&lt;br /&gt;
=== pip ===&lt;br /&gt;
&lt;br /&gt;
See [[Python/pip]]&lt;br /&gt;
&lt;br /&gt;
==== Create PIP Package ====&lt;br /&gt;
&lt;br /&gt;
See [[Python/pip#Create PIP Package]]&lt;br /&gt;
&lt;br /&gt;
=== Distribute ===&lt;br /&gt;
&lt;br /&gt;
distribute - Easily download, build, install, upgrade, and uninstall Python packages&lt;br /&gt;
&lt;br /&gt;
distribute 0.6.24 : Python Package Index - http://pypi.python.org/pypi/distribute&lt;br /&gt;
&lt;br /&gt;
Installation:&lt;br /&gt;
 mkdir -p ~/.src ; cd ~/.src&lt;br /&gt;
 wget http://pypi.python.org/packages/source/d/distribute/distribute-0.6.24.tar.gz#md5=17722b22141aba8235787f79800cc452&lt;br /&gt;
 tar -zvxf distribute-0.6.24.tar.gz&lt;br /&gt;
 cd distribute-0.6.24&lt;br /&gt;
 sudo python setup.py install&lt;br /&gt;
&lt;br /&gt;
Test:&lt;br /&gt;
 echo &amp;quot;import distribute&amp;quot; | grep python&lt;br /&gt;
&lt;br /&gt;
== Named Parameters ==&lt;br /&gt;
&lt;br /&gt;
http://diveintopython.org/power_of_introspection/optional_arguments.html&lt;br /&gt;
&lt;br /&gt;
Python allows function arguments to have default values; if the function is called without the argument, the argument gets its default value. Futhermore, arguments can be specified in any order by using named arguments. Stored procedures in SQL Server Transact/SQL can do this, so if you&#039;re a SQL Server scripting guru, you can skim this part.&lt;br /&gt;
&lt;br /&gt;
Here is an example of info, a function with two optional arguments:&lt;br /&gt;
&lt;br /&gt;
 def info(object, spacing=10, collapse=1):&lt;br /&gt;
&lt;br /&gt;
spacing and collapse are optional, because they have default values defined. object is required, because it has no default value. If info is called with only one argument, spacing defaults to 10 and collapse defaults to 1. If info is called with two arguments, collapse still defaults to 1.&lt;br /&gt;
&lt;br /&gt;
Say you want to specify a value for collapse but want to accept the default value for spacing. In most languages, you would be out of luck, because you would need to call the function with three arguments. But in Python, arguments can be specified by name, in any order. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
http://www.wellho.net/mouth/1871_Optional-and-named-parameters-in-Python.html&lt;br /&gt;
&lt;br /&gt;
If you add a parameter with two asterixes (**) on the end of a function definition, that parameter is taken as being the name of a dictionary into which all otherwise unidentified parameters are stored. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def getnet(gross, taxrate=17.5, **others):&lt;br /&gt;
  net = gross / (1.0 + taxrate*0.01)&lt;br /&gt;
  for more in others.keys():&lt;br /&gt;
    print &amp;quot;GETNET:&amp;quot;,more,&amp;quot; - &amp;quot;,others[more]&lt;br /&gt;
  return neto&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Python vs other languages ==&lt;br /&gt;
&lt;br /&gt;
[http://www.strombergers.com/python/ Python is Cool (and Perl is not), Especially for C/C++ Programmers]&lt;br /&gt;
&lt;br /&gt;
==Experimenting with Memory Remanence==&lt;br /&gt;
[http://citp.princeton.edu/memory/exp/ Experimenting with Memory Remanence]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    #!/usr/bin/env python&lt;br /&gt;
&lt;br /&gt;
    # a pirate&#039;s favorite chemical element&lt;br /&gt;
    a = &amp;quot;&amp;quot;&lt;br /&gt;
    while 1: a += &amp;quot;ARGON&amp;quot; &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 sudo strings /dev/mem | less&lt;br /&gt;
&lt;br /&gt;
==UTOSC 2008 - 90 percent of the Python you need to know (in 90 minutes)==&lt;br /&gt;
See [[UTOSC 2008 - 90 percent of the Python you need to know (in 90 minutes)]]&lt;br /&gt;
&lt;br /&gt;
== Program Layout Best Practices Presentation ==&lt;br /&gt;
&lt;br /&gt;
Program layout best practices - Seth House &amp;lt;seth@eseth.com&amp;gt; - Utah Django User Group - 2011-06-23&lt;br /&gt;
* Slides - https://github.com/whiteinge/presentations/tree/master/upyug_2011-06-09_program-layout&lt;br /&gt;
* Video - http://blip.tv/utah-open-source/python-layout-best-practices-for-modules-django-cli-utah-django-user-group-5315808&lt;br /&gt;
&lt;br /&gt;
Module skeleton:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
# coding: utf-8&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;Module docstring&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
__author__ = ’Mr. Me &amp;lt;me@example.net&amp;gt;’&lt;br /&gt;
__version__ = ’1.2.3’&lt;br /&gt;
&lt;br /&gt;
if __name__==’__main__’:&lt;br /&gt;
 main()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Executing modules as scripts&lt;br /&gt;
 # PEP 338:&lt;br /&gt;
 python -m SimpleHTTPServer&lt;br /&gt;
&lt;br /&gt;
== CLI package ==&lt;br /&gt;
&lt;br /&gt;
cli — command line tools — pyCLI v1.1.1 documentation - http://packages.python.org/pyCLI/&lt;br /&gt;
&lt;br /&gt;
== Python IDE ==&lt;br /&gt;
&lt;br /&gt;
IntegratedDevelopmentEnvironments - PythonInfo Wiki - http://wiki.python.org/moin/IntegratedDevelopmentEnvironments&lt;br /&gt;
* IDEs with introspection-based code completion and integrated debugger&lt;br /&gt;
* IDEs with introspection-based code completion /or/ integrated debugger&lt;br /&gt;
* IDEs with integrated gui builder&lt;br /&gt;
* Editors&lt;br /&gt;
* Reviews&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Is there a good, free Python IDE for Windows? - Stack Overflow - http://stackoverflow.com/questions/126753/is-there-a-good-free-python-ide-for-windows&lt;br /&gt;
* Eclipse with PyDev&lt;br /&gt;
* Aptana Studio 3&lt;br /&gt;
* Active State also offers Komodo Edit&lt;br /&gt;
* WingWare - http://www.wingware.com/&lt;br /&gt;
* Eric IDE - http://www.die-offenbachs.de/eric/index.html&lt;br /&gt;
* MMM-Experts - Products - http://mmm-experts.com/Products.aspx?ProductId=4&lt;br /&gt;
** PyScripter is a Python IDE built in Python for Delphi(P4D) components and created with the ambition to become competitive in functionality with commercial Windows-based IDEs available for other languages. Being built in a compiled language is rather snappier than some of the other Python IDEs and provides an extensive blend of features that make it a productive Python development environment. &lt;br /&gt;
* ActiveState Python comes with PythonWin which is reasonably good&lt;br /&gt;
* PyCharm from JetBrains is not free in general, but has free early access program.&lt;br /&gt;
* SPE - Stani&#039;s Python Editor, is pretty awesome. See http://pythonide.blogspot.com/.&lt;br /&gt;
* You may want to take a look at the pdb module - http://docs.python.org/lib/module-pdb.html&lt;br /&gt;
* Geany (http://www.geany.org/) is a fairly light text editor that does a lot of IDE-like stuff.&lt;br /&gt;
* SciTE: http://www.scintilla.org/SciTE.html&lt;br /&gt;
* Editra: http://editra.org/ &lt;br /&gt;
* Netbeans has support for python development in their Python Early Access version. - http://www.netbeans.org/features/python/&lt;br /&gt;
* I use Notepad++ with the appropriate settings.&lt;br /&gt;
* The Eric Python IDE - http://www.die-offenbachs.de/eric/index.html&lt;br /&gt;
* BOa Constructor www.boa-constructor.sourceforge.net really nice! drag and drop stuff!&lt;br /&gt;
* DrPtyhon is also very nice, and has many plug-ins. http://drpython.sourceforge.net/&lt;br /&gt;
* Vim&lt;br /&gt;
* I will make a plug for my preference of Python development environments: SPE. SPE is an integrated development environment that provides code completion, integrated Python shell, calltips, and various helper tools like notes and todo lists. It also includes wxGlade so you can make wxPython applications easily. Plus, it includes the python debugger WinPdb.&lt;br /&gt;
* http://groups.google.com.tr/group/python_opengl this software is my sample visual python ide.its demo version.&lt;br /&gt;
* I use PyScripter, and find it pretty awesome.&lt;br /&gt;
* There is one Python IDE written in Java: jHepWork: http://jwork.org/jhepwork/ it can detect Python&#039;s indentation rules rather nicely (+ detects structure of a code and syntax)&lt;br /&gt;
* gvim built with your python version support and with this plugins:&lt;br /&gt;
** NERDTree (don&#039;t read he&#039;s blog ;)&lt;br /&gt;
** matchit (it&#039;s builtin in new versions just put a symlink or junction)&lt;br /&gt;
** pyflakes&lt;br /&gt;
** pysmell&lt;br /&gt;
* Try Python Tools for Visual Studio. Supports CPython and IronPython. - http://pytools.codeplex.com/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
PythonEditors - PythonInfo Wiki - http://wiki.python.org/moin/PythonEditors&lt;br /&gt;
* List of editors&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Python Ide - http://c2.com/cgi/wiki?PythonIde&lt;br /&gt;
: There are a lot of Ides for PythonLanguage springing up. Many of them written in Python &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Is there a better Python IDE? « Lennart Regebro: Python, Plone, Web - http://regebro.wordpress.com/2010/10/09/is-there-a-better-python-ide/&lt;br /&gt;
: I’m currently a user of WingIDE, but sometimes I feel the need for something better, mainly something that is a bit more stable. WingIDE often hangs when switching projects, sometimes the file listing decides that you must double-click on the expand arrow instead of just click on it, etc. It still doesn’t have macros despite this being a much requested feature (how hard can it be to add, really?) and I never really get the hang of the SVN integration, so I just ignore it. And they keep recommending me to use WingIDE’s separate instance of GTK instead of the System GTK, which is daft. Their designs are ugly, and it should work with the system GTK so it looks the same. Anything else is just silly.&lt;br /&gt;
&lt;br /&gt;
=== Open Komodo ===&lt;br /&gt;
&lt;br /&gt;
Open Komodo - http://www.openkomodo.com/&lt;br /&gt;
: Open Komodo is the source code repository for Komodo Edit - a free multi-language editor for dynamic languages, based on the award-winning Komodo IDE. ActiveState created the Open Komodo code repository in August 2007 and it has been used since then for building all Komodo Edit releases.&lt;br /&gt;
&lt;br /&gt;
=== Eclipse ===&lt;br /&gt;
&lt;br /&gt;
Build an Eclipse development environment for Perl, Python, and PHP - http://www.eclipse.org/resources/resource.php?id=485&lt;br /&gt;
: This tutorial shows how Eclipse&#039;s DLTK makes it possible to build development tools for scripting languages. In particular, it explains how to implement syntax coloring, user preferences, and interpreter integration in a plug-in-based project.&lt;br /&gt;
&lt;br /&gt;
See [[#PyDev]]&lt;br /&gt;
&lt;br /&gt;
=== EasyEclipse ===&lt;br /&gt;
&lt;br /&gt;
EasyEclipse - http://www.easyeclipse.org/&lt;br /&gt;
:EasyEclipse packages together Eclipse, the open-source software&lt;br /&gt;
development platform, and selected open source plugins.&lt;br /&gt;
:We select, assemble, test, patch, build installers and document&lt;br /&gt;
a full IDE, offered as reliable distributions and plugins.&lt;br /&gt;
:EasyEclipse is:&lt;br /&gt;
* Free and open-source,&lt;br /&gt;
* Easy to download and install, and&lt;br /&gt;
* Simple to maintain, without version and dependency issues.&lt;br /&gt;
&lt;br /&gt;
EasyEclipse for Python - http://www.easyeclipse.org/site/distributions/python.html&lt;br /&gt;
&lt;br /&gt;
EclipsePythonIntegration - PythonInfo Wiki - http://wiki.python.org/moin/EclipsePythonIntegration&lt;br /&gt;
: Using Eclipse as a Python editor&lt;br /&gt;
&lt;br /&gt;
=== PyDev ===&lt;br /&gt;
&lt;br /&gt;
PyDev - http://pydev.org/&lt;br /&gt;
: PyDev is a Python IDE for Eclipse, which may be used in Python, Jython and IronPython development.&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
Pydev - http://pydev.sourceforge.net/ (old link)&lt;br /&gt;
&lt;br /&gt;
How to Configure Eclipse for Python - http://www.rose-hulman.edu/class/csse/resources/Eclipse/eclipse-python-configuration.htm&lt;br /&gt;
&lt;br /&gt;
Python Development with PyDev and Eclipse - Tutorial - http://www.vogella.de/articles/Python/article.html&lt;br /&gt;
: This article describes how to write and debug Python programs with Eclipse&lt;br /&gt;
&lt;br /&gt;
PyDev Getting Started - http://pydev.org/manual_101_root.html&lt;br /&gt;
&lt;br /&gt;
Running a program - http://pydev.org/manual_101_run.html&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
Supported Task Tags:&lt;br /&gt;
* TODO:&lt;br /&gt;
* TASK:&lt;br /&gt;
* FIXME:&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
Installation:&lt;br /&gt;
# Platform Runtime Binary (download around 45-50 MB) - http://download.eclipse.org/eclipse/downloads/ or http://www.eclipse.org/downloads/&lt;br /&gt;
#* Example: Eclipse Classic 4.2.2&lt;br /&gt;
# Eclipse Software Add - PyDev: http://pydev.org/updates&lt;br /&gt;
# Eclipse Software Add - MercurialEclipse: http://cbes.javaforge.com/update  [http://javaforge.com/project/HGE] [http://mercurial.selenic.com/wiki/MercurialEclipse]&lt;br /&gt;
# Switch perspectives to PyDev&lt;br /&gt;
&lt;br /&gt;
=== The Eric Python IDE ===&lt;br /&gt;
&lt;br /&gt;
The Eric Python IDE - http://eric-ide.python-projects.org/&lt;br /&gt;
:Eric is a full featured Python and Ruby editor and IDE, written in python. It is based on the cross platform Qt gui toolkit, integrating the highly flexible Scintilla editor control. It is designed to be usable as everdays&#039; quick and dirty editor as well as being usable as a professional project management tool integrating many advanced features Python offers the professional coder. eric4 includes a plugin system, which allows easy extension of the IDE functionality with plugins downloadable from the net.&lt;br /&gt;
&lt;br /&gt;
Eric Python IDE - Wikipedia - http://en.wikipedia.org/wiki/Eric_Python_IDE&lt;br /&gt;
&lt;br /&gt;
=== Wingware Python IDE ===&lt;br /&gt;
&lt;br /&gt;
The Intelligent Development Environment for Python Programmers - Wingware Python IDE - http://www.wingware.com/&lt;br /&gt;
:Wingware&#039;s Python IDE is an Integrated Development Environment designed specifically for the Python programming language. Since 1999, Wingware has focused on Python.&lt;br /&gt;
&lt;br /&gt;
=== VIM ===&lt;br /&gt;
&lt;br /&gt;
Python .vimrc:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;quot; Kenneth&#039;s Preferences&lt;br /&gt;
&lt;br /&gt;
set nobackup            &amp;quot; don&#039;t create backup files&lt;br /&gt;
&amp;quot;set nohlsearch          &amp;quot; don&#039;t highlight search results&lt;br /&gt;
set hlsearch            &amp;quot; do highlight search results&lt;br /&gt;
set incsearch           &amp;quot; incremental search&lt;br /&gt;
set ignorecase          &amp;quot; ignore case during search&lt;br /&gt;
set smartcase           &amp;quot; do case sensitive search when upper case is typed&lt;br /&gt;
set shiftwidth=4        &amp;quot; shift blocks in 4 space increments&lt;br /&gt;
set tabstop=4           &amp;quot; the (typewriter) tab stops are every 4 spaces&lt;br /&gt;
set smarttab            &amp;quot; tab at beginning of line inserts 4 spaces (shiftwidth)&lt;br /&gt;
set showmatch           &amp;quot; briefly highlight matching bracket&lt;br /&gt;
set matchtime=1         &amp;quot; highlight match for 0.1 seconds&lt;br /&gt;
set background=dark     &amp;quot; black background&lt;br /&gt;
set shiftwidth=4        &amp;quot; shift blocks by 4 spaces&lt;br /&gt;
set shortmess=at        &amp;quot; use short messages so we don&#039;t have to hit enter&lt;br /&gt;
set expandtab           &amp;quot; expand tabs into spaces&lt;br /&gt;
set scrolloff=5         &amp;quot; always show 5 lines before &amp;amp; after cursor&lt;br /&gt;
set shell=bash          &amp;quot; use bash for the command shell&lt;br /&gt;
set shellcmdflag=-lc    &amp;quot; make bash startup as a login shell for ~/.bashrc&lt;br /&gt;
&amp;quot;set nowrap              &amp;quot; do not wrap long lines&lt;br /&gt;
set visualbell          &amp;quot; flash the screen rather than beep&lt;br /&gt;
set noerrorbells        &amp;quot; don&#039;t beep on errors&lt;br /&gt;
set wildmenu            &amp;quot; enable filename tab completion&lt;br /&gt;
set ruler               &amp;quot; display the ruler: shows cursor position&lt;br /&gt;
set cpoptions+=$        &amp;quot; display &#039;$&#039; at end of cw sequence&lt;br /&gt;
set title               &amp;quot; display filename and vim info in window title bar&lt;br /&gt;
set modelines=5         &amp;quot; search the first and last 5 lines for &amp;quot;vim:&amp;quot; modeline&lt;br /&gt;
set backspace=2         &amp;quot; backspace deletes&lt;br /&gt;
&lt;br /&gt;
set wildignore=*.o,*.class,*.pyc,*.pyo,*.a,*.so,*.dll,*.exe,core,*.jar,*.zip&lt;br /&gt;
&lt;br /&gt;
&amp;quot;let loaded_matchparen = 1 &amp;quot; don&#039;t highlight parenthesis match&lt;br /&gt;
&lt;br /&gt;
filetype indent on&lt;br /&gt;
&lt;br /&gt;
&amp;quot;if v:version &amp;gt; 700&lt;br /&gt;
&amp;quot;    set cursorline          &amp;quot; underline the current line&lt;br /&gt;
&amp;quot;endif&lt;br /&gt;
&lt;br /&gt;
if &amp;amp;t_Co &amp;gt; 2 || has( &amp;quot;gui_running&amp;quot; )&lt;br /&gt;
    syntax on&lt;br /&gt;
endif&lt;br /&gt;
&lt;br /&gt;
if has( &#039;mouse&#039; )&lt;br /&gt;
    set mouse=a &amp;quot; enable mouse&lt;br /&gt;
endif&lt;br /&gt;
&lt;br /&gt;
if has( &amp;quot;autocmd&amp;quot; )&lt;br /&gt;
    &amp;quot; open the file in the last place we were editing&lt;br /&gt;
    autocmd BufReadPost *&lt;br /&gt;
        \ if line(&amp;quot;&#039;\&amp;quot;&amp;quot;) &amp;gt; 1 &amp;amp;&amp;amp; line(&amp;quot;&#039;\&amp;quot;&amp;quot;) &amp;lt;= line(&amp;quot;$&amp;quot;) |&lt;br /&gt;
        \     exe &amp;quot;normal! g&#039;\&amp;quot;&amp;quot; |&lt;br /&gt;
        \ endif&lt;br /&gt;
endif&lt;br /&gt;
&lt;br /&gt;
&amp;quot;folding settings&lt;br /&gt;
set foldmethod=indent   &amp;quot;fold based on indent&lt;br /&gt;
set foldnestmax=10      &amp;quot;deepest fold is 10 levels&lt;br /&gt;
set nofoldenable        &amp;quot;dont fold by default&lt;br /&gt;
set foldlevel=10        &amp;quot;this is just what i use&lt;br /&gt;
&lt;br /&gt;
&amp;quot; Auto clear trailing white space in Python files&lt;br /&gt;
func! DeleteTrailingWS()&lt;br /&gt;
    exec &amp;quot;normal mz&amp;quot;&lt;br /&gt;
    %s/\s\+$//ge&lt;br /&gt;
    exe &amp;quot;normal `z&amp;quot;&lt;br /&gt;
endfunc&lt;br /&gt;
autocmd BufWrite *.py :call DeleteTrailingWS()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Older versions:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;quot; KENNETH SETTINGS&lt;br /&gt;
set nocp                &amp;quot; turn off compatibility mode&lt;br /&gt;
set nomodeline          &amp;quot; do not allow files to dictate vim behavior&lt;br /&gt;
&lt;br /&gt;
set incsearch           &amp;quot; incremental search&lt;br /&gt;
set ignorecase          &amp;quot; ignore case during search&lt;br /&gt;
&lt;br /&gt;
set visualbell          &amp;quot; flash the screen rather than beep&lt;br /&gt;
set noerrorbells        &amp;quot; don&#039;t beep on errors&lt;br /&gt;
set background=dark     &amp;quot; black background&lt;br /&gt;
syntax on               &amp;quot; turn on syntax highlighting&lt;br /&gt;
set hlsearch            &amp;quot; highligh last search pattern&lt;br /&gt;
&lt;br /&gt;
set nowrap              &amp;quot; do not wrap long lines&lt;br /&gt;
set scrolloff=5         &amp;quot; always show 5 lines before &amp;amp; after cursor&lt;br /&gt;
set ruler               &amp;quot; show the cursor position all the time&lt;br /&gt;
set backspace=2         &amp;quot; allow backspace deletion&lt;br /&gt;
set bs=indent,eol,start &amp;quot; allow backspacing over everything in insert mode&lt;br /&gt;
&lt;br /&gt;
set shiftwidth=4        &amp;quot; shift blocks in 4 space increments&lt;br /&gt;
set tabstop=4           &amp;quot; the (typewriter) tab stops are every 4 spaces&lt;br /&gt;
set expandtab           &amp;quot; expand tab into spaces&lt;br /&gt;
set smarttab            &amp;quot; tab at beginning of line inserts 4 spaces (shiftwidth)&lt;br /&gt;
filetype indent on      &amp;quot; turn on auto indent for specific file types&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Other options:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
set number              &amp;quot; show line numbers&lt;br /&gt;
set numberwidth=1       &amp;quot; remove space before largest line numbers&lt;br /&gt;
&lt;br /&gt;
set smartindent         &amp;quot; ?? - maybe included in &#039;filetype indent on&#039;&lt;br /&gt;
&lt;br /&gt;
set ai                  &amp;quot; always auto indent&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
if has( &amp;quot;autocmd&amp;quot; )&lt;br /&gt;
    &amp;quot; open the file in the last place we were editing&lt;br /&gt;
    autocmd BufReadPost *&lt;br /&gt;
        \ if line(&amp;quot;&#039;\&amp;quot;&amp;quot;) &amp;gt; 1 &amp;amp;&amp;amp; line(&amp;quot;&#039;\&amp;quot;&amp;quot;) &amp;lt;= line(&amp;quot;$&amp;quot;) |&lt;br /&gt;
        \     exe &amp;quot;normal! g&#039;\&amp;quot;&amp;quot; |&lt;br /&gt;
        \ endif&lt;br /&gt;
endif&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Kenneth&#039;s fio .vimrc:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;quot;source $VIM/mswin.vim&lt;br /&gt;
&lt;br /&gt;
set nobackup            &amp;quot; don&#039;t create backup files&lt;br /&gt;
&amp;quot;set nohlsearch          &amp;quot; don&#039;t highlight search results&lt;br /&gt;
set incsearch           &amp;quot; incremental search&lt;br /&gt;
set ignorecase          &amp;quot; ignore case during search&lt;br /&gt;
set smartcase           &amp;quot; do case sensitive search when upper case is typed&lt;br /&gt;
set shiftwidth=4        &amp;quot; shift blocks in 4 space increments&lt;br /&gt;
set tabstop=4           &amp;quot; the (typewriter) tab stops are every 4 spaces&lt;br /&gt;
set smarttab            &amp;quot; tab at beginning of line inserts 4 spaces (shiftwidth)&lt;br /&gt;
set showmatch           &amp;quot; briefly highlight matching bracket&lt;br /&gt;
set matchtime=1         &amp;quot; highlight match for 0.1 seconds&lt;br /&gt;
set background=dark     &amp;quot; black background&lt;br /&gt;
set shiftwidth=4        &amp;quot; shift blocks by 4 spaces&lt;br /&gt;
set shortmess=at        &amp;quot; use short messages so we don&#039;t have to hit enter&lt;br /&gt;
set expandtab           &amp;quot; expand tabs into spaces&lt;br /&gt;
set scrolloff=5         &amp;quot; always show 5 lines before &amp;amp; after cursor&lt;br /&gt;
set shell=bash          &amp;quot; use bash for the command shell&lt;br /&gt;
set shellcmdflag=-lc    &amp;quot; make bash startup as a login shell for ~/.bashrc&lt;br /&gt;
&amp;quot;set nowrap              &amp;quot; do not wrap long lines&lt;br /&gt;
set visualbell          &amp;quot; flash the screen rather than beep&lt;br /&gt;
set noerrorbells        &amp;quot; don&#039;t beep on errors&lt;br /&gt;
set wildmenu            &amp;quot; enable filename tab completion&lt;br /&gt;
set ruler               &amp;quot; display the ruler: shows cursor position&lt;br /&gt;
set cpoptions+=$        &amp;quot; display &#039;$&#039; at end of cw sequence&lt;br /&gt;
set title               &amp;quot; display filename and vim info in window title bar&lt;br /&gt;
set modelines=5         &amp;quot; search the first and last 5 lines for &amp;quot;vim:&amp;quot; modeline&lt;br /&gt;
&lt;br /&gt;
set wildignore=*.o,*.class,*.pyc,*.pyo,*.a,*.so,*.dll,*.exe,core,*.jar,*.zip&lt;br /&gt;
&lt;br /&gt;
&amp;quot;let loaded_matchparen = 1 &amp;quot; don&#039;t highlight parenthesis match&lt;br /&gt;
&lt;br /&gt;
filetype indent on&lt;br /&gt;
&lt;br /&gt;
if v:version &amp;gt; 700&lt;br /&gt;
    set cursorline          &amp;quot; underline the current line&lt;br /&gt;
endif&lt;br /&gt;
&lt;br /&gt;
if &amp;amp;t_Co &amp;gt; 2 || has( &amp;quot;gui_running&amp;quot; )&lt;br /&gt;
    syntax on&lt;br /&gt;
endif&lt;br /&gt;
&lt;br /&gt;
if has( &#039;mouse&#039; )&lt;br /&gt;
    set mouse=a &amp;quot; enable mouse&lt;br /&gt;
endif&lt;br /&gt;
&lt;br /&gt;
if has( &amp;quot;autocmd&amp;quot; )&lt;br /&gt;
    &amp;quot; open the file in the last place we were editing&lt;br /&gt;
    autocmd BufReadPost *&lt;br /&gt;
        \ if line(&amp;quot;&#039;\&amp;quot;&amp;quot;) &amp;gt; 1 &amp;amp;&amp;amp; line(&amp;quot;&#039;\&amp;quot;&amp;quot;) &amp;lt;= line(&amp;quot;$&amp;quot;) |&lt;br /&gt;
        \     exe &amp;quot;normal! g&#039;\&amp;quot;&amp;quot; |&lt;br /&gt;
        \ endif&lt;br /&gt;
endif&lt;br /&gt;
&lt;br /&gt;
&amp;quot;folding settings&lt;br /&gt;
set foldmethod=indent   &amp;quot;fold based on indent&lt;br /&gt;
set foldnestmax=10      &amp;quot;deepest fold is 10 levels&lt;br /&gt;
set nofoldenable        &amp;quot;dont fold by default&lt;br /&gt;
set foldlevel=10        &amp;quot;this is just what i use&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Interpreter vs Script ==&lt;br /&gt;
&lt;br /&gt;
Interpreter:&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; import os&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; os.uname()&lt;br /&gt;
 (&#039;Linux&#039;, &#039;demo.oeey.com&#039;, &#039;2.6.18-194.8.1.el5&#039;, &#039;#1 SMP Thu Jul 1 19:07:06 EDT 2010&#039;, &#039;i686&#039;)&lt;br /&gt;
&lt;br /&gt;
Script:&lt;br /&gt;
 #!/usr/bin/env python&lt;br /&gt;
 import os&lt;br /&gt;
 print os.uname()&lt;br /&gt;
&lt;br /&gt;
== Web Development ==&lt;br /&gt;
&lt;br /&gt;
WebProgramming - PythonInfo Wiki - http://wiki.python.org/moin/WebProgramming&lt;br /&gt;
: This topic guide attempts to cover every aspect of programming Web applications (both clients and servers) using Python. &lt;br /&gt;
&lt;br /&gt;
HOWTO Use Python in the web — Python v2.7.2 documentation - http://docs.python.org/howto/webservers.html&lt;br /&gt;
: This document shows how Python fits into the web. It presents some ways to integrate Python with a web server, and general practices useful for developing web sites.&lt;br /&gt;
&lt;br /&gt;
=== Plug Simple Python Web App ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
-------- Original Message --------&lt;br /&gt;
Subject: 	Re: Writing a simple python web app&lt;br /&gt;
Date: 	Mon, 25 Oct 2010 19:03:31 -0400&lt;br /&gt;
From: 	Roberto Mello &amp;lt;roberto.mello@gmail.com&amp;gt;&lt;br /&gt;
To: 	Provo Linux Users Group &amp;lt;plug@plug.org&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
On Sat, Sep 11, 2010 at 5:40 PM, Dave Smith &amp;lt;dave@thesmithfam.org&amp;gt; wrote:&lt;br /&gt;
&amp;gt; I&#039;m creating a very simple web application, and I want to use python. My first guess was that mod_python&lt;br /&gt;
would provide the easiest entry point. Boy, was I wrong. All the mod_python tutorials spend 80% of their&lt;br /&gt;
time extolling the virtues of mod_python over CGI, but they are quite lean on specific examples. It&#039;s quite&lt;br /&gt;
disappointing. A natural progression then leads me to mod_wsgi, and since that has equally poor&lt;br /&gt;
documentation, to Django. However, Django is overkill for my app (I don&#039;t even have a database).&lt;br /&gt;
&lt;br /&gt;
For something as simple as you have described, and to run on an&lt;br /&gt;
embedded platform, I would probably stay away from frameworks designed&lt;br /&gt;
to run on full hardware, and go with something more minimalistic.&lt;br /&gt;
&lt;br /&gt;
Take a look at CherryPy [1] or web.py [2].&lt;br /&gt;
&lt;br /&gt;
[1] http://www.cherrypy.org/&lt;br /&gt;
[2] http://webpy.org/&lt;br /&gt;
&lt;br /&gt;
Roberto Mello&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
See also [[web.py]]&lt;br /&gt;
&lt;br /&gt;
See also [[CherryPy]]&lt;br /&gt;
&lt;br /&gt;
See also [[Django]]&lt;br /&gt;
&lt;br /&gt;
=== Apache CGI ===&lt;br /&gt;
&lt;br /&gt;
See [[CGI]]&lt;br /&gt;
&lt;br /&gt;
Great tutorial: https://www.tutorialspoint.com/python/python_cgi_programming.htm&lt;br /&gt;
&lt;br /&gt;
My favorite option, make all .cgi files executable: (or .py)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 DirectoryIndex index.html index.php index.py&lt;br /&gt;
 &amp;lt;Location /&amp;gt;&lt;br /&gt;
   # AddHandler cgi-script .cgi&lt;br /&gt;
   AddHandler cgi-script .py&lt;br /&gt;
   Options +ExecCGI &lt;br /&gt;
 &amp;lt;/Location&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you want to allow .htaccess:&lt;br /&gt;
* see [[Apache#.htaccess]]&lt;br /&gt;
&lt;br /&gt;
To enable on Ubuntu:&lt;br /&gt;
 sudo a2enmod cgi&lt;br /&gt;
 service apache2 restart&lt;br /&gt;
&lt;br /&gt;
Directory index:&lt;br /&gt;
 DirectoryIndex index.py&lt;br /&gt;
&lt;br /&gt;
Or if you really want to go crazy, this will try to run *every* file: [http://blog.kapsobor.de/archives/2006/09/05/apache_addhandler_multiple_extensions/]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    # this has problems with / directory being run as a script, instead of index too!&lt;br /&gt;
    #&amp;lt;Location /&amp;gt;&lt;br /&gt;
    #    SetHandler cgi-script&lt;br /&gt;
    #    Options +ExecCGI&lt;br /&gt;
    #&amp;lt;/Location&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;Files ~ &amp;quot;.&amp;quot;&amp;gt;&lt;br /&gt;
        SetHandler cgi-script&lt;br /&gt;
        Options +ExecCGI&lt;br /&gt;
    &amp;lt;/Files&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    &amp;lt;Files ~ &amp;quot;^.[a-zA-Z]*$&amp;quot;&amp;gt;&lt;br /&gt;
        SetHandler cgi-script&lt;br /&gt;
        Options +ExecCGI&lt;br /&gt;
    &amp;lt;/Files&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Or just have index file:&lt;br /&gt;
    &amp;lt;Files &amp;quot;index&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: Place within a &amp;lt;VirtualHost&amp;gt; section if needed.&lt;br /&gt;
&lt;br /&gt;
Note: Make sure to &#039;chmod +x&#039; the files.&lt;br /&gt;
&lt;br /&gt;
Start all HTML output with:&lt;br /&gt;
 print &amp;quot;Content-Type: text/html\n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If you want just text output:&lt;br /&gt;
 print &amp;quot;Content-Type: text/plain\n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
GET (from Environment):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
print &amp;quot;&amp;amp;lt;pre&amp;gt;&amp;quot;&lt;br /&gt;
for env in os.environ:&lt;br /&gt;
    print &amp;quot;%s = %s&amp;quot; % (env, os.environ[env])&lt;br /&gt;
print &amp;quot;&amp;amp;lt;/pre&amp;gt;&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# sample for: http://oeey.com/py/test.py/test?var1=ken&amp;amp;var2=barbie&lt;br /&gt;
&lt;br /&gt;
REQUEST_URI = /py/index.py/test?var1=ken&amp;amp;var2=barbie&lt;br /&gt;
QUERY_STRING = var1=ken&amp;amp;var2=barbie&lt;br /&gt;
PATH_INFO = /test&lt;br /&gt;
REQUEST_METHOD = GET&lt;br /&gt;
&lt;br /&gt;
SCRIPT_NAME = /py/test.py&lt;br /&gt;
SERVER_NAME = oeey.com&lt;br /&gt;
REMOTE_ADDR = 216.51.42.66&lt;br /&gt;
SERVER_ADDR = 192.168.108.4&lt;br /&gt;
DOCUMENT_ROOT = /www/py&lt;br /&gt;
SCRIPT_FILENAME = /www/py/test.py&lt;br /&gt;
HTTP_HOST = cgi.oeey.com&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
POST (from stdin):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
post = sys.stdin.readline()&lt;br /&gt;
if post:&lt;br /&gt;
    print post&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CONTENT_TYPE = application/x-www-form-urlencoded&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
yin=one+two+three&amp;amp;yang=four+five+six&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
cgi helper class:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import cgi&lt;br /&gt;
&lt;br /&gt;
print &amp;quot;Content-Type: text/html\n\n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
form = cgi.FieldStorage()&lt;br /&gt;
&lt;br /&gt;
# field keys&lt;br /&gt;
print &amp;quot;fields keys: &amp;quot;, form.keys()  # list of field keys&lt;br /&gt;
&lt;br /&gt;
# fild values&lt;br /&gt;
if &amp;quot;name&amp;quot; in form:  # if form.has_key(&#039;name&#039;):&lt;br /&gt;
    print &amp;quot;field &#039;name&#039; is: &amp;quot;, form[&amp;quot;name&amp;quot;].value&lt;br /&gt;
    print &amp;quot;field &#039;name&#039; is: &amp;quot;, form.getvalue(&#039;name&#039;)&lt;br /&gt;
&lt;br /&gt;
# headers&lt;br /&gt;
print &amp;quot;dictionary of headers: &amp;quot;, form.headers&lt;br /&gt;
print form.type&lt;br /&gt;
print form.headers[&#039;content-type&#039;]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To prevent XSS escape the characters:&lt;br /&gt;
  print cgi.escape(form.getvalue(&#039;name&#039;))&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import cgi&lt;br /&gt;
&lt;br /&gt;
print &amp;quot;Content-Type: text/html\n\n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
form = cgi.FieldStorage()&lt;br /&gt;
if (form.has_key(&amp;quot;action&amp;quot;) and form.has_key(&amp;quot;name&amp;quot;) \&lt;br /&gt;
        and form.has_key(&amp;quot;age&amp;quot;)):&lt;br /&gt;
    if (form[&amp;quot;action&amp;quot;].value == &amp;quot;display&amp;quot;):&lt;br /&gt;
        print &amp;quot;%s = %s&amp;quot; % (form[&amp;quot;name&amp;quot;].value form[&amp;quot;age&amp;quot;].value)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: cgi helper class also does sessions and cookies.&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* CGI Tutorial | Web Python - http://webpython.codepoint.net/cgi_tutorial&lt;br /&gt;
* Python CGI: An Interactive Instruction - http://www.cs.virginia.edu/~lab2q/&lt;br /&gt;
&lt;br /&gt;
See also:&lt;br /&gt;
* Web Python - http://webpython.codepoint.net/&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
REST Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import os, re&lt;br /&gt;
def get_rest():&lt;br /&gt;
    if not &amp;quot;PATH_INFO&amp;quot; in os.environ:&lt;br /&gt;
        return ()&lt;br /&gt;
    # filter for garbage&lt;br /&gt;
    #print os.environ[&amp;quot;PATH_INFO&amp;quot;]&lt;br /&gt;
    path_info = re.findall(&#039;[/A-Za-z0-9_-]*&#039;, os.environ[&amp;quot;PATH_INFO&amp;quot;])&lt;br /&gt;
    if not path_info:&lt;br /&gt;
        return ()&lt;br /&gt;
    path_info = &#039;&#039;.join(path_info)&lt;br /&gt;
    # collapse empty paths&lt;br /&gt;
    paths = path_info.split(&#039;/&#039;)&lt;br /&gt;
    final_paths = []&lt;br /&gt;
    for path in paths:&lt;br /&gt;
        if path:&lt;br /&gt;
            final_paths.append(path)&lt;br /&gt;
    return tuple(final_paths)&lt;br /&gt;
rest = get_rest();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== mod_python ===&lt;br /&gt;
&lt;br /&gt;
AVOID! AVOID! AVOID! - if you want this simple, just use CGI!&lt;br /&gt;
&lt;br /&gt;
See [[Apache mod_python]]&lt;br /&gt;
&lt;br /&gt;
mod_python - http://docs.python.org/howto/webservers.html#mod-python&lt;br /&gt;
&lt;br /&gt;
Install:&lt;br /&gt;
 yum install mod_python&lt;br /&gt;
&lt;br /&gt;
Config:&lt;br /&gt;
 /etc/httpd/conf.d/python.conf&lt;br /&gt;
&lt;br /&gt;
Simple:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;quot;People coming from PHP often find it hard to grasp how to use Python in the web. Their first thought is mostly mod_python, because they think that this is the equivalent to mod_php. Actually, there are many differences. What mod_python does is embed the interpreter into the Apache process, thus speeding up requests by not having to start a Python interpreter for each request. On the other hand, it is not “Python intermixed with HTML” in the way that PHP is often intermixed with HTML. The Python equivalent of that is a template engine. mod_python itself is much more powerful and provides more access to Apache internals. It can emulate CGI, work in a “Python Server Pages” mode (similar to JSP) which is “HTML intermingled with Python”, and it has a “Publisher” which designates one file to accept all requests and decide what to do with them.&lt;br /&gt;
&lt;br /&gt;
:mod_python does have some problems. Unlike the PHP interpreter, the Python interpreter uses caching when executing files, so changes to a file will require the web server to be restarted. Another problem is the basic concept – Apache starts child processes to handle the requests, and unfortunately every child process needs to load the whole Python interpreter even if it does not use it. This makes the whole web server slower. Another problem is that, because mod_python is linked against a specific version of libpython, it is not possible to switch from an older version to a newer (e.g. 2.4 to 2.5) without recompiling mod_python. mod_python is also bound to the Apache web server, so programs written for mod_python cannot easily run on other web servers.&lt;br /&gt;
&lt;br /&gt;
:These are the reasons why mod_python should be avoided when writing new programs. In some circumstances it still might be a good idea to use mod_python for deployment, but WSGI makes it possible to run WSGI programs under mod_python as well.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== WSGI ===&lt;br /&gt;
&lt;br /&gt;
WSGI - http://docs.python.org/howto/webservers.html#mod-wsgi&lt;br /&gt;
&lt;br /&gt;
: &amp;quot;The Web Server Gateway Interface, or WSGI for short, is defined in PEP 333 and is currently the best way to do Python web programming. While it is great for programmers writing frameworks, a normal web developer does not need to get in direct contact with it. When choosing a framework for web development it is a good idea to choose one which supports WSGI.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
See [[mod_wsgi]]&lt;br /&gt;
&lt;br /&gt;
=== Django ===&lt;br /&gt;
&lt;br /&gt;
See [[Django]]&lt;br /&gt;
&lt;br /&gt;
=== CherryPy ===&lt;br /&gt;
&lt;br /&gt;
See [[CherryPy]]&lt;br /&gt;
&lt;br /&gt;
=== web.py ===&lt;br /&gt;
&lt;br /&gt;
web.py: makes web apps&lt;br /&gt;
&lt;br /&gt;
Think about the ideal way to write a web app. Write the code to make it happen.&lt;br /&gt;
&lt;br /&gt;
web.py : Python Package Index - http://pypi.python.org/pypi/web.py&lt;br /&gt;
&lt;br /&gt;
Home Page: http://webpy.org/&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Django lets you write web apps in Django. TurboGears lets you write web apps in TurboGears. Web.py lets you write web apps in Python.&amp;quot;&lt;br /&gt;
:—  Adam Atlas&lt;br /&gt;
&lt;br /&gt;
NOTE: Can modify source code without having to restart app!  :-)&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
PIP Install:&lt;br /&gt;
 pip install web.py&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
Hello World: [http://webpy.org/]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import web&lt;br /&gt;
        &lt;br /&gt;
urls = (&lt;br /&gt;
    &#039;/(.*)&#039;, &#039;hello&#039;&lt;br /&gt;
)&lt;br /&gt;
app = web.application(urls, globals())&lt;br /&gt;
&lt;br /&gt;
class hello:        &lt;br /&gt;
    def GET(self, name):&lt;br /&gt;
        if not name: &lt;br /&gt;
            name = &#039;World&#039;&lt;br /&gt;
        return &#039;Hello, &#039; + name + &#039;!&#039;&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
    app.run()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: app.py can be renamed.&lt;br /&gt;
&lt;br /&gt;
Running:&lt;br /&gt;
 python app.py&lt;br /&gt;
&lt;br /&gt;
Note: You can add an IP address/port after the &amp;quot;app.py&amp;quot; bit to control where web.py launches the server. You can also tell it to run a fastcgi or scgi server.&lt;br /&gt;
 python app.py 1234&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
Templates&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# templates/hello.html&lt;br /&gt;
$def with (name)&lt;br /&gt;
&lt;br /&gt;
$if name:&lt;br /&gt;
    I just wanted to say &amp;lt;em&amp;gt;hello&amp;lt;/em&amp;gt; to $name.&lt;br /&gt;
$else:&lt;br /&gt;
    &amp;lt;em&amp;gt;Hello&amp;lt;/em&amp;gt;, world!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 app = ...&lt;br /&gt;
 render = web.template.render(&#039;templates/&#039;)&lt;br /&gt;
&lt;br /&gt;
index.GET:&lt;br /&gt;
 name = &#039;Bob&#039;    &lt;br /&gt;
 return render.hello(name)  # render.[TEMPLATE_NAME](vars)&lt;br /&gt;
&lt;br /&gt;
get variable: (/?name=Joe)&lt;br /&gt;
 i = web.input(name=None)&lt;br /&gt;
 return render.hello(i.name)&lt;br /&gt;
&lt;br /&gt;
variable in url:&lt;br /&gt;
 urls = (&#039;/(.*)&#039;, &#039;hello&#039;)&lt;br /&gt;
&lt;br /&gt;
 class index:&lt;br /&gt;
     def GET(self, name):&lt;br /&gt;
        return render.hello(name)&lt;br /&gt;
&lt;br /&gt;
 # visit: /Joe&lt;br /&gt;
&lt;br /&gt;
multiple variables in url:&lt;br /&gt;
 urls = (&#039;/(.*)/(.*)&#039;, &#039;hello&#039;)&lt;br /&gt;
&lt;br /&gt;
  class hello:&lt;br /&gt;
    def GET(self, fname, lname):&lt;br /&gt;
        return render.hello(fname, lname)&lt;br /&gt;
&lt;br /&gt;
 # visit: /Joe/Smith&lt;br /&gt;
&lt;br /&gt;
=== lpthw.web ===&lt;br /&gt;
&lt;br /&gt;
lpthw.web: a fork of web.py for Learn Python The Hard Way&lt;br /&gt;
&lt;br /&gt;
Locks web.py at a specific version and removes some magic. Thanks to Aaron Swartz for making it originally.&lt;br /&gt;
&lt;br /&gt;
lpthw.web: a fork of web.py for Learn Python The Hard Way - http://pypi.python.org/pypi/lpthw.web&lt;br /&gt;
&lt;br /&gt;
Home Page: http://learnpythonthehardway.org/&lt;br /&gt;
&lt;br /&gt;
This conflicts with web.py, so only install one.&lt;br /&gt;
&lt;br /&gt;
=== web ===&lt;br /&gt;
&lt;br /&gt;
web - Web modules for CGI and WSGI web programming&lt;br /&gt;
&lt;br /&gt;
web : Python Package Index - http://pypi.python.org/pypi/web&lt;br /&gt;
&lt;br /&gt;
Warning: This is an alpha release for those who are interested in&lt;br /&gt;
    checking progress. No documentation and not for production use.&lt;br /&gt;
&lt;br /&gt;
Auth, session, mail, form and templating tools for writing CGI scripts or WSGI web applications.&lt;br /&gt;
&lt;br /&gt;
This version incompatible with previous versions becuase large portions of the code have been refactored into separate components.&lt;br /&gt;
&lt;br /&gt;
== Issues ==&lt;br /&gt;
&lt;br /&gt;
=== Hide DeprecationWarning ===&lt;br /&gt;
&lt;br /&gt;
==== Import DeprecationWarning ====&lt;br /&gt;
&lt;br /&gt;
Error:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/opt/xmpppy-0.4.1/xmpp/auth.py:24: DeprecationWarning: the sha module is deprecated; use the hashlib module instead&lt;br /&gt;
  import sha,base64,random,dispatcher,re&lt;br /&gt;
/opt/xmpppy-0.4.1/xmpp/auth.py:26: DeprecationWarning: the md5 module is deprecated; use hashlib instead&lt;br /&gt;
  import md5&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hide deprecation warnings with code: [http://stackoverflow.com/questions/879173/how-to-ignore-deprecation-warnings-in-python]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import warnings&lt;br /&gt;
&lt;br /&gt;
with warnings.catch_warnings():&lt;br /&gt;
    warnings.filterwarnings(&amp;quot;ignore&amp;quot;,category=DeprecationWarning)&lt;br /&gt;
    import md5, sha&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hide with header:&lt;br /&gt;
 #!/usr/bin/env python -W ignore::DeprecationWarning&lt;br /&gt;
&lt;br /&gt;
Hide from command line:&lt;br /&gt;
 python -W ignore::DeprecationWarning script.py&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* How to ignore deprecation warnings in Python - Stack Overflow - http://stackoverflow.com/questions/879173/how-to-ignore-deprecation-warnings-in-python&lt;br /&gt;
&lt;br /&gt;
==== Funciton DeprecationWarning ====&lt;br /&gt;
&lt;br /&gt;
Error:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/opt/xmpppy-0.4.1/xmpp/transports.py:307: DeprecationWarning: socket.ssl() is deprecated.  Use ssl.wrap_socket() instead.&lt;br /&gt;
  tcpsock._sslObj    = socket.ssl(tcpsock._sock, None, None)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hide with header:&lt;br /&gt;
 #!/usr/bin/env python -W ignore::DeprecationWarning&lt;br /&gt;
&lt;br /&gt;
Hide from command line:&lt;br /&gt;
 python -W ignore::DeprecationWarning script.py&lt;br /&gt;
&lt;br /&gt;
==== Ubuntu 24 pip packages ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
error: externally-managed-environment&lt;br /&gt;
&lt;br /&gt;
× This environment is externally managed&lt;br /&gt;
╰─&amp;gt; To install Python packages system-wide, try apt install&lt;br /&gt;
    python3-xyz, where xyz is the package you are trying to&lt;br /&gt;
    install.&lt;br /&gt;
&lt;br /&gt;
    If you wish to install a non-Debian-packaged Python package,&lt;br /&gt;
    create a virtual environment using python3 -m venv path/to/venv.&lt;br /&gt;
    Then use path/to/venv/bin/python and path/to/venv/bin/pip. Make&lt;br /&gt;
    sure you have python3-full installed.&lt;br /&gt;
&lt;br /&gt;
    If you wish to install a non-Debian packaged Python application,&lt;br /&gt;
    it may be easiest to use pipx install xyz, which will manage a&lt;br /&gt;
    virtual environment for you. Make sure you have pipx installed.&lt;br /&gt;
&lt;br /&gt;
    See /usr/share/doc/python3.12/README.venv for more information.&lt;br /&gt;
&lt;br /&gt;
note: If you believe this is a mistake, please contact your Python installation or OS distribution provider. You can override this, at the risk of breaking your Python installation or OS, by passing --break-system-packages.&lt;br /&gt;
hint: See PEP 668 for the detailed specification.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== keywords ==&lt;br /&gt;
&lt;br /&gt;
[[Category:Programming]]&lt;br /&gt;
[[Category:Python]]&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=Python&amp;diff=9860</id>
		<title>Python</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=Python&amp;diff=9860"/>
		<updated>2026-04-27T19:08:42Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: /* Apache CGI */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{subtop}}&lt;br /&gt;
&lt;br /&gt;
== Python ==&lt;br /&gt;
&lt;br /&gt;
Python (programming language) - Wikipedia - http://en.wikipedia.org/wiki/Python_(programming_language)&lt;br /&gt;
: Python is an interpreted, general-purpose high-level programming language whose design philosophy emphasizes code readability. Python aims to combine &amp;quot;remarkable power with very clear syntax&amp;quot;, and its standard library is large and comprehensive. Its use of indentation for block delimiters is unique among popular programming languages.&lt;br /&gt;
: Python supports multiple programming paradigms, primarily but not limited to object-oriented, imperative and, to a lesser extent, functional programming styles. It features a fully dynamic type system and automatic memory management, similar to that of Scheme, Ruby, Perl, and Tcl. Like other dynamic languages, Python is often used as a scripting language, but is also used in a wide range of non-scripting contexts.&lt;br /&gt;
: The reference implementation of Python ([http://en.wikipedia.org/wiki/CPython CPython]) is free and open source software and has a community-based development model, as do all or nearly all of its alternative implementations. CPython is managed by the non-profit Python Software Foundation.&lt;br /&gt;
: Python interpreters are available for many operating systems, and Python programs can be packaged into stand-alone executable code for many systems using various tools.&lt;br /&gt;
&lt;br /&gt;
Author:&lt;br /&gt;
:&amp;quot;Python was conceived in the late 1980s and its implementation was started in December 1989 by &#039;&#039;&#039;[http://www.python.org/~guido/ Guido van Rossum]&#039;&#039;&#039; at CWI in the Netherlands as a successor to the ABC programming language (itself inspired by SETL) capable of exception handling and interfacing with the Amoeba operating system. Van Rossum is Python&#039;s principal author, and his continuing central role in deciding the direction of Python is reflected in the title given to him by the Python community, Benevolent Dictator for Life (BDFL).&amp;quot; [http://en.wikipedia.org/wiki/Python_(programming_language)]&lt;br /&gt;
&lt;br /&gt;
Name:&lt;br /&gt;
:&amp;quot;The language is named after the BBC show “Monty Python’s Flying Circus” and has nothing to do with reptiles. Making references to Monty Python skits in documentation is not only allowed, it is encouraged!&amp;quot; [http://docs.python.org/py3k/tutorial/appetite.html]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
We as people are &amp;quot;Pythonites&amp;quot; [http://raspi.tv/2013/how-to-use-interrupts-with-python-on-the-raspberry-pi-and-rpi-gpio-part-2]&lt;br /&gt;
&lt;br /&gt;
== [http://www.python.org/dev/peps/pep-0020/ The Zen of Python] ==&lt;br /&gt;
&lt;br /&gt;
&amp;quot;The core philosophy of the language is summarized by the document &#039;PEP 20 (The Zen of Python)&#039;&amp;quot; [http://en.wikipedia.org/wiki/Python_%28programming_language%29]&lt;br /&gt;
* PEP 20 -- The Zen of Python - http://www.python.org/dev/peps/pep-0020/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Abstract&lt;br /&gt;
&lt;br /&gt;
    Long time Pythoneer Tim Peters succinctly channels the BDFL&#039;s&lt;br /&gt;
    guiding principles for Python&#039;s design into 20 aphorisms, only 19&lt;br /&gt;
    of which have been written down.&lt;br /&gt;
&lt;br /&gt;
The Zen of Python&lt;br /&gt;
&lt;br /&gt;
    Beautiful is better than ugly.&lt;br /&gt;
    Explicit is better than implicit.&lt;br /&gt;
    Simple is better than complex.&lt;br /&gt;
    Complex is better than complicated.&lt;br /&gt;
    Flat is better than nested.&lt;br /&gt;
    Sparse is better than dense.&lt;br /&gt;
    Readability counts.&lt;br /&gt;
    Special cases aren&#039;t special enough to break the rules.&lt;br /&gt;
    Although practicality beats purity.&lt;br /&gt;
    Errors should never pass silently.&lt;br /&gt;
    Unless explicitly silenced.&lt;br /&gt;
    In the face of ambiguity, refuse the temptation to guess.&lt;br /&gt;
    There should be one-- and preferably only one --obvious way to do it.&lt;br /&gt;
    Although that way may not be obvious at first unless you&#039;re Dutch.&lt;br /&gt;
    Now is better than never.&lt;br /&gt;
    Although never is often better than *right* now.&lt;br /&gt;
    If the implementation is hard to explain, it&#039;s a bad idea.&lt;br /&gt;
    If the implementation is easy to explain, it may be a good idea.&lt;br /&gt;
    Namespaces are one honking great idea -- let&#039;s do more of those!&lt;br /&gt;
&lt;br /&gt;
Easter Egg&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import this&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Other Sources:&lt;br /&gt;
* http://www.python.org/doc/humor/&lt;br /&gt;
* The Zen of Python – as a Poster « CODE POETRY - http://codepoetry.wordpress.com/2010/03/23/the-zen-of-python-as-a-poster/&lt;br /&gt;
** Zen of Python (PDF) http://codepoetry.files.wordpress.com/2010/03/zen-of-python.pdf&lt;br /&gt;
&lt;br /&gt;
== Documentation ==&lt;br /&gt;
&lt;br /&gt;
* Overview — Python v2.7.1 documentation - http://docs.python.org/index.html&lt;br /&gt;
** Download — Python v2.7.1 documentation - http://docs.python.org/download.html&lt;br /&gt;
&lt;br /&gt;
* Overview — Python v3.2 documentation - http://docs.python.org/py3k/&lt;br /&gt;
**  Download — Python v3.2 documentation - http://docs.python.org/py3k/download.html&lt;br /&gt;
&lt;br /&gt;
* PEP 8 -- Style Guide for Python Code - http://www.python.org/dev/peps/pep-0008/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Tutorials ==&lt;br /&gt;
&lt;br /&gt;
* The Python Tutorial — Python v2.7.1 documentation - http://docs.python.org/tutorial/&lt;br /&gt;
&lt;br /&gt;
* Python 101 -- Introduction to Python - http://www.rexx.com/~dkuhlman/python_101/python_101.html&lt;br /&gt;
&lt;br /&gt;
* 4. More Control Flow Tools — Python v2.7.1 documentation - http://docs.python.org/tutorial/controlflow.html&lt;br /&gt;
&lt;br /&gt;
== Linux Installation ==&lt;br /&gt;
&lt;br /&gt;
RHEL Distribution installation:&lt;br /&gt;
 yum -y install python python-setuptools&lt;br /&gt;
&lt;br /&gt;
Ubuntu Distribution installation: [https://help.ubuntu.com/community/Mercurial]&lt;br /&gt;
 # enable &#039;universe&#039; in the sources.list&lt;br /&gt;
 # &amp;quot;Mercurial is included in the Universe repository - activate this repo first&amp;quot;&lt;br /&gt;
 sudo apt-get install mercurial&lt;br /&gt;
&lt;br /&gt;
CentOS 5 Option Recommended Dependencies:&lt;br /&gt;
 yum -y install gcc make sudo readline-devel openssl-devel ncurses-devel zlib-devel gdbm-devel sqlite-devel bzip2-devel tk-devel tcl-devel&lt;br /&gt;
&lt;br /&gt;
 # this leaves: 2.6.6: _bsddb, bsddb185, dl, imageop, sunaudiodev&lt;br /&gt;
 # this leaves: 2.7.1: _bsddb, bsddb185, dl, imageop, sunaudiodev&lt;br /&gt;
 # this leaves: 3.2: none&lt;br /&gt;
&lt;br /&gt;
CentOS 9 Option Recommended Dependencies:&lt;br /&gt;
 # gdbm-devel not found in centos9?&lt;br /&gt;
 yum -y install gcc make sudo readline-devel openssl-devel ncurses-devel zlib-devel sqlite-devel bzip2-devel tk-devel tcl-devel&lt;br /&gt;
&lt;br /&gt;
Ubuntu 12.04 LTS 64bit dependencies:&lt;br /&gt;
 apt-get install gcc make sudo lib64bz2-dev tcl-dev lib64ncurses5-dev libssl-dev libreadline-dev tk-dev libsqlite3-dev libgdbm-dev&lt;br /&gt;
&lt;br /&gt;
 # maybe: lib64readline-dev libsqlite3-dev tk-dev&lt;br /&gt;
&lt;br /&gt;
 # this leaves: 2.7: _bsddb, bsddb185, dl, imageop, sunaudiodev&lt;br /&gt;
&lt;br /&gt;
=== 2.x ===&lt;br /&gt;
&lt;br /&gt;
CentOS dependencies:&lt;br /&gt;
 sudo yum -y install gcc make sudo readline-devel openssl-devel ncurses-devel zlib-devel gdbm-devel sqlite-devel bzip2-devel tk-devel tcl-devel&lt;br /&gt;
&lt;br /&gt;
Ubuntu 12.04 LTS 64bit dependencies:&lt;br /&gt;
 sudo apt-get update&lt;br /&gt;
 sudo apt-get install gcc make sudo lib64bz2-dev tcl-dev lib64ncurses5-dev libssl-dev libreadline-dev tk-dev libsqlite3-dev libgdbm-dev&lt;br /&gt;
&lt;br /&gt;
Ubuntu 24.04 LTS 64bit dependencies:&lt;br /&gt;
 sudo apt-get update&lt;br /&gt;
 sudo apt-get install gcc make sudo libbz2-dev tcl-dev libncurses-dev libssl-dev libreadline-dev tk-dev libsqlite3-dev libgdbm-dev libffi-dev&lt;br /&gt;
 # optional install&lt;br /&gt;
 sudo apt-get install checkinstall&lt;br /&gt;
&lt;br /&gt;
2.7.15:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#  PYVER=2.6.6&lt;br /&gt;
#  PYVER=2.7.5&lt;br /&gt;
#  PYVER=2.7.6&lt;br /&gt;
#  PYVER=2.7.9&lt;br /&gt;
#  PYVER=2.7.10&lt;br /&gt;
#  PYVER=2.7.15&lt;br /&gt;
PYVER=2.7.18&lt;br /&gt;
mkdir -p ~/.src ; cd ~/.src&lt;br /&gt;
wget --no-check-certificate http://www.python.org/ftp/python/$PYVER/Python-$PYVER.tgz&lt;br /&gt;
tar -zvxf Python-$PYVER.tgz&lt;br /&gt;
cd Python-$PYVER&lt;br /&gt;
#  ./configure --prefix=/opt/python-$PYVER&lt;br /&gt;
#  make clean &amp;amp;&amp;amp; make&lt;br /&gt;
./configure --prefix=/opt/python-$PYVER &amp;amp;&amp;amp; make clean &amp;amp;&amp;amp; make&lt;br /&gt;
sudo make install&lt;br /&gt;
&lt;br /&gt;
sudo /opt/python-$PYVER/bin/python -m ensurepip --upgrade&lt;br /&gt;
sudo /opt/python-$PYVER/bin/pip install --upgrade pip&lt;br /&gt;
sudo /opt/python-$PYVER/bin/pip install requests&lt;br /&gt;
&lt;br /&gt;
export PATH=/opt/python-$PYVER/bin:$PATH&lt;br /&gt;
echo -e &amp;quot;\n\nexport PATH=/opt/python-$PYVER/bin:\$PATH\n&amp;quot; &amp;gt;&amp;gt; ~/.bash_profile&lt;br /&gt;
#  echo -e &amp;quot;\n\nexport PATH=/opt/python27/bin:\$PATH\n&amp;quot; &amp;gt;&amp;gt; ~/.bashrc&lt;br /&gt;
&lt;br /&gt;
#  NOTE: remove any old versions from your .bash_profile&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Bootstrapping the pip installer - https://docs.python.org/2/library/ensurepip.html&lt;br /&gt;
&lt;br /&gt;
=== 3.x ===&lt;br /&gt;
&lt;br /&gt;
3.8.16:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#VER=3.7.0&lt;br /&gt;
#VER=3.8.15&lt;br /&gt;
#VER=3.10.9&lt;br /&gt;
VER=3.8.16&lt;br /&gt;
mkdir -p ~/.src ; cd ~/.src&lt;br /&gt;
wget http://www.python.org/ftp/python/${VER}/Python-${VER}.tgz&lt;br /&gt;
tar -zvxf Python-${VER}.tgz&lt;br /&gt;
cd Python-${VER}&lt;br /&gt;
./configure --prefix=/opt/python${VER}&lt;br /&gt;
make&lt;br /&gt;
&lt;br /&gt;
sudo make install&lt;br /&gt;
&lt;br /&gt;
## OPTIONAL alternative install path:&lt;br /&gt;
sudo checkinstall&lt;br /&gt;
## note: &#039;checkinstall&#039; makes a .deb, which you can uninstall with easier, but if you are using --prefix, you do need to&lt;br /&gt;
##       premake the folders&lt;br /&gt;
sudo mkdir -p /opt/python${VER}/bin&lt;br /&gt;
sudo mkdir -p /opt/python${VER}/lib&lt;br /&gt;
shortVER=`echo $VER | cut -d &#039;.&#039; -f 1-2`  # get short version eg. 3.10 from 3.10.9&lt;br /&gt;
sudo mkdir -p /opt/python${VER}/lib/python${shortVER}&lt;br /&gt;
sudo mkdir -p /opt/python${VER}/lib/python${shortVER}/test&lt;br /&gt;
# sudo checkinstall    # hit Y, and enter twice&lt;br /&gt;
## note: older versions have problems with the virtualization of the file system, so do FS Translation = no&lt;br /&gt;
checkinstall --fstrans=no&lt;br /&gt;
&lt;br /&gt;
export PATH=/opt/python${VER}/bin:$PATH&lt;br /&gt;
echo -e &amp;quot;\n\nexport PATH=/opt/python${VER}/bin:\$PATH\n&amp;quot; &amp;gt;&amp;gt; ~/.bash_profile&lt;br /&gt;
&lt;br /&gt;
# have to manually update version&lt;br /&gt;
rm /opt/python${VER}/bin/python&lt;br /&gt;
ln -sfn python3.8 /opt/python${VER}/bin/python&lt;br /&gt;
#cp /opt/python${VER}/bin/python3.8 /opt/python${VER}/bin/python&lt;br /&gt;
&lt;br /&gt;
# DEPENDENCIES&lt;br /&gt;
sudo apt install ...&lt;br /&gt;
yum install libffi-devel openssl-devel&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note, if you want the libraries to be shared (like python-dev):&lt;br /&gt;
 ./configure --enable-shared&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
 VER=3.6.9&lt;br /&gt;
&lt;br /&gt;
 VER=3.6.8&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
3.2.0:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir -p ~/src ; cd ~/src&lt;br /&gt;
wget http://www.python.org/ftp/python/3.2/Python-3.2.tgz&lt;br /&gt;
tar -zvxf Python-3.2.tgz&lt;br /&gt;
cd Python-3.2&lt;br /&gt;
./configure --prefix=/opt/python32&lt;br /&gt;
make&lt;br /&gt;
sudo make install&lt;br /&gt;
&lt;br /&gt;
export PATH=/opt/python32/bin:$PATH&lt;br /&gt;
echo -e &amp;quot;\n\nexport PATH=/opt/python32/bin:\$PATH\n&amp;quot; &amp;gt;&amp;gt; ~/.bash_profile&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3.3.0:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir -p ~/src ; cd ~/src&lt;br /&gt;
wget http://www.python.org/ftp/python/3.3.0/Python-3.3.0.tgz&lt;br /&gt;
tar -zvxf Python-3.3.0.tgz&lt;br /&gt;
cd Python-3.3.0&lt;br /&gt;
./configure --prefix=/opt/python3.3.0&lt;br /&gt;
make&lt;br /&gt;
sudo make install&lt;br /&gt;
&lt;br /&gt;
export PATH=/opt/python3.3.0/bin:$PATH&lt;br /&gt;
echo -e &amp;quot;\n\nexport PATH=/opt/python3.3.0/bin:\$PATH\n&amp;quot; &amp;gt;&amp;gt; ~/.bash_profile&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3.3.4:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir -p ~/.src ; cd ~/.src&lt;br /&gt;
wget http://www.python.org/ftp/python/3.3.4/Python-3.3.4.tgz&lt;br /&gt;
tar -zvxf Python-3.3.4.tgz&lt;br /&gt;
cd Python-3.3.4&lt;br /&gt;
./configure --prefix=/opt/python3.3.4&lt;br /&gt;
make clean&lt;br /&gt;
make&lt;br /&gt;
sudo make install&lt;br /&gt;
&lt;br /&gt;
export PATH=/opt/python3.3.4/bin:$PATH&lt;br /&gt;
echo -e &amp;quot;\n\nexport PATH=/opt/python3.3.4/bin:\$PATH\n&amp;quot; &amp;gt;&amp;gt; ~/.bash_profile&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3.4.0:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir -p ~/.src ; cd ~/.src&lt;br /&gt;
wget http://www.python.org/ftp/python/3.4.0/Python-3.4.0.tgz&lt;br /&gt;
tar -zvxf Python-3.4.0.tgz&lt;br /&gt;
cd Python-3.4.0&lt;br /&gt;
./configure --prefix=/opt/python3.4.0&lt;br /&gt;
make&lt;br /&gt;
sudo make install&lt;br /&gt;
&lt;br /&gt;
export PATH=/opt/python3.4.0/bin:$PATH&lt;br /&gt;
echo -e &amp;quot;\n\nexport PATH=/opt/python3.4.0/bin:\$PATH\n&amp;quot; &amp;gt;&amp;gt; ~/.bash_profile&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== setuptools ===&lt;br /&gt;
&lt;br /&gt;
Purpose: to install pip&lt;br /&gt;
&lt;br /&gt;
Note: required for several &#039;python setup.py install&#039; installations.&lt;br /&gt;
&lt;br /&gt;
Python Package Index : setuptools 0.6c11 - http://pypi.python.org/pypi/setuptools&lt;br /&gt;
&lt;br /&gt;
By Package Manager:&lt;br /&gt;
 yum install python-setuptools&lt;br /&gt;
&lt;br /&gt;
By Source:&lt;br /&gt;
 #VER=2.0.1&lt;br /&gt;
 #VER=2.2&lt;br /&gt;
 VER=3.4.4&lt;br /&gt;
 mkdir -p ~/.src ; cd ~/.src&lt;br /&gt;
 wget --no-check-certificate http://pypi.python.org/packages/source/s/setuptools/setuptools-$VER.tar.gz&lt;br /&gt;
 tar -zvxf setuptools-$VER.tar.gz&lt;br /&gt;
 cd setuptools-$VER&lt;br /&gt;
 # sudo python setup.py install&lt;br /&gt;
 sudo /opt/python-2.7.9/bin/python setup.py install&lt;br /&gt;
&lt;br /&gt;
Fix header:&lt;br /&gt;
 # Only needed on older versions&lt;br /&gt;
 sed -i &#039;s#!/usr/bin/python#!/usr/bin/env python#g&#039; /opt/python279/bin/easy_install&lt;br /&gt;
&lt;br /&gt;
Install pip:&lt;br /&gt;
 sudo /opt/python-2.7.9/bin/easy_install pip&lt;br /&gt;
&lt;br /&gt;
Sample pip usage:&lt;br /&gt;
 sudo /opt/python-2.7.9/bin/pip install paramiko&lt;br /&gt;
&lt;br /&gt;
== IDLE and Interactive Mode ==&lt;br /&gt;
&lt;br /&gt;
Interactive Mode - &amp;quot;When commands are read from a tty, the interpreter is said to be in interactive mode. In this mode it prompts for the next command with the primary prompt, usually three greater-than signs (&amp;gt;&amp;gt;&amp;gt;); for continuation lines it prompts with the secondary prompt, by default three dots (...).&amp;quot; [http://docs.python.org/2/tutorial/interpreter.html#invoking-the-interpreter]&lt;br /&gt;
&lt;br /&gt;
Can use &#039;_&#039; to reference last output:&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; 5 + 6&lt;br /&gt;
 11&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; print _&lt;br /&gt;
 11&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* 2. Using the Python Interpreter — Python v2.7.3 documentation - http://docs.python.org/2/tutorial/interpreter.html&lt;br /&gt;
&lt;br /&gt;
== Python 2.7 EOL ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
DEPRECATION: Python 2.7 will reach the end of its life on January 1st, 2020. Please upgrade your Python as Python 2.7 won&#039;t be maintained after that date. A future version of pip will drop support for Python 2.7.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Show All Python in Path ==&lt;br /&gt;
&lt;br /&gt;
 compgen -c | grep -i &amp;quot;python&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
&lt;br /&gt;
=== Hello World ===&lt;br /&gt;
&lt;br /&gt;
[http://en.wikipedia.org/wiki/Shebang_%28Unix%29 shebang] (also called a hashbang) of Python:&lt;br /&gt;
 #!/usr/bin/env python&lt;br /&gt;
 print &amp;quot;Hello World&amp;quot;&lt;br /&gt;
&lt;br /&gt;
NOTE: can also just use &amp;quot;#!/usr/bin/python&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Standard Script ===&lt;br /&gt;
&lt;br /&gt;
Standard Script:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def main(args):&lt;br /&gt;
  # do logic&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
  sys.exit(main(sys.argv))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Needed for things like pylint&lt;br /&gt;
&lt;br /&gt;
=== White Space ===&lt;br /&gt;
&lt;br /&gt;
Python uses white space to indicate code blocks.  Instead of &#039;&#039;{&#039;&#039; use a &#039;&#039;:&#039;&#039; and indent consistently (4 spaces).&lt;br /&gt;
&lt;br /&gt;
 if a == b:&lt;br /&gt;
     print &#039;equal&#039;&lt;br /&gt;
&lt;br /&gt;
Convert tabs to spaces:&lt;br /&gt;
 sed -i &#039;s/\t/    /g&#039; *.py&lt;br /&gt;
&lt;br /&gt;
Remove trailing whitespace:&lt;br /&gt;
 sed -i &#039;s/\s*$//&#039; *.py&lt;br /&gt;
 sed --in-place &#039;s/[[:space:]]\+$//&#039; fileName&lt;br /&gt;
&lt;br /&gt;
Clean project:&lt;br /&gt;
 # find . -name &amp;quot;*py&amp;quot; -exec dos2unix {} \;&lt;br /&gt;
 # find . -name &amp;quot;*py&amp;quot; -exec sed -i &#039;s/\t/    /g&#039; {} \;&lt;br /&gt;
 # find . -name &amp;quot;*py&amp;quot; -exec sed -i &#039;s/\s*$//&#039; {} \;&lt;br /&gt;
 find . -name &amp;quot;*py&amp;quot; -exec dos2unix {} \; -exec sed -i &#039;s/\t/    /g&#039; {} \; -exec sed -i &#039;s/\s*$//&#039; {} \;&lt;br /&gt;
&lt;br /&gt;
==== Trim Tailing White Space ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sed -e &#039;s/[[:space:]]*$//&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
find . -name &amp;quot;*.py&amp;quot; -exec sed -i -e &#039;s/[[:space:]]*$//&#039; {} \;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ref: [https://stackoverflow.com/questions/369758/how-to-trim-whitespace-from-a-bash-variable]&lt;br /&gt;
&lt;br /&gt;
=== Print ===&lt;br /&gt;
&lt;br /&gt;
print - http://docs.python.org/tutorial/inputoutput.html&lt;br /&gt;
&lt;br /&gt;
Print:  # include new line&lt;br /&gt;
 print(&amp;quot;Hello World&amp;quot;)&lt;br /&gt;
 print &amp;quot;Hello World&amp;quot;   # python 2 only&lt;br /&gt;
&lt;br /&gt;
Suppress new line: [http://stackoverflow.com/questions/493386/how-to-print-in-python-without-newline-or-space]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
print(&#039;#&#039;, end=&#039;&#039;)    # python 3&lt;br /&gt;
print &amp;quot;Hello World&amp;quot;,  # python 2 only (does produce a single separating white space though)&lt;br /&gt;
&lt;br /&gt;
import sys&lt;br /&gt;
sys.stdout.write(&#039;.&#039;)  # no separating white space&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 # flush output&lt;br /&gt;
 # optional, if new line won&#039;t come for some time&lt;br /&gt;
 import sys&lt;br /&gt;
 sys.stdout.flush()&lt;br /&gt;
&lt;br /&gt;
Multiple with separator:&lt;br /&gt;
 print(&amp;quot;hello&amp;quot;, &amp;quot;world&amp;quot;)  # separated by spaces&lt;br /&gt;
 print(&amp;quot;hello&amp;quot;, &amp;quot;world&amp;quot;, sep = &#039;.&#039;)  # separated by period&lt;br /&gt;
&lt;br /&gt;
Formatting:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mystr = &amp;quot;abc&amp;quot;&lt;br /&gt;
myint = 5&lt;br /&gt;
myflt = 3.141592&lt;br /&gt;
print( &amp;quot;%s %d %.3f&amp;quot; % (mystr, myint, myflt) )&lt;br /&gt;
print( &amp;quot;{0} {1} {2}&amp;quot;.format(mystr, myint, myflt) )  # string&#039;s format function (python &amp;gt; 2.7)&lt;br /&gt;
print( &amp;quot;{a} {b} {c}&amp;quot;.format( b = myint, a = mystr, c = myflt) )  # by name&lt;br /&gt;
print( &amp;quot;={a:4s}={b:3d}={c:10.3f}=&amp;quot;.format( b = myint, a = mystr, c = myflt) )  # type and padding&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Padded floating point decimal number: (rounds)&lt;br /&gt;
 print &amp;quot;%06.2f&amp;quot; % 2.319         # &amp;quot;002.32&amp;quot;&lt;br /&gt;
 print &amp;quot;%6.2f&amp;quot; % 2.311          # &amp;quot;  2.31&amp;quot;&lt;br /&gt;
 print &amp;quot;{:06.2f}&amp;quot;.format(2.319) # &amp;quot;002.32&amp;quot;&lt;br /&gt;
 print &amp;quot;{:6.2f}&amp;quot;.format(2.319)  # &amp;quot;  2.32&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 # Python 3 version where var=2.321234&lt;br /&gt;
 print(f&amp;quot;{var:.2f}&amp;quot;)  # &amp;quot;2.32&amp;quot;&lt;br /&gt;
 print(f&amp;quot;{var:6.2f}&amp;quot;)  # &amp;quot;  2.32&amp;quot;&lt;br /&gt;
 print(f&amp;quot;{var:06.2f}&amp;quot;)  # &amp;quot;002.32&amp;quot;&lt;br /&gt;
 print(f&amp;quot;{var:08.2f}&amp;quot;)  # &amp;quot;00002.32&amp;quot;&lt;br /&gt;
 print(f&amp;quot;{var:08.4f}&amp;quot;)  # &amp;quot;002.3212&amp;quot;&lt;br /&gt;
 # Python 3 version where var=2.329 - rounding&lt;br /&gt;
 print(f&amp;quot;{var:06.2f}&amp;quot;)  # &amp;quot;002.33&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Comments ===&lt;br /&gt;
&lt;br /&gt;
 # this is a comment&lt;br /&gt;
 # this is a comment&lt;br /&gt;
 x = y  # this is a comment&lt;br /&gt;
&lt;br /&gt;
Using a non assigned string constant as a comment: (also used for doc strings, not generally recommended)&lt;br /&gt;
 &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
 multi line comment&lt;br /&gt;
 &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;&#039;&lt;br /&gt;
 multi line comment can comment out &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
 &#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This can be used like a C &amp;quot;#if 0&amp;quot; concept to comment out whole sections of code.&lt;br /&gt;
&lt;br /&gt;
Using false block to comment out a block code: (does not ignore bad syntax though)&lt;br /&gt;
 if False:&lt;br /&gt;
    # code in this block is ignored&lt;br /&gt;
&lt;br /&gt;
=== doc strings ===&lt;br /&gt;
&lt;br /&gt;
Using a non assigned string constant as a comment: (also used for doc strings, not generally recommended)&lt;br /&gt;
 &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
 multi line comment&lt;br /&gt;
 &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Help ===&lt;br /&gt;
&lt;br /&gt;
dir - list functions and properties of objects:&lt;br /&gt;
 import math&lt;br /&gt;
 dir(math)  # module&lt;br /&gt;
 dir(dir)   # function&lt;br /&gt;
 dir(&amp;quot;&amp;quot;)    # object  - &amp;quot;&amp;quot;, [], {}, etc...&lt;br /&gt;
 dir(__builtins__)  # built in functions&lt;br /&gt;
 dir()      # list imported objects, and dunder methods&lt;br /&gt;
&lt;br /&gt;
Note: dunder (double under) methods determine special functionality (eg. __add__ for +)&lt;br /&gt;
&lt;br /&gt;
help - manual printout: (class doc string, function doc string, data, etc)&lt;br /&gt;
 import math&lt;br /&gt;
 help(math)    # full module info&lt;br /&gt;
 help(len)     # full function info&lt;br /&gt;
 help([&amp;quot;foo&amp;quot;]) # full object info&lt;br /&gt;
&lt;br /&gt;
Pydoc: (command line, same as &#039;import math, help(math)&#039;&lt;br /&gt;
 $ pydoc math&lt;br /&gt;
&lt;br /&gt;
Documentation String: (aka docstring, doc string)&lt;br /&gt;
 print(math.pow.__doc__)  # module doc string&lt;br /&gt;
 print(len.__doc__)       # function doc string&lt;br /&gt;
&lt;br /&gt;
Object or function type:&lt;br /&gt;
 type(x)&lt;br /&gt;
&lt;br /&gt;
 mylist = []&lt;br /&gt;
 isinstance(mylist, list)  # True&lt;br /&gt;
 type(s) is list           # True&lt;br /&gt;
&lt;br /&gt;
Note: isinstance() and type() not equivalent when objects and subclass get involved&lt;br /&gt;
&lt;br /&gt;
IDLE interactive help:&lt;br /&gt;
 help()&lt;br /&gt;
&lt;br /&gt;
=== Variables ===&lt;br /&gt;
&lt;br /&gt;
Basic Data Types&lt;br /&gt;
 str = &amp;quot;string&amp;quot;  # string&lt;br /&gt;
 num = 5         # integer&lt;br /&gt;
 flt = 5.0       # float&lt;br /&gt;
 nothing = None  # None  (not the same as undefined)&lt;br /&gt;
&lt;br /&gt;
Undefined.  Variables start off in an &#039;undefined&#039; state.  It is always better to initially set the variable to None to avoid this state.  To check if undefined: [http://code.activestate.com/recipes/59892-testing-if-a-variable-is-defined/] [http://code.activestate.com/recipes/59892/]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 try:&lt;br /&gt;
   x&lt;br /&gt;
 except NameError:&lt;br /&gt;
   x = None&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Rules: [http://www.python.org/dev/peps/pep-0008/ PEP8 - Method Names and Instance Variables]&lt;br /&gt;
* any length&lt;br /&gt;
* letters, numbers, underscore&lt;br /&gt;
* first character can&#039;t be number&lt;br /&gt;
* case sensitive&lt;br /&gt;
* cannot use keywords&lt;br /&gt;
&lt;br /&gt;
Multiple assignment:&lt;br /&gt;
 x = y = z = 0              # Zero x, y and z&lt;br /&gt;
 x, y, z = 1, &amp;quot;two&amp;quot;, 3.0    # x = 1, y = &amp;quot;two&amp;quot;, z = 3.0&lt;br /&gt;
&lt;br /&gt;
Swap variables: (done in parallel)&lt;br /&gt;
 a, b = b, a&lt;br /&gt;
&lt;br /&gt;
Unpack variables: (requires equal items on each side)&lt;br /&gt;
 a, b, c = [1, 2, 3]&lt;br /&gt;
&lt;br /&gt;
Other Data Types:&lt;br /&gt;
* tuple&lt;br /&gt;
* list&lt;br /&gt;
* dictionary&lt;br /&gt;
* set&lt;br /&gt;
* objects&lt;br /&gt;
&lt;br /&gt;
Everything in Python is an object that has:&lt;br /&gt;
* identity:  id(obj)&lt;br /&gt;
* type:  type(obj)&lt;br /&gt;
* value:  obj&lt;br /&gt;
** mutable - id() stays the same on modification (dictionary, lists, objects)&lt;br /&gt;
** immutable - id() changes on modification as new object is created (string, integer, tuple)&lt;br /&gt;
&lt;br /&gt;
==== Check if Variable Exists ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
try:&lt;br /&gt;
    a # does a exist in the current namespace&lt;br /&gt;
except NameError:&lt;br /&gt;
    a = 10 # nope&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &#039;a&#039; in vars() or &#039;a&#039; in globals()&lt;br /&gt;
 &#039;a&#039; in vars(__builtins__)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if hasattr(a, &#039;property&#039;):&lt;br /&gt;
    doStuff(a.property)&lt;br /&gt;
else:&lt;br /&gt;
    otherStuff()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ref: [https://stackoverflow.com/questions/1592565/determine-if-variable-is-defined-in-python] [https://stackoverflow.com/questions/610883/how-to-know-if-an-object-has-an-attribute-in-python]&lt;br /&gt;
&lt;br /&gt;
=== Numbers ===&lt;br /&gt;
&lt;br /&gt;
 num = 5&lt;br /&gt;
 print &amp;quot;num: %d&amp;quot; % num&lt;br /&gt;
&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; print &amp;quot;Today&#039;s stock price: %f&amp;quot; % 50.4625   1&lt;br /&gt;
 50.462500&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; print &amp;quot;Today&#039;s stock price: %.2f&amp;quot; % 50.4625 2&lt;br /&gt;
 50.46&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; print &amp;quot;Change since yesterday: %+.2f&amp;quot; % 1.5 3&lt;br /&gt;
 +1.50&lt;br /&gt;
&lt;br /&gt;
Arithmetic:&lt;br /&gt;
 + - * /&lt;br /&gt;
 //  # integer division&lt;br /&gt;
 %   # modulus&lt;br /&gt;
 **  # exponent&lt;br /&gt;
&lt;br /&gt;
Compact Arithmetic:&lt;br /&gt;
 i+=1  # Increment - Note, there is no &#039;i++&#039;&lt;br /&gt;
 i*=2  # Multiply&lt;br /&gt;
 i%=2  # modulus&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
Math Functions:&lt;br /&gt;
 import math&lt;br /&gt;
 math.ceil(x)&lt;br /&gt;
 math.floor(x)&lt;br /&gt;
 math.trunc(x)&lt;br /&gt;
 math.pow(x,y)&lt;br /&gt;
&lt;br /&gt;
 abs(x)  # built in&lt;br /&gt;
&lt;br /&gt;
String interpolation:&lt;br /&gt;
 %% % character&lt;br /&gt;
 %d integer&lt;br /&gt;
 %x hex&lt;br /&gt;
 %X hex (upper)&lt;br /&gt;
 %f float&lt;br /&gt;
 %s string&lt;br /&gt;
&lt;br /&gt;
 x = 1/81&lt;br /&gt;
 print(&#039;value: %.2f&#039; % x)  # 0.01&lt;br /&gt;
 print(&#039;value: %.5f&#039; % x)  # 0.012345&lt;br /&gt;
 print(&#039;%d %d %d&#039; % (1, 2, 3))&lt;br /&gt;
&lt;br /&gt;
Type check:&lt;br /&gt;
 if not isinstance(myvar, (int, float)): ...&lt;br /&gt;
&lt;br /&gt;
=== Strings ===&lt;br /&gt;
&lt;br /&gt;
STRINGS ARE IMMUTABLE!  (to modify convert to a list)&lt;br /&gt;
&lt;br /&gt;
Strings: (String Constants)&lt;br /&gt;
 str = &amp;quot;Hello&amp;quot;&lt;br /&gt;
 str = &#039;Hello&#039;&lt;br /&gt;
 str = &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
   Hello&lt;br /&gt;
   World&lt;br /&gt;
 &amp;quot;&amp;quot;&amp;quot;      # can also use &#039;&#039;&#039;...&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
String literals can span multiple lines: (no wrapping when \ used)&lt;br /&gt;
 hello = &amp;quot;hello\&lt;br /&gt;
 world&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Length:&lt;br /&gt;
 len(&amp;quot;str&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Raw string: (back slashes are not escaped)&lt;br /&gt;
 myrawstr = r&amp;quot;hello\nworld\&lt;br /&gt;
 how are you&amp;quot;&lt;br /&gt;
 myrawstr = r&amp;quot;C:\&amp;quot;  # ERROR - limitation of what won&#039;t be escaped&lt;br /&gt;
&lt;br /&gt;
Concatenation:&lt;br /&gt;
 str = &#039;hot&#039; + &#039;dog&#039;&lt;br /&gt;
 print &amp;quot;Hello&amp;quot; &amp;quot;World&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Can&#039;t concat numbers&lt;br /&gt;
 str = 5 + &#039;test&#039;  # error&lt;br /&gt;
 num = 5&lt;br /&gt;
 str = num + &#039;test&#039;  # error&lt;br /&gt;
 str = str(5) + str(num) + &#039;test&#039;  # ok&lt;br /&gt;
&lt;br /&gt;
Repeated Concatenation:&lt;br /&gt;
 str = 10 * &#039;ha&#039;&lt;br /&gt;
 str = &#039;ha&#039; * 10  # same&lt;br /&gt;
 print &#039;-&#039;*60  # --------------------&lt;br /&gt;
&lt;br /&gt;
String Indexing:&lt;br /&gt;
 s = &#039;hello&#039;&lt;br /&gt;
 print( s[0] )    # is &#039;h&#039;&lt;br /&gt;
 print( s[-1] )   # is &#039;o&#039;&lt;br /&gt;
 print( s[len(s) - 1 ] )  # is also &#039;o&#039;&lt;br /&gt;
&lt;br /&gt;
Modify Strings: [http://stackoverflow.com/questions/1228299/change-one-character-in-a-string-in-python]&lt;br /&gt;
 s[1] = &#039;x&#039;  # ERROR!&lt;br /&gt;
 ERROR: can&#039;t modify string by index&lt;br /&gt;
 &lt;br /&gt;
 # solution:&lt;br /&gt;
 s = list(&amp;quot;Hello World&amp;quot;)&lt;br /&gt;
 s[0] = &#039;C&#039;&lt;br /&gt;
 print( &amp;quot;&amp;quot;.join(s) )&lt;br /&gt;
&lt;br /&gt;
String Slicing:&lt;br /&gt;
 s = &#039;hello&#039;&lt;br /&gt;
 print( s[0:3] )  # &#039;hel&#039;&lt;br /&gt;
 i = 1&lt;br /&gt;
 print( s[i:i+1] )  # &#039;e&#039;&lt;br /&gt;
 print( s[:3] )  # 0:3 &#039;hel&#039;&lt;br /&gt;
 print( s[4:] )  # 4:end &#039;o&#039;&lt;br /&gt;
 print( s[:] )  # start:end &#039;hello&#039;&lt;br /&gt;
 print( s[-2:] )  # -2:end &#039;lo&#039;&lt;br /&gt;
&lt;br /&gt;
For loop:&lt;br /&gt;
 s = &#039;hello&#039;&lt;br /&gt;
 for c in s:&lt;br /&gt;
   print c  # c = &#039;h&#039; first time&lt;br /&gt;
&lt;br /&gt;
Escape characters:&lt;br /&gt;
 \\  \&#039;  \&amp;quot;  \n  \r  \t&lt;br /&gt;
&lt;br /&gt;
Alternate loop:&lt;br /&gt;
 s = &#039;hello&#039;&lt;br /&gt;
 for i in range( len(s) ):&lt;br /&gt;
   print s[i]&lt;br /&gt;
&lt;br /&gt;
Ord and Char (ASCII):&lt;br /&gt;
 ord(&#039;a&#039;)  # 97&lt;br /&gt;
 chr(97)   # &#039;a&#039;&lt;br /&gt;
&lt;br /&gt;
 0-9 : 48-57&lt;br /&gt;
 A-Z : 65-90&lt;br /&gt;
 a-z : 97-122&lt;br /&gt;
&lt;br /&gt;
List Functions:  (dir on any string)&lt;br /&gt;
 dir(&#039;&#039;)&lt;br /&gt;
 dir(str)&lt;br /&gt;
&lt;br /&gt;
Help:&lt;br /&gt;
 help(&#039;&#039;)&lt;br /&gt;
 help(str)&lt;br /&gt;
&lt;br /&gt;
Padding:&lt;br /&gt;
 &amp;quot;a&amp;quot;.rjust(2, &#039;0&#039;)  # &#039;0a&#039;&lt;br /&gt;
 &amp;quot;1&amp;quot;.ljust(4, &#039;0&#039;)  # &#039;1000&#039;&lt;br /&gt;
&lt;br /&gt;
String Test Functions:&lt;br /&gt;
 &amp;quot;HELLO&amp;quot;.isupper()   # True&lt;br /&gt;
 &amp;quot;hello&amp;quot;.islower()   # True&lt;br /&gt;
 &amp;quot;hello&amp;quot;.isalpha()   # True&lt;br /&gt;
 &amp;quot;12.22&amp;quot;.isdigit()   # False (because of &#039;.&#039;)&lt;br /&gt;
 &amp;quot;12.22&amp;quot;.isnumeric() # False (because of &#039;.&#039;)&lt;br /&gt;
 &amp;quot;hel2&amp;quot;.isalnum()    # True&lt;br /&gt;
 &amp;quot;e&amp;quot; in &amp;quot;hello&amp;quot;      # True&lt;br /&gt;
 &amp;quot;hello&amp;quot;.startswith(&#039;he&#039;)  # True&lt;br /&gt;
 &amp;quot;hello&amp;quot;.endswith(&#039;lo&#039;)    # True&lt;br /&gt;
&lt;br /&gt;
Note: To check for floats: [http://stackoverflow.com/questions/354038/how-do-i-check-if-a-string-is-a-number-in-python]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def is_number(s):&lt;br /&gt;
    try:&lt;br /&gt;
        float(s)&lt;br /&gt;
        return True&lt;br /&gt;
    except ValueError:&lt;br /&gt;
        return False&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
String Modify Functions: (sort of... Strings are immutable)&lt;br /&gt;
 &amp;quot;HELLO&amp;quot;.lower()           # &#039;hello&#039;&lt;br /&gt;
 &amp;quot;hello&amp;quot;.upper()           # &#039;HELLO&#039;&lt;br /&gt;
 &amp;quot; hello &amp;quot;.strip()         # &#039;hello&#039; remove leading/tailing whitespace&lt;br /&gt;
 &amp;quot; hello &amp;quot;.lstrip()        # &#039;hello &#039; remove left whitespace&lt;br /&gt;
 &amp;quot; hello &amp;quot;.rstrip()        # &#039; hello&#039; remove right whitespace&lt;br /&gt;
 &amp;quot;www.com&amp;quot;.split(&#039;.&#039;)      # [&#039;www&#039;, &#039;com&#039;]   &amp;lt;- list&lt;br /&gt;
 &amp;quot;www.com&amp;quot;.partition(&#039;.&#039;)  # (&#039;www&#039;, &#039;.&#039;, &#039;com&#039;)  &amp;lt;- tuple&lt;br /&gt;
 &amp;quot;&amp;quot;.join( (&#039;a&#039;,&#039;b&#039;,&#039;c&#039;) )  # &amp;quot;abc&amp;quot;  join strings, list or tuple&lt;br /&gt;
 &amp;quot;-&amp;quot;.join( (&#039;a&#039;,&#039;b&#039;,&#039;c&#039;) ) # &amp;quot;a-b-c&amp;quot;  join with separator&lt;br /&gt;
 &amp;quot;23&amp;quot;.zfill(4)             # &amp;quot;0023&amp;quot;&lt;br /&gt;
&lt;br /&gt;
String Search Functions:&lt;br /&gt;
 &amp;quot;hello&amp;quot;.find(&#039;lo&#039;)   # 3  (-1 on fail)&lt;br /&gt;
 &amp;quot;hello&amp;quot;.index(&#039;lo&#039;)  # 3 (exception on fail)&lt;br /&gt;
 &amp;quot;hello&amp;quot;.rfind(&#039;lo&#039;)  # 3 right to left (-1 on fail)&lt;br /&gt;
 &amp;quot;hello&amp;quot;.rindex(&#039;lo&#039;) # 3 right to left (exception on fail)&lt;br /&gt;
&lt;br /&gt;
Formatting: (form of concatenation)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mystr = &amp;quot;abc&amp;quot;&lt;br /&gt;
myint = 5&lt;br /&gt;
myflt = 3.141592&lt;br /&gt;
print( &amp;quot;%s %d %.3f&amp;quot; % (mystr, myint, myflt) )&lt;br /&gt;
print( &amp;quot;{0} {1} {2}&amp;quot;.format(mystr, myint, myflt) )  # pep 3101 style - string&#039;s format function (python &amp;gt; 2.7)&lt;br /&gt;
print( &amp;quot;{a} {b} {c}&amp;quot;.format( b = myint, a = mystr, c = myflt) )  # by name&lt;br /&gt;
print( &amp;quot;={a:4s}={b:3d}={c:10.3f}=&amp;quot;.format( b = myint, a = mystr, c = myflt) )  # type and padding&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Split multi line string:&lt;br /&gt;
 for line in str.split(&#039;\n&#039;):  print(line)&lt;br /&gt;
 lines = str.splitlines()      # returns list&lt;br /&gt;
 lines = str.splitlines(True)  # returns list (each includes new line characters)&lt;br /&gt;
&lt;br /&gt;
Input a string:&lt;br /&gt;
 name = input(&#039;What is your name: &#039;).strip()  # python 3&lt;br /&gt;
 name = raw_input(&#039;What is your name: &#039;).strip()  # python 2&lt;br /&gt;
&lt;br /&gt;
Leet Speak:&lt;br /&gt;
 leet_table = &#039;&#039;.maketrans(&#039;EIOBT&#039;, &#039;31087&#039;)&lt;br /&gt;
 &#039;BE COOL. SPEAK LEET!&#039;.translate(leet_table)&lt;br /&gt;
&lt;br /&gt;
String Functions:&lt;br /&gt;
 newstr = mystr.strip()             # remove white space on both sides&lt;br /&gt;
 newstr = mystr.rstrip()            # remove white space on right side&lt;br /&gt;
 newstr = mystr.lstrip()            # remove white space on left side&lt;br /&gt;
 newstr = mystr.replace(&#039;\n&#039;, &#039; &#039;)  # replace string with another&lt;br /&gt;
 newstr = mystr.replace(&#039;jello&#039;, &#039;hello&#039;)  # replace string with another&lt;br /&gt;
&lt;br /&gt;
==== String Formatting ====&lt;br /&gt;
&lt;br /&gt;
PyFormat: Using % and .format() for great good! - https://pyformat.info/&lt;br /&gt;
&lt;br /&gt;
===== Zero Padding =====&lt;br /&gt;
&lt;br /&gt;
3 zero padding:&lt;br /&gt;
 &amp;quot;{:03}&amp;quot;.format(1)  # 003&lt;br /&gt;
&lt;br /&gt;
3 zero padding, specify position:&lt;br /&gt;
 &amp;quot;{1:03}&amp;quot;.format(1, 2)  # 002&lt;br /&gt;
&lt;br /&gt;
Old method:&lt;br /&gt;
 &amp;quot;%03d&amp;quot; % 2  # 002&lt;br /&gt;
&lt;br /&gt;
=== chr and ord ===&lt;br /&gt;
&lt;br /&gt;
Ord and Char (ASCII):&lt;br /&gt;
 ord(&#039;a&#039;)  # 97&lt;br /&gt;
 chr(97)   # &#039;a&#039;&lt;br /&gt;
&lt;br /&gt;
=== Range ===&lt;br /&gt;
&lt;br /&gt;
Creates a list of numbers.  Remember: range always ends one less than you want!&lt;br /&gt;
&lt;br /&gt;
Count:&lt;br /&gt;
 ten = 10&lt;br /&gt;
 one = 1&lt;br /&gt;
 range(ten)               # [0,1,...,9]   starts with zero by default&lt;br /&gt;
 range(one, ten + 1)      # [1,...,10]    actually get 1 to 10&lt;br /&gt;
 range(ten, one - 1, -1)  # [10,9,...,1]  count down&lt;br /&gt;
 range(2, 10 + 1, 2)      # [2,4,...,10]  even numbers&lt;br /&gt;
&lt;br /&gt;
=== drange ===&lt;br /&gt;
&lt;br /&gt;
Solution for decimal range() step value:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def drange(start, stop, step):&lt;br /&gt;
    r = start&lt;br /&gt;
    while r &amp;lt; stop:&lt;br /&gt;
        yield r&lt;br /&gt;
    r += step&lt;br /&gt;
&lt;br /&gt;
sub_ten = drange(0.0, 1.0, 0.1)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* floating point - Python decimal range() step value - Stack Overflow - http://stackoverflow.com/questions/477486/python-decimal-range-step-value&lt;br /&gt;
&lt;br /&gt;
=== Casting ===&lt;br /&gt;
&lt;br /&gt;
Convert:&lt;br /&gt;
 float(3)&lt;br /&gt;
 str(85)&lt;br /&gt;
 int(8.6)&lt;br /&gt;
 round(5.5)&lt;br /&gt;
&lt;br /&gt;
Check Type:&lt;br /&gt;
 type(5)     # &amp;lt;class &#039;int&#039;&amp;gt;&lt;br /&gt;
 type(5.0)   # &amp;lt;class &#039;float&#039;&amp;gt;&lt;br /&gt;
 type(&#039;5&#039;)   # &amp;lt;class &#039;str&#039;&amp;gt;&lt;br /&gt;
 type(None)  # &amp;lt;class &#039;NoneType&#039;&amp;gt;&lt;br /&gt;
 type(print) # &amp;lt;class &#039;builtin_function_or_method&#039;&amp;gt;&lt;br /&gt;
 type(())    # &amp;lt;class &#039;tuple&#039;&amp;gt;&lt;br /&gt;
 type([])    # &amp;lt;class &#039;list&#039;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 mytype = int&lt;br /&gt;
 if type(1) is mytype: ...&lt;br /&gt;
&lt;br /&gt;
=== Boolean Logic ===&lt;br /&gt;
&lt;br /&gt;
True and False:&lt;br /&gt;
 bol = True&lt;br /&gt;
 bol = False&lt;br /&gt;
&lt;br /&gt;
Boolean Operators: (in order precedence)&lt;br /&gt;
 a == b&lt;br /&gt;
 a != b&lt;br /&gt;
 not a&lt;br /&gt;
 a and b&lt;br /&gt;
 a or b&lt;br /&gt;
&lt;br /&gt;
Note: Short-circuit evaluated - &#039;and&#039; and &#039;or&#039;&lt;br /&gt;
&lt;br /&gt;
Return Boolean:&lt;br /&gt;
 return myint &amp;gt;= 16&lt;br /&gt;
&lt;br /&gt;
Get Boolean from string: [http://stackoverflow.com/questions/715417/converting-from-a-string-to-boolean-in-python]&lt;br /&gt;
 # Note: no built in way to do this&lt;br /&gt;
&lt;br /&gt;
 myString = &amp;quot;false&amp;quot;&lt;br /&gt;
 val = (myString == &amp;quot;true&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
 True if myString==&amp;quot;True&amp;quot; else False&lt;br /&gt;
&lt;br /&gt;
 s in [&#039;true&#039;, &#039;1&#039;, &#039;t&#039;, &#039;y&#039;, &#039;yes&#039;, &#039;yeah&#039;, &#039;yup&#039;, &#039;certainly&#039;, &#039;uh-huh&#039;]&lt;br /&gt;
&lt;br /&gt;
 def str2bool(v):&lt;br /&gt;
   return v.lower() in (&amp;quot;yes&amp;quot;, &amp;quot;true&amp;quot;, &amp;quot;t&amp;quot;, &amp;quot;1&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
=== None ===&lt;br /&gt;
&lt;br /&gt;
None is Python&#039;s version of NULL or NIL.&lt;br /&gt;
&lt;br /&gt;
None is a singleton (Python only has one copy of None in the interpreter).&lt;br /&gt;
&lt;br /&gt;
 if myvar is None:&lt;br /&gt;
     ...&lt;br /&gt;
&lt;br /&gt;
=== If Conditionals ===&lt;br /&gt;
&lt;br /&gt;
Operators:&lt;br /&gt;
 ==, !=, not, and, or, &amp;lt;, &amp;gt;, &amp;lt;&amp;gt;, &amp;lt;=, &amp;gt;=, in, not in, is, is not&lt;br /&gt;
&lt;br /&gt;
If statement:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if a == b:&lt;br /&gt;
  ...&lt;br /&gt;
elif c &amp;lt; age &amp;lt; d:&lt;br /&gt;
  ...&lt;br /&gt;
else:&lt;br /&gt;
  ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Shorthand conditional: (ternary operator)&lt;br /&gt;
 val = True if a == b else False&lt;br /&gt;
&lt;br /&gt;
is - checks for identical objects - same id()&lt;br /&gt;
 # None is a singleton, so this works great for None&lt;br /&gt;
 if myvar is None:&lt;br /&gt;
     ...&lt;br /&gt;
&lt;br /&gt;
Other shorthand:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def mycmp(x, y):&lt;br /&gt;
  if x &amp;gt; y: return True&lt;br /&gt;
  else: return False&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Switch/Case statement:&lt;br /&gt;
* there is no built in switch/case statement, use &amp;quot;if ... elif ... elif ...&amp;quot; sequence instead&lt;br /&gt;
&lt;br /&gt;
=== For Loop ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;for&#039;&#039; is used for iterating over an iterable sequence (eg. lists, dictionaries, tuples). (for each)&lt;br /&gt;
&lt;br /&gt;
# range(start, end + 1, skip)&lt;br /&gt;
&lt;br /&gt;
 for i in range(10):&lt;br /&gt;
   print(i)  # 0 .. 9&lt;br /&gt;
&lt;br /&gt;
 for i in range(5, 10):&lt;br /&gt;
   print(i)  # 5 .. 9&lt;br /&gt;
&lt;br /&gt;
 for i in range(10, 0, -1):&lt;br /&gt;
   print(i)  # 10 .. 1&lt;br /&gt;
&lt;br /&gt;
 for i in [1, 2, 3]:  # iterate over list&lt;br /&gt;
   print(i)  # 1 2 3&lt;br /&gt;
&lt;br /&gt;
Discard variable: [http://bytes.com/topic/python/answers/757444-loop-without-variable]&lt;br /&gt;
 for _ in range(10):  # repeat and discard variable (good for pep8 check)&lt;br /&gt;
   print &amp;quot;hello world&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 for key in my_dict.keys(): ...&lt;br /&gt;
 for value in my_dict.values(): ...&lt;br /&gt;
 for key, value in my_dict.items(): ...&lt;br /&gt;
&lt;br /&gt;
Compact version:&lt;br /&gt;
 for i in range(10): print(i)    # 0 .. 9&lt;br /&gt;
&lt;br /&gt;
Access index: [http://stackoverflow.com/questions/522563/accessing-the-index-in-python-for-loops]&lt;br /&gt;
 # using enumeration&lt;br /&gt;
 for idx, val in enumerate(mylist):&lt;br /&gt;
   print idx, val&lt;br /&gt;
&lt;br /&gt;
 # using range&lt;br /&gt;
 for ix in range(len(mylist)):&lt;br /&gt;
   print mylist[ix]&lt;br /&gt;
&lt;br /&gt;
 # list comprehension&lt;br /&gt;
 [ (ix, mylist[ix]) for ix in range(len(mylist))]&lt;br /&gt;
&lt;br /&gt;
=== While Loop ===&lt;br /&gt;
&lt;br /&gt;
 i = 0&lt;br /&gt;
 while i &amp;lt; 10:&lt;br /&gt;
   i = i + 1&lt;br /&gt;
&lt;br /&gt;
 while True:&lt;br /&gt;
   ...  # infinite loop&lt;br /&gt;
&lt;br /&gt;
=== Breaking Loops ===&lt;br /&gt;
&lt;br /&gt;
break statement:&lt;br /&gt;
 while True:&lt;br /&gt;
   if s == &#039;done&#039;:&lt;br /&gt;
     break  # jump out of the loop&lt;br /&gt;
   ...&lt;br /&gt;
&lt;br /&gt;
continue statement: (works with while too)&lt;br /&gt;
  for i in range(10):&lt;br /&gt;
    if i == 2:&lt;br /&gt;
      continue  # skip 2&lt;br /&gt;
    ...&lt;br /&gt;
&lt;br /&gt;
=== Functions ===&lt;br /&gt;
&lt;br /&gt;
No return value:  (None)&lt;br /&gt;
 x = print(&#039;&#039;)&lt;br /&gt;
 # x is &#039;None&#039;&lt;br /&gt;
&lt;br /&gt;
Note: specifying no return value is the same as this:&lt;br /&gt;
 return None&lt;br /&gt;
&lt;br /&gt;
No Operation - &#039;pass&#039;:&lt;br /&gt;
 def noop():&lt;br /&gt;
   pass&lt;br /&gt;
&lt;br /&gt;
Function:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def area(radius):&lt;br /&gt;
  &amp;quot;&amp;quot;&amp;quot; This is a doc string &amp;quot;&amp;quot;&amp;quot;   # can be &amp;quot; ... &amp;quot; also...&lt;br /&gt;
  import math&lt;br /&gt;
  return math.pi * radius ** 2&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Function Doc string:&lt;br /&gt;
 print(area.__doc__)&lt;br /&gt;
 foo.func_doc&lt;br /&gt;
&lt;br /&gt;
Function name:&lt;br /&gt;
  foo.func_name&lt;br /&gt;
&lt;br /&gt;
Local variable:&lt;br /&gt;
 name = &amp;quot;old&amp;quot;&lt;br /&gt;
 def cname():&lt;br /&gt;
   name = &amp;quot;new&amp;quot;&lt;br /&gt;
 print(name)  # is still &#039;old&#039;&lt;br /&gt;
&lt;br /&gt;
Global variable:&lt;br /&gt;
 name = &amp;quot;old&amp;quot;&lt;br /&gt;
 def cname():&lt;br /&gt;
   global name&lt;br /&gt;
   name = &amp;quot;new&amp;quot;&lt;br /&gt;
 cname()&lt;br /&gt;
 print(name)  # is now &#039;new&#039;&lt;br /&gt;
&lt;br /&gt;
By convention starting point is: (not required)&lt;br /&gt;
 def main():&lt;br /&gt;
&lt;br /&gt;
Parameters: (with default)&lt;br /&gt;
 def foo(x, y, z = &amp;quot;default&amp;quot;):&lt;br /&gt;
&lt;br /&gt;
Note: don&#039;t use mutable for defaults, as the object is remembered across runs! (unless that is what you want)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# each call to t() will increase list&lt;br /&gt;
def t(foo=[]):&lt;br /&gt;
   foo.append(&#039;1&#039;)&lt;br /&gt;
   print(foo)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# fix mutable issue&lt;br /&gt;
def named_param(a, foo=None):&lt;br /&gt;
  foo = foo or []&lt;br /&gt;
  if not foo:&lt;br /&gt;
    foo.append(a)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Parameters by keyword:&lt;br /&gt;
 def foo(x = &#039;1&#039;, y = &#039;2&#039;, z = &#039;3&#039;):&lt;br /&gt;
   ...&lt;br /&gt;
 foo(y = &#039;a&#039;, x = &#039;b&#039;)   # order is not important with keywords&lt;br /&gt;
&lt;br /&gt;
Trick for optional parameter:&lt;br /&gt;
 def do(x = None):&lt;br /&gt;
   if x == None:&lt;br /&gt;
&lt;br /&gt;
Function tests - functions are callable&lt;br /&gt;
 callable(myfunc)&lt;br /&gt;
&lt;br /&gt;
=== Type Hints ===&lt;br /&gt;
&lt;br /&gt;
: &amp;quot;Note The Python runtime does not enforce function and variable type annotations. They can be used by third party tools such as type checkers, IDEs, linters, etc.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 def surface_area_of_cube(edge_length: float) -&amp;gt; str:&lt;br /&gt;
     return f&amp;quot;The surface area of the cube is {6 * edge_length ** 2}.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Without the hints:&lt;br /&gt;
 def surface_area_of_cube(edge_length):&lt;br /&gt;
     ...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ref: https://docs.python.org/3/library/typing.html&lt;br /&gt;
&lt;br /&gt;
=== Pass ===&lt;br /&gt;
&lt;br /&gt;
Pass is a null operation (noop):&lt;br /&gt;
&lt;br /&gt;
Do nothing, noop, take no action:&lt;br /&gt;
 pass&lt;br /&gt;
&lt;br /&gt;
Great for creating minimal classes:&lt;br /&gt;
 class MyEmptyClass:&lt;br /&gt;
   pass&lt;br /&gt;
&lt;br /&gt;
Greate for making stub functions/methods:&lt;br /&gt;
 def initlog(*args):&lt;br /&gt;
   pass  # remember to implement this!&lt;br /&gt;
&lt;br /&gt;
=== Slice ===&lt;br /&gt;
&lt;br /&gt;
Take take a slice of strings, lists, tuples, etc...&lt;br /&gt;
 a = [0,1,2,3,4,5]&lt;br /&gt;
 a[0]    # 0 - not a slice&lt;br /&gt;
 a[-1]   # 5 - not a slice&lt;br /&gt;
 a[0:1]  # [0]&lt;br /&gt;
 a[1:3]  # [1, 2]&lt;br /&gt;
 a[:2]   # [0, 1]&lt;br /&gt;
 a[:-1]  # [0, 1, 2, 3, 4] - all but last&lt;br /&gt;
 a[2:]   # [2, 3, 4, 5]&lt;br /&gt;
 a[::2]  # [0, 2, 4] - stride&lt;br /&gt;
 a[::-1] # [5, 4, 3, 2, 1, 0] - reverse&lt;br /&gt;
 range(0,10)[::2]  # [0, 2, 4, 6, 8] - stride&lt;br /&gt;
&lt;br /&gt;
 a = &#039;012345&#039;&lt;br /&gt;
 a[1:3]  # &#039;12&#039;&lt;br /&gt;
 a[::2]  # &#039;024&#039;&lt;br /&gt;
&lt;br /&gt;
=== [http://docs.python.org/reference/compound_stmts.html Compound Statements] ===&lt;br /&gt;
&lt;br /&gt;
Compound statements: (generally discouraged)&lt;br /&gt;
 fun1(); fun2(); fun3()&lt;br /&gt;
&lt;br /&gt;
Compound with statements: [http://docs.python.org/reference/compound_stmts.html#the-with-statement]&lt;br /&gt;
 with A() as a, B() as b: ...&lt;br /&gt;
&lt;br /&gt;
 #is equivalent to&lt;br /&gt;
 with A() as a:&lt;br /&gt;
     with B() as b:&lt;br /&gt;
         ...&lt;br /&gt;
&lt;br /&gt;
[http://www.python.org/dev/peps/pep-0343 PEP 0343] - The “with” statement&lt;br /&gt;
&lt;br /&gt;
 f = open(&#039;file&#039;)&lt;br /&gt;
 with f: ...&lt;br /&gt;
&lt;br /&gt;
Try: (quick ignore all exceptions, very dangerous)&lt;br /&gt;
 try: my_broken_function()&lt;br /&gt;
 except: pass&lt;br /&gt;
&lt;br /&gt;
=== Passing Command Line Arguments ===&lt;br /&gt;
&lt;br /&gt;
Parameters are stored in the &#039;sys.argv&#039; variable:&lt;br /&gt;
 import sys&lt;br /&gt;
 print( sys.argv[0] )  # name of script&lt;br /&gt;
 print( sys.argv[1] )  # first argument&lt;br /&gt;
 for arg in sys.argv: print( arg )  # list all arguments&lt;br /&gt;
&lt;br /&gt;
Print script name:&lt;br /&gt;
 os.path.basename(sys.argv[0])&lt;br /&gt;
&lt;br /&gt;
Print path to script:&lt;br /&gt;
 print sys.path[0]&lt;br /&gt;
&lt;br /&gt;
Paths: [http://code.activestate.com/recipes/474083-get-the-path-of-the-currently-executing-python-scr/]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import os,sys&lt;br /&gt;
print &amp;quot;CWD: &amp;quot;,os.getcwd()&lt;br /&gt;
print &amp;quot;Script: &amp;quot;,sys.argv[0]&lt;br /&gt;
print &amp;quot;.EXE: &amp;quot;,os.path.dirname(sys.executable)&lt;br /&gt;
print &amp;quot;Script dir: &amp;quot;, os.path.realpath(os.path.dirname(sys.argv[0]))&lt;br /&gt;
pathname, scriptname = os.path.split(sys.argv[0])&lt;br /&gt;
print &amp;quot;Relative script dir: &amp;quot;,pathname&lt;br /&gt;
print &amp;quot;Script dir: &amp;quot;, os.path.abspath(pathname)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 os.path.realpath(__file__)&lt;br /&gt;
&lt;br /&gt;
 print &#039;sys.argv[0] =&#039;, sys.argv[0]             &lt;br /&gt;
 pathname = os.path.dirname(sys.argv[0])        &lt;br /&gt;
 print &#039;path =&#039;, pathname&lt;br /&gt;
 print &#039;full path =&#039;, os.path.abspath(pathname)&lt;br /&gt;
&lt;br /&gt;
=== Environment Variables ===&lt;br /&gt;
&lt;br /&gt;
 import os&lt;br /&gt;
 a = os.environ.get(&#039;MYVAR&#039;)               # get environment var&lt;br /&gt;
 a = os.environ.get(&#039;MYVAR&#039;,&#039;default&#039;)     # get environment var&lt;br /&gt;
 a = os.environ[&#039;MYVAR&#039;]                   # get environment var&lt;br /&gt;
 os.environ[&#039;MYVAR&#039;] = &#039;something&#039;         # set environment var&lt;br /&gt;
 os.environ.update({&#039;MYVAR&#039;:&#039;something&#039;})  # set environment var&lt;br /&gt;
&lt;br /&gt;
 for env in os.environ:&lt;br /&gt;
   print &amp;quot;%s = %s&amp;quot; % (env, os.environ[env])&lt;br /&gt;
&lt;br /&gt;
 with open(&amp;quot;environment.txt&amp;quot;, &amp;quot;w&amp;quot;) as f:&lt;br /&gt;
   for env in os.environ:&lt;br /&gt;
      f.write(&amp;quot;%s = %s\n&amp;quot; % (env, os.environ[env]))&lt;br /&gt;
&lt;br /&gt;
=== PYTHONPATH ===&lt;br /&gt;
&lt;br /&gt;
Environment Search path:&lt;br /&gt;
 PYTHONPATH=...&lt;br /&gt;
&lt;br /&gt;
From Code:&lt;br /&gt;
 sys.path.append(&#039;...&#039;)&lt;br /&gt;
&lt;br /&gt;
Get site-package directory from shell: [http://stackoverflow.com/questions/122327/how-do-i-find-the-location-of-my-python-site-packages-directory]&lt;br /&gt;
 python -c &amp;quot;from distutils.sysconfig import get_python_lib; print(get_python_lib())&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Import and Modules ===&lt;br /&gt;
&lt;br /&gt;
Import and Modules - http://docs.python.org/tutorial/modules.html&lt;br /&gt;
&lt;br /&gt;
Import module:&lt;br /&gt;
 import package            # standard import&lt;br /&gt;
 import package.code       # nested name space&lt;br /&gt;
 from package import code  # import specifics from module&lt;br /&gt;
 import module             # standard import&lt;br /&gt;
 from math import sin      # import specifics from module&lt;br /&gt;
 from module import myfunc as fun1  # alias function/object&lt;br /&gt;
 import math as other_math # alias module&lt;br /&gt;
 import longname as ln     # alias module&lt;br /&gt;
 from module import *      # BAD BAD BAD!&lt;br /&gt;
&lt;br /&gt;
 import math&lt;br /&gt;
 math.pow(x,y)&lt;br /&gt;
&lt;br /&gt;
Group and organize by:&lt;br /&gt;
* stdlib libraries&lt;br /&gt;
* local libraries&lt;br /&gt;
* 3rd party libraries&lt;br /&gt;
&lt;br /&gt;
Remove import:&lt;br /&gt;
 del math&lt;br /&gt;
&lt;br /&gt;
 from math import *&lt;br /&gt;
 pow(x,y)&lt;br /&gt;
&lt;br /&gt;
 from math import pow&lt;br /&gt;
 pow(x,y)&lt;br /&gt;
&lt;br /&gt;
 import math as math_lib   # rename&lt;br /&gt;
 math_lib.pow(x,y)&lt;br /&gt;
&lt;br /&gt;
List functions in module:&lt;br /&gt;
 import math&lt;br /&gt;
 dir(math)&lt;br /&gt;
&lt;br /&gt;
List all built in functions:&lt;br /&gt;
 dir(__builtins__)&lt;br /&gt;
&lt;br /&gt;
Note: Modules have the extension .py&lt;br /&gt;
&lt;br /&gt;
Simply module Example:&lt;br /&gt;
&lt;br /&gt;
 # mymod.py:&lt;br /&gt;
 def hello():&lt;br /&gt;
   &amp;quot;&amp;quot;&amp;quot; this is a doc string &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
   print &amp;quot;Hello World&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 # Use the module:&lt;br /&gt;
 import mymod&lt;br /&gt;
 mymod.hello():&lt;br /&gt;
&lt;br /&gt;
 # Use everything in the the module, except for names beginning with &#039;_&#039;:  (bad practice!)&lt;br /&gt;
 from mymod import *&lt;br /&gt;
 hello()&lt;br /&gt;
&lt;br /&gt;
 # Use specific functions in the module:&lt;br /&gt;
 from mymod import hello, hi&lt;br /&gt;
 hello()&lt;br /&gt;
&lt;br /&gt;
 # Function assignment:&lt;br /&gt;
 h = mymod.hello&lt;br /&gt;
 h()&lt;br /&gt;
&lt;br /&gt;
 # module name&lt;br /&gt;
 mymod.__name__   # mymod&lt;br /&gt;
 __name__         # used inside of module will print current module or &amp;quot;__main__&amp;quot; if directly called&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Note: careful when building own modules, as the import literally imports and executes the code, so any code not in functions is executed!&lt;br /&gt;
&lt;br /&gt;
Check if being called directly or indirectly:&lt;br /&gt;
 if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
   # execute tests...&lt;br /&gt;
&lt;br /&gt;
Standard Script Setup:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def main(args):&lt;br /&gt;
  # do logic&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
  sys.exit(main(sys.argv))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Easter egg:&lt;br /&gt;
 # The Zen of Python&lt;br /&gt;
 import this&lt;br /&gt;
&lt;br /&gt;
Search path:&lt;br /&gt;
* environment variable &#039;PYTHONPATH&#039;   (on Unix, this is usually .:/usr/local/lib/python)&lt;br /&gt;
* sys.path  (list of paths, initialized to PYTHONPATH)&lt;br /&gt;
** sys.path.append(&#039;path&#039;)&lt;br /&gt;
&lt;br /&gt;
Module folder: [http://stackoverflow.com/questions/391879/organising-my-python-project] [http://stackoverflow.com/questions/279237/python-import-a-module-from-a-folder] [http://stackoverflow.com/questions/72852/how-to-do-relative-imports-in-python]&lt;br /&gt;
 /kenlib/kenmod.py&lt;br /&gt;
 # so you can do &amp;quot;import kenlib.kenmod&amp;quot;&lt;br /&gt;
 # create file &#039;__init__.py&#039; in kenlib/&lt;br /&gt;
&lt;br /&gt;
Check if package exists:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
try:&lt;br /&gt;
    import argparse&lt;br /&gt;
except ImportError:&lt;br /&gt;
    print &amp;gt;&amp;gt; sys.stderr, &amp;quot;Please install argparse from http://code.google.com/p/&lt;br /&gt;
argparse.&amp;quot;&lt;br /&gt;
    exit(1)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== ifmain ===&lt;br /&gt;
&lt;br /&gt;
 if __name__ == &#039;__main__&#039;:&lt;br /&gt;
     sys.exit(main(sys.argv))&lt;br /&gt;
&lt;br /&gt;
 if __name__ == &#039;__main__&#039;:&lt;br /&gt;
     sys.exit(main(sys.argv[1:]) or 0)&lt;br /&gt;
&lt;br /&gt;
=== Lists ===&lt;br /&gt;
&lt;br /&gt;
* Lists can be modified (mutable)&lt;br /&gt;
* Tuples are constant (immutable)&lt;br /&gt;
&lt;br /&gt;
List: (mutable or modifiable)&lt;br /&gt;
 x = []  # empty list&lt;br /&gt;
 x = [5] # singleton list&lt;br /&gt;
&lt;br /&gt;
 s = list(&amp;quot;Hello World&amp;quot;)&lt;br /&gt;
 print(s)  # s = [&#039;H&#039;, &#039;e&#039;, &#039;l&#039;, &#039;l&#039;, &#039;o&#039;, &#039; &#039;, &#039;W&#039;, &#039;o&#039;, &#039;r&#039;, &#039;l&#039;, &#039;d&#039;]&lt;br /&gt;
 s[0] = &#039;X&#039;&lt;br /&gt;
&lt;br /&gt;
 s.append(x)     # append x&lt;br /&gt;
 s.insert(i, x)  # insert x at i&lt;br /&gt;
 del(s[i])       # delete item at i&lt;br /&gt;
 s.sort()        # sort (modify in place!)&lt;br /&gt;
 s.reverse()     # reverse&lt;br /&gt;
 s.index(x)      # index of x in s&lt;br /&gt;
 new = old[:]    # create copy of list&lt;br /&gt;
 new = list(old) # create copy of list&lt;br /&gt;
&lt;br /&gt;
Check if item in list:&lt;br /&gt;
 if x in s: ...&lt;br /&gt;
&lt;br /&gt;
Filter list of strings based on contents: [https://stackoverflow.com/questions/2152898/filtering-a-list-of-strings-based-on-contents]&lt;br /&gt;
 res = [k for k in lst if &#039;ab&#039; in k]&lt;br /&gt;
&lt;br /&gt;
List comprehension&lt;br /&gt;
 [n * n for n in range(1, 11)]   # squares of numbers 1 to 10&lt;br /&gt;
 [c for c in &#039;pizza&#039;]            # list of string &#039;pizza&#039;&lt;br /&gt;
 [c.upper() for c in &#039;pizza&#039;]    # list of string &#039;pizza&#039; uppercase&lt;br /&gt;
 [n for n in nums if n &amp;gt; 0]      # filters out only positive numbers in nums list&lt;br /&gt;
 [fname for fname in os.listdir(path)  # on multiple lines&lt;br /&gt;
    if os.path.isfile(fname)&lt;br /&gt;
    if fname.endswith(&#039;.py&#039;)]&lt;br /&gt;
&lt;br /&gt;
Enumeration&lt;br /&gt;
 for index, value in enumerate(mylist):  print index, value&lt;br /&gt;
&lt;br /&gt;
Length:&lt;br /&gt;
 len(x)&lt;br /&gt;
&lt;br /&gt;
Concatenation:&lt;br /&gt;
 x + s&lt;br /&gt;
 x * 2&lt;br /&gt;
&lt;br /&gt;
Convert list to string:&lt;br /&gt;
 &amp;quot;&amp;quot;.join(mylist)  # no separator&lt;br /&gt;
 &amp;quot; &amp;quot;.join(mylist) # space separator&lt;br /&gt;
 &amp;quot;,&amp;quot;.join(mylist) # comma separator&lt;br /&gt;
&lt;br /&gt;
Test Membership&lt;br /&gt;
 x in s&lt;br /&gt;
&lt;br /&gt;
Multi dimensional list:&lt;br /&gt;
 mylist = [ [0,&amp;quot;hi&amp;quot;], [1,&amp;quot;bye&amp;quot;] ]&lt;br /&gt;
 print( mylist[0][1] )&lt;br /&gt;
&lt;br /&gt;
Sorting: (see lambda)&lt;br /&gt;
 data.sort()  # alpha numerica sort&lt;br /&gt;
 data.reverse()  # alpha numerica sort&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# custom sort&lt;br /&gt;
data = [1, 5, 3, 9]&lt;br /&gt;
def mylistcmp(x, y):&lt;br /&gt;
  if x == y: return 0&lt;br /&gt;
  if x &amp;lt; y:&lt;br /&gt;
    return -1&lt;br /&gt;
  else:  # swap 1 and -1 here to reverse&lt;br /&gt;
    return 1&lt;br /&gt;
&lt;br /&gt;
data.sort(cmp=mylistcmp)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Slices:&lt;br /&gt;
 lst = [&#039;1a&#039;, &#039;2b&#039;, &#039;3c&#039;, &#039;4d&#039;, &#039;5e&#039;, &#039;6f&#039;]&lt;br /&gt;
 lst[0]     # &#039;1a&#039;&lt;br /&gt;
 lst[-1]    # &#039;6f&#039; last item&lt;br /&gt;
 lst[0:2]   # [&#039;1a&#039;, &#039;2b&#039;]&lt;br /&gt;
 lst[0:2] = [&#039;11&#039;, &#039;22&#039;]   # lst = [&#039;11&#039;, &#039;22&#039;, &#039;3c&#039;, &#039;4d&#039;, &#039;5e&#039;, &#039;6f&#039;] - assignment to slice&lt;br /&gt;
 lst[0:2] = []   # remove items&lt;br /&gt;
 lst[0:0] = [&#039;1a&#039;, &#039;2b&#039;]   # insert items (at beginning)&lt;br /&gt;
 lst[-1:-1] = [&#039;7g&#039;, &#039;8h&#039;]   # insert items (at item BEFORE last), not really what you want, use append()&lt;br /&gt;
 lst[-1:] = [&#039;7g&#039;, &#039;8h&#039;]   # replace last item&lt;br /&gt;
 lst[:] = []   # clear entire list&lt;br /&gt;
 del(lst[0:2])  # delete slice items&lt;br /&gt;
&lt;br /&gt;
Note: it is not safe to modify a sequence while being iterated over.  Create a copy first:&lt;br /&gt;
 for x in mylst[:]:  # make a slice copy of the entire list&lt;br /&gt;
   if len(x) &amp;gt; 6: a.insert(0,x)&lt;br /&gt;
&lt;br /&gt;
Make list from tuple:&lt;br /&gt;
 list( range(10) )&lt;br /&gt;
&lt;br /&gt;
Merge multiple lists: [http://www.testingreflections.com/node/view/4930]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def merge(seq):&lt;br /&gt;
    merged = []&lt;br /&gt;
    for s in seq:&lt;br /&gt;
        for x in s:&lt;br /&gt;
            merged.append(x)&lt;br /&gt;
    return merged&lt;br /&gt;
&lt;br /&gt;
# sample usage:&lt;br /&gt;
foo = [[&#039;a&#039;, &#039;b&#039;],[&#039;c&#039;],[&#039;d&#039;, &#039;e&#039;, &#039;f&#039;]]&lt;br /&gt;
print merge(foo)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt;[&#039;a&#039;, &#039;b&#039;, &#039;c&#039;, &#039;d&#039;, &#039;e&#039;, &#039;f&#039;]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Tuple ===&lt;br /&gt;
&lt;br /&gt;
Tuple: (immutable or constant)&lt;br /&gt;
 x = ()    # empty tuple&lt;br /&gt;
 x = (5,)  # singleton tuple&lt;br /&gt;
 x = (5)   # NOTE: integer with parenthesis, not tuple&lt;br /&gt;
 &lt;br /&gt;
 s = tuple(&amp;quot;Hello World&amp;quot;)&lt;br /&gt;
 print(s)  # s = (&#039;H&#039;, &#039;e&#039;, &#039;l&#039;, &#039;l&#039;, &#039;o&#039;, &#039; &#039;, &#039;W&#039;, &#039;o&#039;, &#039;r&#039;, &#039;l&#039;, &#039;d&#039;)&lt;br /&gt;
 # ERROR: s[0] = &#039;X&#039;&lt;br /&gt;
&lt;br /&gt;
Make list from tuple:&lt;br /&gt;
 list( range(10) )&lt;br /&gt;
&lt;br /&gt;
Use in conditionals:&lt;br /&gt;
 if answer in (&#039;y&#039;, &#039;ye&#039;, &#039;yes&#039;): ...&lt;br /&gt;
&lt;br /&gt;
Convert tuple string to tuple: [http://stackoverflow.com/questions/3945856/converting-string-to-tuple-and-adding-to-tuple]&lt;br /&gt;
 x = &amp;quot;(1,2,3)&amp;quot;&lt;br /&gt;
 t = tuple(int(v) for v in re.findall(&amp;quot;[0-9]+&amp;quot;, x))&lt;br /&gt;
&lt;br /&gt;
Another Convert tuple string to tuple: [http://stackoverflow.com/questions/3945856/converting-string-to-tuple-and-adding-to-tuple]&lt;br /&gt;
 import ast&lt;br /&gt;
 ast.literal_eval(&amp;quot;(1,2,3,4)&amp;quot;) # (1,2,3,4)&lt;br /&gt;
&lt;br /&gt;
=== Named Tuple ===&lt;br /&gt;
&lt;br /&gt;
What are &amp;quot;named tuples&amp;quot; in Python? - Stack Overflow - http://stackoverflow.com/questions/2970608/what-are-named-tuples-in-python&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from collections import namedtuple&lt;br /&gt;
Point = namedtuple(&#039;Point&#039;, &#039;x y&#039;)&lt;br /&gt;
pt1 = Point(1.0, 5.0)&lt;br /&gt;
pt2 = Point(2.5, 1.5)&lt;br /&gt;
print p1     # point(x=1, y=5)&lt;br /&gt;
print p1.x   # 1.0&lt;br /&gt;
print p1[0]  # 1.0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Dictionary ===&lt;br /&gt;
&lt;br /&gt;
NOTE: Dictionaries are also known as associative arrays, maps or hash tables.&lt;br /&gt;
&lt;br /&gt;
Dictionary: (mutable or modifiable)&lt;br /&gt;
&lt;br /&gt;
 color = {}                      # empty dictionary&lt;br /&gt;
 color = {&#039;red&#039; : 1, &#039;blue&#039;, 2}&lt;br /&gt;
 print( color[&#039;red&#039;] )           # 1&lt;br /&gt;
 print( color.get(&#039;red&#039;) )       # 1&lt;br /&gt;
 print( color.get(&#039;red&#039;, &#039;default&#039;) )       # red if found, or return &#039;default&#039;&lt;br /&gt;
 color[&#039;green&#039;] = 3              # able to add new item on the fly!&lt;br /&gt;
 &#039;red&#039; in color                  # True - check if index exists&lt;br /&gt;
 del(color[&amp;quot;red&amp;quot;])               # delete item&lt;br /&gt;
 len(color)                      # 2 - count of items&lt;br /&gt;
&lt;br /&gt;
List in dictionary&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
d.setdefault(key,[]).append(member)  # tricky!&lt;br /&gt;
&lt;br /&gt;
# more tricky: set default type as list&lt;br /&gt;
from from collections import defaultdict&lt;br /&gt;
d = defaultdict(list)&lt;br /&gt;
d[key].append(member)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Enumeration:&lt;br /&gt;
 for index, key in enumerate(mylist):  print index, key&lt;br /&gt;
&lt;br /&gt;
functions:&lt;br /&gt;
 d.clear()&lt;br /&gt;
 d.copy()&lt;br /&gt;
 d.get(key)&lt;br /&gt;
 d.get(key, default_val)&lt;br /&gt;
 d.update(e)   # update with (key, value) pairs in e&lt;br /&gt;
 d.setdefault(key, value)  # only update if not exist, and return set value&lt;br /&gt;
&lt;br /&gt;
Views: (adjust on the fly as dictionary changes)&lt;br /&gt;
 d.items()  (key, values)&lt;br /&gt;
 for k, v in d.items(): print(k, v)&lt;br /&gt;
 &lt;br /&gt;
 d.keys()&lt;br /&gt;
 for k in d.keys(): print(k)&lt;br /&gt;
 &lt;br /&gt;
 d.values()&lt;br /&gt;
 for v in d.values(): print(v)&lt;br /&gt;
&lt;br /&gt;
Sorting: (see also lambda)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# custom sort of dictionaries in list&lt;br /&gt;
data = [dict(number=x) for x in &#039;036149&#039;]  # create list of dictionaries&lt;br /&gt;
def mydictcmp(x, y):&lt;br /&gt;
  if x[&#039;number&#039;] == y[&#039;number&#039;]: return 0&lt;br /&gt;
  if x[&#039;number&#039;] &amp;lt; y[&#039;number&#039;]:&lt;br /&gt;
    return -1&lt;br /&gt;
  else:  # swap 1 and -1 here to reverse&lt;br /&gt;
    return 1&lt;br /&gt;
&lt;br /&gt;
# data.sort(cmp=mydictcmp)  # modifies data&lt;br /&gt;
&lt;br /&gt;
new_data = sorted(data, cmp=mydictcmp)  # better solution&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sorting:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
my_dict = {&#039;a&#039;:1, &#039;b&#039;:4, &#039;c&#039;:3, &#039;d&#039;:9}&lt;br /&gt;
my_dict_keys = my_dict.keys()&lt;br /&gt;
&lt;br /&gt;
def my_dict_sort(x, y):&lt;br /&gt;
    if my_dict[x] == my_dict[y]: return 0&lt;br /&gt;
    if my_dict[x] &amp;lt; my_dict[y]: return -1&lt;br /&gt;
    if my_dict[x] &amp;gt; my_dict[y]: return 1&lt;br /&gt;
&lt;br /&gt;
#sorted_my_dict = sorted(my_dict_keys, cmp=my_dict_sort, reverse=True)&lt;br /&gt;
sorted_tuple = sorted(my_dict_keys, cmp=my_dict_sort)&lt;br /&gt;
print &amp;quot;Sorted Dictionary:&amp;quot;&lt;br /&gt;
for key in sorted_tuple:&lt;br /&gt;
    print &amp;quot;%s: %d&amp;quot; % (key, my_dict[key])&lt;br /&gt;
&lt;br /&gt;
# a: 1, c: 3, b: 4, d: 9,&lt;br /&gt;
# reverse: d: 9, b: 4, c: 3, a: 1,&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sort and keys:&lt;br /&gt;
 keys = sorted(mydict.keys())&lt;br /&gt;
&lt;br /&gt;
Sort by value: [http://stackoverflow.com/questions/613183/python-sort-a-dictionary-by-value]&lt;br /&gt;
 import operator&lt;br /&gt;
 x = {1: 2, 3: 4, 4:3, 2:1, 0:0}&lt;br /&gt;
 sorted_x = sorted(x.iteritems(), key=operator.itemgetter(1))&lt;br /&gt;
&lt;br /&gt;
Sort options:&lt;br /&gt;
 # LIST.sort(cmp=None, key=None, reverse=False) -- stable sort *IN PLACE*;&lt;br /&gt;
 # sorted(iterable, cmp=None, key=None, reverse=False)&lt;br /&gt;
&lt;br /&gt;
Another: (works well!)&lt;br /&gt;
 sorted(my_dict.items(), key=lambda x: x[1])&lt;br /&gt;
&lt;br /&gt;
See: http://wiki.python.org/moin/HowTo/Sorting/&lt;br /&gt;
&lt;br /&gt;
=== Sets ===&lt;br /&gt;
&lt;br /&gt;
Sets are special lists with unique values (good for removing duplicates)&lt;br /&gt;
 lst = [1, 1, 6, 8, 1, 5]&lt;br /&gt;
 s = set(lst)&lt;br /&gt;
 print(s)  # set([8, 1, 5, 6])&lt;br /&gt;
 s.add(item)&lt;br /&gt;
 item in s  # true&lt;br /&gt;
 s.remove(item)&lt;br /&gt;
&lt;br /&gt;
Union (return combination of all):&lt;br /&gt;
 s.union(t)&lt;br /&gt;
&lt;br /&gt;
Intersection (return matching):&lt;br /&gt;
 s.intersection(t)&lt;br /&gt;
&lt;br /&gt;
Symmetric Difference (return only items not matching either, inverse of intersection):&lt;br /&gt;
 s.symmetric_difference(t)&lt;br /&gt;
 list( set(mylist).symmetric_difference(set(mylist2)) )&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Operation		   Equivalent	Result&lt;br /&gt;
len(s) 	  				cardinality of set s&lt;br /&gt;
x in s 	  				test x for membership in s&lt;br /&gt;
x not in s 	  			test x for non-membership in s&lt;br /&gt;
s.issubset(t) 		   s &amp;lt;= t       test whether every element in s is in t&lt;br /&gt;
s.issuperset(t) 	   s &amp;gt;= t 	test whether every element in t is in s&lt;br /&gt;
s.union(t) 		   s | t 	new set with elements from both s and t&lt;br /&gt;
s.intersection(t)	   s &amp;amp; t 	new set with elements common to s and t&lt;br /&gt;
s.difference(t) 	   s - t	new set with elements in s but not in t&lt;br /&gt;
s.symmetric_difference(t)  s ^ t 	new set with elements in either s or t but not both&lt;br /&gt;
s.copy() 	  			new set with a shallow copy of s&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* sets — Unordered collections of unique elements - http://docs.python.org/library/sets.html&lt;br /&gt;
&lt;br /&gt;
=== Files ===&lt;br /&gt;
&lt;br /&gt;
Open file, get file descriptor:&lt;br /&gt;
 fd = open(&#039;/dev/null&#039;)&lt;br /&gt;
&lt;br /&gt;
File Modes:&lt;br /&gt;
 &#039;r&#039; read (default)&lt;br /&gt;
 &#039;w&#039; write (truncate and create if needed)&lt;br /&gt;
 &#039;a&#039; append (create if needed)&lt;br /&gt;
 &lt;br /&gt;
 &#039;b&#039; binary&lt;br /&gt;
 &#039;t&#039; text (default)&lt;br /&gt;
 &lt;br /&gt;
 &#039;+&#039; read and write&lt;br /&gt;
&lt;br /&gt;
Common Functions: (fd)&lt;br /&gt;
&lt;br /&gt;
 f.read()       # read whole file to string&lt;br /&gt;
 f.read(n)      # read n bytes from file to string&lt;br /&gt;
 f.readline()   # read single line as string (while loop)&lt;br /&gt;
 f.readlines()  # read all lines to list&lt;br /&gt;
&lt;br /&gt;
 f.write(str)   # write string to file (does not auto include new line)&lt;br /&gt;
 f.writelines(list)  # write list to file (does not auto include new lines)&lt;br /&gt;
&lt;br /&gt;
 f.seek(0)      # seek to start of file&lt;br /&gt;
 f.seek(pos)    # seek to position&lt;br /&gt;
 f.truncate()   # truncate file&lt;br /&gt;
&lt;br /&gt;
 f.close()      # close file (fd)&lt;br /&gt;
 f.closed       # True/False flag that reports if file is closed&lt;br /&gt;
&lt;br /&gt;
Help:&lt;br /&gt;
 help(open(&#039;/dev/null&#039;))&lt;br /&gt;
 pydoc file&lt;br /&gt;
&lt;br /&gt;
Read Text File Line by Line&lt;br /&gt;
 f = open(fname, &#039;r&#039;)  # (&#039;r&#039; optional)&lt;br /&gt;
 for line in f:  # or f.readlines()&lt;br /&gt;
   print(line)&lt;br /&gt;
 f.close()  # optional&lt;br /&gt;
&lt;br /&gt;
Write list to file (with new lines):&lt;br /&gt;
 f.writelines(&#039;\n&#039;.join(mylist))&lt;br /&gt;
&lt;br /&gt;
One liner read whole file:&lt;br /&gt;
 print( open( fname, &#039;r&#039; ).read() )&lt;br /&gt;
&lt;br /&gt;
Write text file:&lt;br /&gt;
 # f = open(fname, &#039;a&#039;)  # append text file&lt;br /&gt;
 f = open(fname, &#039;w&#039;)&lt;br /&gt;
 f.write(&amp;quot;Hello\n&amp;quot;)&lt;br /&gt;
 f.write( str(10) )  # convert numbers to strings first&lt;br /&gt;
 f.writelines([&amp;quot;line one\n&amp;quot;, &amp;quot;line two\n&amp;quot;])&lt;br /&gt;
 f.close&lt;br /&gt;
&lt;br /&gt;
Read binary file:&lt;br /&gt;
 def is_gif(fname):&lt;br /&gt;
   f = open(fname, &#039;br&#039;)  # not sure &#039;b&#039; is correct&lt;br /&gt;
   first4 = tuple(f.read(4))&lt;br /&gt;
   return first4 == (0x47, 0x49, 0x46, 0x38)&lt;br /&gt;
&lt;br /&gt;
Read all characters of file:&lt;br /&gt;
 c = f.read(1)&lt;br /&gt;
 while c:&lt;br /&gt;
   # if c == ... logic&lt;br /&gt;
   c = f.read(1)&lt;br /&gt;
&lt;br /&gt;
Reading file in while loop: [http://ubuntuforums.org/showthread.php?t=1092300]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
f=open(&amp;quot;file&amp;quot;)&lt;br /&gt;
while True:&lt;br /&gt;
  line=f.readline()&lt;br /&gt;
  if not line: break&lt;br /&gt;
  print line  &lt;br /&gt;
f.close()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
with - implicit close - [http://www.python.org/dev/peps/pep-0343/ PEP 343 -- The &amp;quot;with&amp;quot; Statement]: [http://docs.python.org/reference/compound_stmts.html#the-with-statement] (python &amp;gt;= 2.5)&lt;br /&gt;
 with open(&amp;quot;/etc/passwd&amp;quot;) as f:&lt;br /&gt;
   # ..., f.read(), etc&lt;br /&gt;
&lt;br /&gt;
With statement: (promptly close open handle at end of block)&lt;br /&gt;
 with open(fname, &#039;r&#039;) as f:&lt;br /&gt;
   for ...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# eqivalent to:&lt;br /&gt;
f = open(&amp;quot;/etc/passwd&amp;quot;)&lt;br /&gt;
f.__enter__()&lt;br /&gt;
try:&lt;br /&gt;
  ...&lt;br /&gt;
finally:&lt;br /&gt;
  f.__exit__()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
cat: (for grabbing a configuration line)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def cat(filename):&lt;br /&gt;
    with open(filename) as f:&lt;br /&gt;
        return f.readline().strip()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== With ===&lt;br /&gt;
&lt;br /&gt;
PEP 343 -- The &amp;quot;with&amp;quot; Statement - http://www.python.org/dev/peps/pep-0343/&lt;br /&gt;
&lt;br /&gt;
&#039;with&#039; structure:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
with EXPR as VAR:&lt;br /&gt;
  BLOCK&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
translates to:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
VAR = EXPR&lt;br /&gt;
VAR.__enter__()&lt;br /&gt;
try:&lt;br /&gt;
  BLOCK&lt;br /&gt;
finally:&lt;br /&gt;
  VAR.__exit__()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: The &amp;quot;as VAR&amp;quot; part is optional.  Good for locking:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
with locking(myLock):&lt;br /&gt;
  BLOCK&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
with - implicit close - [http://www.python.org/dev/peps/pep-0343/ PEP 343 -- The &amp;quot;with&amp;quot; Statement]: [http://docs.python.org/reference/compound_stmts.html#the-with-statement] (python &amp;gt;= 2.5)&lt;br /&gt;
 with open(&amp;quot;/etc/passwd&amp;quot;) as f:&lt;br /&gt;
   ...&lt;br /&gt;
&lt;br /&gt;
With statement: (promptly close open handle at end of block)&lt;br /&gt;
 with open(fname, &#039;r&#039;) as f:&lt;br /&gt;
   for ...&lt;br /&gt;
&lt;br /&gt;
See also [[#Files]]&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* PEP 343 -- The &amp;quot;with&amp;quot; Statement - http://www.python.org/dev/peps/pep-0343/&lt;br /&gt;
* PEP 340 -- Anonymous Block Statements - http://www.python.org/dev/peps/pep-0340/&lt;br /&gt;
&lt;br /&gt;
=== Try Exception Handling ===&lt;br /&gt;
&lt;br /&gt;
Exception Handling - http://docs.python.org/release/2.6.6/tutorial/errors.html&lt;br /&gt;
&lt;br /&gt;
throw execption:&lt;br /&gt;
 raise [EXCEPTION]&lt;br /&gt;
 raise IOError(&amp;quot;This is a test!&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Catch exceptions:&lt;br /&gt;
 try:&lt;br /&gt;
 except ( [EXCEPTION], [EXCEPTION] ):&lt;br /&gt;
 except [EXCEPTION]:&lt;br /&gt;
 except [EXCEPTION] as err:  # use &amp;quot;[EXCEPTION], err&amp;quot; in python &amp;lt; 2.6&lt;br /&gt;
   print(&amp;quot;Error: {}&amp;quot;.format(err))&lt;br /&gt;
 except:&lt;br /&gt;
   raise   # reraise caught error that is not handled&lt;br /&gt;
 else:     # if no exception caught&lt;br /&gt;
 finally:  # always executed&lt;br /&gt;
&lt;br /&gt;
Note: Usually a good idea to re-raise exception if you don&#039;t handle it (just &#039;raise&#039;)&lt;br /&gt;
&lt;br /&gt;
General Exception: (all exceptions inherit from Exception)&lt;br /&gt;
 try:&lt;br /&gt;
   raise Exception(&#039;spam&#039;, &#039;eggs&#039;)&lt;br /&gt;
 except Exception as e:&lt;br /&gt;
   pass&lt;br /&gt;
&lt;br /&gt;
Custom Exception Class:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class MyError(Exception):&lt;br /&gt;
  &amp;quot;&amp;quot;&amp;quot;My Error Exception&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
class MyException(Exception):&lt;br /&gt;
    pass&lt;br /&gt;
&lt;br /&gt;
rasie MyError(&amp;quot;My Error&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class ValidationError(Exception):&lt;br /&gt;
    def __init__(self, message, Errors):&lt;br /&gt;
&lt;br /&gt;
        # Call the base class constructor with the parameters it needs&lt;br /&gt;
        Exception.__init__(self, message)&lt;br /&gt;
&lt;br /&gt;
        # Now for your custom code...&lt;br /&gt;
        self.Errors = Errors&lt;br /&gt;
    def __str__(self):&lt;br /&gt;
        return &amp;quot;MyErrors - %s&amp;quot; % self.Errors&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Rename standard exception:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Failure(StandardError):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;Exception for unexpected failures.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: a good place to hide the exception classes in the __init__.py file.&lt;br /&gt;
&lt;br /&gt;
==== exception line number ====&lt;br /&gt;
&lt;br /&gt;
Python When I catch an exception, how do I get the type, file, and line number? - Stack Overflow [http://stackoverflow.com/questions/1278705/python-when-i-catch-an-exception-how-do-i-get-the-type-file-and-line-number]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import sys, os&lt;br /&gt;
&lt;br /&gt;
try:&lt;br /&gt;
    raise NotImplementedError(&amp;quot;No error&amp;quot;)&lt;br /&gt;
except Exception as e:&lt;br /&gt;
    exc_type, exc_obj, exc_tb = sys.exc_info()&lt;br /&gt;
    fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]&lt;br /&gt;
    print(exc_type, fname, exc_tb.tb_lineno)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== traceback ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import traceback&lt;br /&gt;
    try:&lt;br /&gt;
    ...&lt;br /&gt;
    except Exception as E:&lt;br /&gt;
        ...&lt;br /&gt;
        print &#039;Traceback: %s&#039;, traceback.format_exc()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Catching multiple exceptions and getting properties from the exception:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import traceback&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
class MyError(Exception):&lt;br /&gt;
  &amp;quot;&amp;quot;&amp;quot;My Error Exception&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
try:&lt;br /&gt;
  #raise ValueError(&amp;quot;a value error&amp;quot;)  # &amp;lt;type &#039;exceptions.ValueError&#039;&amp;gt;&lt;br /&gt;
  raise MyError(&amp;quot;a my error&amp;quot;)         # &amp;lt;class &#039;__main__.MyError&#039;&amp;gt;&lt;br /&gt;
  raise Exception(&amp;quot;won&#039;t be caught&amp;quot;)  # &amp;lt;type &#039;exceptions.Exception&#039;&amp;gt;&lt;br /&gt;
except (ValueError, MyError) as e:&lt;br /&gt;
  print type(e)       # &amp;lt;class &#039;__main__.MyError&#039;&amp;gt;&lt;br /&gt;
  print e             # __str__() = a my error&lt;br /&gt;
  msg = str(e)        # msg = &#039;a my error&#039;&lt;br /&gt;
  print e.__doc__     # My Error Exception&lt;br /&gt;
  print e.__str__()   # a my error&lt;br /&gt;
  print e.__repr__()  # MyError(&#039;a my error&#039;,)&lt;br /&gt;
  print e.args        # (&#039;a my error&#039;,)&lt;br /&gt;
  x = e               # __getitem__() allows args to be unpacked directly&lt;br /&gt;
  # x, y = e          # if two args were passed, use len(e.args) to see count&lt;br /&gt;
&lt;br /&gt;
  # manually print stack trace (import traceback, sys)&lt;br /&gt;
  print &amp;quot;Exception in user code:&amp;quot;&lt;br /&gt;
  print &#039;-&#039;*60&lt;br /&gt;
  traceback.print_exc(file=sys.stdout)&lt;br /&gt;
  # stack_trace = traceback.format_exc()&lt;br /&gt;
  print &#039;-&#039;*60&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Object Oriented Programming ===&lt;br /&gt;
&lt;br /&gt;
Terms:&lt;br /&gt;
* encapsulates&lt;br /&gt;
* inheritance&lt;br /&gt;
* polymorphism&lt;br /&gt;
* method overriding&lt;br /&gt;
&lt;br /&gt;
==== class ====&lt;br /&gt;
&lt;br /&gt;
class animal.py:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Animal(object):  # default &amp;quot;(object)&amp;quot; not required&lt;br /&gt;
  &amp;quot; Animal class &amp;quot;&lt;br /&gt;
  def __init__(self, name):&lt;br /&gt;
    self.name = name       # name is private variable&lt;br /&gt;
    self.__iam = &amp;quot;animal&amp;quot;  # __iam is private variable&lt;br /&gt;
  def __str__(self):       # string representation&lt;br /&gt;
    return &amp;quot;name = &#039;%s&#039;&amp;quot; % (self.name)&lt;br /&gt;
  def __repr__(self):      # object representation (just typing instance in IDLE, or repr())&lt;br /&gt;
    return &#039;Animal(%s)&#039; % str(self)  # returns __str__&lt;br /&gt;
  def speak(self, msg=&#039;Nothing to say&#039;):&lt;br /&gt;
    print(msg)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: if no __str__ defined, but __repr__ is, then:  __str__ = __repr__&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from animal import Animal&lt;br /&gt;
a = Animal(&#039;good&#039;)&lt;br /&gt;
print(a.__doc__)  # Animal class&lt;br /&gt;
print(a)          # name = &#039;good&#039;&lt;br /&gt;
a                 # Animal(name = &#039;good&#039;)&lt;br /&gt;
print(a.name)     # good&lt;br /&gt;
a.speak(&#039;hi&#039;)     # hi&lt;br /&gt;
print(a._Animal__iam)  # animal - access to private variable (shouldn&#039;t do)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
subclass dog.py:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from animal import Animal&lt;br /&gt;
class Dog(Animal):&lt;br /&gt;
  &amp;quot; Dog class &amp;quot;&lt;br /&gt;
  def __init__(self, name):&lt;br /&gt;
    self.name = name      # name is private variable&lt;br /&gt;
    self.__iam = &amp;quot;dog&amp;quot;    # __iam is private variable&lt;br /&gt;
  # NOTICE: no __str__, inherited from super class&lt;br /&gt;
  def __repr__(self):     # override to reflect &amp;quot;dog&amp;quot;&lt;br /&gt;
    return &#039;Dog(%s)&#039; % str(self)  # returns __str__&lt;br /&gt;
  def speak(self, msg=&#039;Nothing to say&#039;):   # override method&lt;br /&gt;
    super(Dog, self).speak(&#039;Dog says: &#039; + msg)     # call super class method&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Subclass usage:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from dog import Dog&lt;br /&gt;
d = Dog(&#039;bad&#039;)&lt;br /&gt;
print(d.__doc__)    # Dog class&lt;br /&gt;
print(d)            # name = &#039;bad&#039;&lt;br /&gt;
d                   # Dog(name = &#039;bad&#039;)&lt;br /&gt;
print(d.name)       # bad&lt;br /&gt;
d.speak(&#039;hi&#039;)       # Dog says: hi&lt;br /&gt;
print(d._Dog__iam)  # dog - access to private variable (shouldn&#039;t do)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Super: [http://stackoverflow.com/questions/576169/understanding-python-super-with-init-methods]&lt;br /&gt;
 # python 3.0&lt;br /&gt;
 super().__init__()&lt;br /&gt;
&lt;br /&gt;
 # python 2.7&lt;br /&gt;
 super(self.__class__, self).__init__()&lt;br /&gt;
 super([CLASSNAME], self).__init__()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Rectangle(Polygon):&lt;br /&gt;
    def __init__(self, id, width, height):&lt;br /&gt;
        #  super(Rectangle, self).__init__(id)&lt;br /&gt;
        super(self.__class__, self).__init__(id)&lt;br /&gt;
        self.shape = (width, height)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Get class name:&lt;br /&gt;
 self.__class__.__name__&lt;br /&gt;
 obj.__class__.__name__&lt;br /&gt;
&lt;br /&gt;
Full name:&lt;br /&gt;
 obj.__module__ + &amp;quot;.&amp;quot; + obj.__class__.__name__&lt;br /&gt;
&lt;br /&gt;
Private variables: (uses name mangling)&lt;br /&gt;
  self.__age&lt;br /&gt;
  # direct access:  _classname__varname  (eg. p._Person__age = 44)&lt;br /&gt;
&lt;br /&gt;
Tests:&lt;br /&gt;
 isinstance(myobj, myclass)  # check if myobj is a class or subclass of myclass &lt;br /&gt;
 issubclass(A, B)  # check if A is subclass of B&lt;br /&gt;
 issubclass(Exception, BaseException)  # True&lt;br /&gt;
&lt;br /&gt;
Multiple Inheritance:  (methods searched in order)&lt;br /&gt;
 class DerviedClass(Base1, Base2, Base3):&lt;br /&gt;
   pass&lt;br /&gt;
&lt;br /&gt;
Standard startup script:&lt;br /&gt;
 class MyClass():&lt;br /&gt;
     ...&lt;br /&gt;
     @classmethod&lt;br /&gt;
     def main(cls, argv=None):&lt;br /&gt;
         ...&lt;br /&gt;
         # return cls() # creator&lt;br /&gt;
 if __name__ == &amp;quot;__main__&amp;quot;;&lt;br /&gt;
     sys.exit(MyClass.main(sys.argv))&lt;br /&gt;
&lt;br /&gt;
Raise an error if a method is not overridden (not implemented)&lt;br /&gt;
    def _get_dist(self):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Find linux disto. Implemented in subclasses.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        raise NotImplementedError&lt;br /&gt;
&lt;br /&gt;
==== Multiple Constructors ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Animal(object):&lt;br /&gt;
&lt;br /&gt;
  def __init__(self, name):&lt;br /&gt;
    self.name = name&lt;br /&gt;
&lt;br /&gt;
  @classmethod&lt;br /&gt;
  def create_fido(cls):&lt;br /&gt;
    return cls(&amp;quot;fido&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Descriptor Classes ====&lt;br /&gt;
&lt;br /&gt;
&amp;quot;In general, a descriptor is an object attribute with “binding behavior”, one whose attribute access has been overridden by methods in the descriptor protocol: __get__(), __set__(), and __delete__(). If any of those methods are defined for an object, it is said to be a descriptor.&amp;quot; [http://docs.python.org/2/reference/datamodel.html#implementing-descriptors]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
object.__get__(self, instance, owner)&lt;br /&gt;
&lt;br /&gt;
    Called to get the attribute of the owner class (class attribute access) or of an instance of that&lt;br /&gt;
    class (instance attribute access). owner is always the owner class, while instance is the instance&lt;br /&gt;
    that the attribute was accessed through, or None when the attribute is accessed through the owner.&lt;br /&gt;
    This method should return the (computed) attribute value or raise an AttributeError exception.&lt;br /&gt;
&lt;br /&gt;
object.__set__(self, instance, value)&lt;br /&gt;
&lt;br /&gt;
    Called to set the attribute on an instance instance of the owner class to a new value, value.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example: [http://stackoverflow.com/questions/3798835/understanding-get-and-set-and-python-descriptors]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Celsius(object):&lt;br /&gt;
    def __init__(self, value=0.0):&lt;br /&gt;
        self.value = float(value)&lt;br /&gt;
    def __get__(self, instance, owner):&lt;br /&gt;
        return self.value&lt;br /&gt;
    def __set__(self, instance, value):&lt;br /&gt;
        self.value = float(value)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
class Temperature(object):&lt;br /&gt;
    celsius = Celsius()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
t = Temperature()&lt;br /&gt;
t.celsius = 5    # calls Celsius.__set__&lt;br /&gt;
print t.celsius  # calls Celsius.__get__&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: Also appears in &#039;pydoc&#039; under &amp;quot;Data descriptors defined here&amp;quot; with object&#039;s docstring.  Trick: the __doc__ can be overridden in the __init__ method, which makes for dynamic docstrings!&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* Descriptor HowTo Guide — Python v2.7.5 documentation - http://docs.python.org/2/howto/descriptor.html&lt;br /&gt;
* 3.4.2.2. Implementing Descriptors¶ - 3. Data model — Python v2.7.5 documentation - http://docs.python.org/2/reference/datamodel.html#implementing-descriptors&lt;br /&gt;
&lt;br /&gt;
=== [http://docs.python.org/reference/simple_stmts.html#the-exec-statement exec code] ===&lt;br /&gt;
&lt;br /&gt;
DANGEROUS!&lt;br /&gt;
&lt;br /&gt;
Execute code in string:&lt;br /&gt;
 exec( &#039;print(&amp;quot;hi&amp;quot;)&#039; )&lt;br /&gt;
&lt;br /&gt;
Example of executing a startup script for IDLE:&lt;br /&gt;
 if os.path.isfile(&#039;.pythonrc.py&#039;): exec(open(&#039;.pythonrc.py&#039;).read())&lt;br /&gt;
&lt;br /&gt;
 import os&lt;br /&gt;
 filename = os.environ.get(&#039;PYTHONSTARTUP&#039;)&lt;br /&gt;
 if filename and os.path.isfile(filename):&lt;br /&gt;
   exec(open(filename).read())&lt;br /&gt;
&lt;br /&gt;
=== eval ===&lt;br /&gt;
&lt;br /&gt;
VERY DANGEROUS&lt;br /&gt;
&lt;br /&gt;
Will execute a string as though it were pure python code!&lt;br /&gt;
&lt;br /&gt;
 eval(&amp;quot;print &#039;hello&#039;&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
=== Common Header Format ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
__author__ = &amp;quot;software team&amp;quot;&lt;br /&gt;
__date__ =&amp;quot;$Feb 15, 2011 1:42:17 PM$&amp;quot;&lt;br /&gt;
__version__ = &amp;quot;1.1.0.441 bandelier@66d9fe1edf3e&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Next should be authorship information. This information should follow this format:&lt;br /&gt;
&lt;br /&gt;
__author__ = &amp;quot;Rob Knight, Gavin Huttley, and Peter Maxwell&amp;quot;&lt;br /&gt;
__copyright__ = &amp;quot;Copyright 2007, The Cogent Project&amp;quot;&lt;br /&gt;
__credits__ = [&amp;quot;Rob Knight&amp;quot;, &amp;quot;Peter Maxwell&amp;quot;, &amp;quot;Gavin Huttley&amp;quot;,&lt;br /&gt;
                    &amp;quot;Matthew Wakefield&amp;quot;]&lt;br /&gt;
__license__ = &amp;quot;GPL&amp;quot;&lt;br /&gt;
__version__ = &amp;quot;1.0.1&amp;quot;&lt;br /&gt;
__maintainer__ = &amp;quot;Rob Knight&amp;quot;&lt;br /&gt;
__email__ = &amp;quot;rob@spot.colorado.edu&amp;quot;&lt;br /&gt;
__status__ = &amp;quot;Production&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Source: Python Coding Guidelines - http://bayes.colorado.edu/PythonGuidelines.html&lt;br /&gt;
&lt;br /&gt;
These will show up in the help() like such:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Help on module test:&lt;br /&gt;
&lt;br /&gt;
NAME&lt;br /&gt;
    test&lt;br /&gt;
&lt;br /&gt;
FILE&lt;br /&gt;
    /home/kenneth/test.py&lt;br /&gt;
&lt;br /&gt;
FUNCTIONS&lt;br /&gt;
    test()&lt;br /&gt;
&lt;br /&gt;
DATA&lt;br /&gt;
    __author__ = &#039;test author&#039;&lt;br /&gt;
    __version__ = &#039;1.0&#039;&lt;br /&gt;
&lt;br /&gt;
VERSION&lt;br /&gt;
    1.0&lt;br /&gt;
&lt;br /&gt;
AUTHOR&lt;br /&gt;
    test author&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* Python: What is the common header format? - Stack Overflow - http://stackoverflow.com/questions/1523427/python-what-is-the-common-header-format&lt;br /&gt;
&lt;br /&gt;
=== Common Environment Variables ===&lt;br /&gt;
&lt;br /&gt;
 Command line and environment — Python v2.7.2 documentation - http://docs.python.org/using/cmdline.htm&lt;br /&gt;
&lt;br /&gt;
PYTHONUNBUFFERED&lt;br /&gt;
: If this is set to a non-empty string it is equivalent to specifying the -u option. [http://docs.python.org/using/cmdline.html#envvar-PYTHONUNBUFFERED]&lt;br /&gt;
: -u - Force stdin, stdout and stderr to be totally unbuffered. On systems where it matters, also put stdin, stdout and stderr in binary mode.&lt;br /&gt;
* See also stdout - Python output buffering - Stack Overflow - http://stackoverflow.com/questions/107705/python-output-buffering&lt;br /&gt;
 export PYTHONUNBUFFERED=1&lt;br /&gt;
 set PYTHONUNBUFFERED=1&lt;br /&gt;
&lt;br /&gt;
PYTHONVERBOSE&lt;br /&gt;
:If this is set to a non-empty string it is equivalent to specifying the -v option. If set to an integer, it is equivalent to specifying -v multiple times.&lt;br /&gt;
: -v - Print a message each time a module is initialized, showing the place (filename or built-in module) from which it is loaded.&lt;br /&gt;
 export PYTHONVERBOSE=1&lt;br /&gt;
 set PYTHONVERBOSE=1&lt;br /&gt;
&lt;br /&gt;
PYTHONPATH&lt;br /&gt;
: Augment the default search path for module files. The format is the same as the shell’s PATH: one or more directory pathnames separated by os.pathsep (e.g. colons on Unix or semicolons on Windows). Non-existent directories are silently ignored. [http://docs.python.org/using/cmdline.html#envvar-PYTHONPATH]&lt;br /&gt;
 export PYTHONPATH=/path1/:path2/&lt;br /&gt;
 set PYTHONPATH=C:\path1\;C:\path2\&lt;br /&gt;
&lt;br /&gt;
=== Queue ===&lt;br /&gt;
&lt;br /&gt;
Good for threading.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;The Queue module implements multi-producer, multi-consumer queues. It is especially useful in threaded programming when information must be exchanged safely between multiple threads. The Queue class in this module implements all the required locking semantics.&amp;quot; [http://docs.python.org/2/library/queue.html]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import Queue&lt;br /&gt;
&lt;br /&gt;
bucket = Queue.Queue()&lt;br /&gt;
bucket.put(&amp;quot;something&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
while True:&lt;br /&gt;
    try:&lt;br /&gt;
        item = bucket.get(block=False)&lt;br /&gt;
    except Queue.Empty:&lt;br /&gt;
        pass&lt;br /&gt;
    else:&lt;br /&gt;
        # do stuff with queue&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Important methods:&lt;br /&gt;
  Queue.qsize()&lt;br /&gt;
  Queue.empty()&lt;br /&gt;
  Queue.put(item[, block[, timeout]])&lt;br /&gt;
  Queue.get([block[, timeout]])&lt;br /&gt;
&lt;br /&gt;
-&lt;br /&gt;
&lt;br /&gt;
Example: http://docs.python.org/2/library/queue.html&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def worker():&lt;br /&gt;
    while True:&lt;br /&gt;
        item = q.get()&lt;br /&gt;
        do_work(item)&lt;br /&gt;
        q.task_done()&lt;br /&gt;
&lt;br /&gt;
q = Queue()&lt;br /&gt;
for i in range(num_worker_threads):&lt;br /&gt;
     t = Thread(target=worker)&lt;br /&gt;
     t.daemon = True&lt;br /&gt;
     t.start()&lt;br /&gt;
&lt;br /&gt;
for item in source():&lt;br /&gt;
    q.put(item)&lt;br /&gt;
&lt;br /&gt;
q.join()       # block until all tasks are done&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
-&lt;br /&gt;
&lt;br /&gt;
&amp;quot;The module implements three types of queue, which differ only in the order in which the entries are retrieved. In a FIFO queue, the first tasks added are the first retrieved. In a LIFO queue, the most recently added entry is the first retrieved (operating like a stack). With a priority queue, the entries are kept sorted (using the heapq module) and the lowest valued entry is retrieved first.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Queue Types:&lt;br /&gt;
  class Queue.Queue(maxsize=0)          # FIFO Queue&lt;br /&gt;
  class Queue.LifoQueue(maxsize=0)      # LIFO Queue&lt;br /&gt;
  class Queue.PriorityQueue(maxsize=0)  # Priority Queue&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* 8.10. Queue — A synchronized queue class — Python v2.7.5 documentation - http://docs.python.org/2/library/queue.html&lt;br /&gt;
&lt;br /&gt;
== Recipes ==&lt;br /&gt;
&lt;br /&gt;
=== Remove Numbers from String ===&lt;br /&gt;
&lt;br /&gt;
Using list comprehension: [http://stackoverflow.com/questions/12851791/removing-numbers-from-string]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
result = &#039;&#039;.join([i for i in s if not i.isdigit()])&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Using pattern matching:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; re.compile(r&#039;\D+&#039;).findall(&amp;quot;test 1234 test 1234&amp;quot;)&lt;br /&gt;
[&#039;test &#039;, &#039; test &#039;]&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; re.compile(r&amp;quot;\d&amp;quot;).sub(&amp;quot;&amp;quot;, &amp;quot;test 1234 test 1234&amp;quot;)&lt;br /&gt;
&#039;test  test &#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Retry Wrapper ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import functool&lt;br /&gt;
class SomethingRetry:&lt;br /&gt;
&lt;br /&gt;
    def retry_with_backoff(retries: int, base_delay: float, exceptions: tuple[type[Exception], ...] = (Exception,)) -&amp;gt; callable:&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Retries a function with exponential backoff, doubling on each attempt.&lt;br /&gt;
        Arguments:&lt;br /&gt;
            retries: Number of retry attempts.&lt;br /&gt;
            base_delay: Initial delay between retries in seconds.&lt;br /&gt;
            exceptions: Tuple of exceptions to catch and retry.&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
        def decorator(func):&lt;br /&gt;
            @functools.wraps(func)&lt;br /&gt;
            def wrapper(*args, **kwargs):&lt;br /&gt;
                for attempt in range(1, retries + 1):&lt;br /&gt;
                    try:&lt;br /&gt;
                        return func(*args, **kwargs)&lt;br /&gt;
                    except exceptions as e:&lt;br /&gt;
                        print(f&amp;quot;Warning: Attempt {attempt} failed with error: {e}&amp;quot;)&lt;br /&gt;
                        if attempt == retries:&lt;br /&gt;
                            print(&amp;quot;Error: All retry attempts failed.&amp;quot;)&lt;br /&gt;
                            raise&lt;br /&gt;
                        sleep_time = base_delay * (2 ** (attempt - 1))&lt;br /&gt;
                        print(f&amp;quot;Notice: Retrying in {sleep_time} seconds...&amp;quot;)&lt;br /&gt;
                        time.sleep(sleep_time)&lt;br /&gt;
            return wrapper&lt;br /&gt;
        return decorator&lt;br /&gt;
&lt;br /&gt;
    @retry_with_backoff(retries=6, base_delay=10, exceptions=(Exception,))&lt;br /&gt;
    def do_something(self, sample_param: str):&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Standard Libraries ==&lt;br /&gt;
&lt;br /&gt;
=== user input ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
line = raw_input()  # Python 2&lt;br /&gt;
# line = input()    # Python 2&lt;br /&gt;
line = input(&#039;What is your name: &#039;)&lt;br /&gt;
print(&amp;quot;: &amp;quot; + line.strip() + &amp;quot; :&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== sys - stdout stderr stdin ===&lt;br /&gt;
&lt;br /&gt;
STDOUT:&lt;br /&gt;
 import sys&lt;br /&gt;
 sys.stdout.write(&amp;quot;Hello &amp;quot;)  # does not write new line&lt;br /&gt;
 sys.stdout.write(&amp;quot;World\n&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
STDERR:&lt;br /&gt;
 import sys&lt;br /&gt;
 sys.stderr.write(&amp;quot;ERROR!\n&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
STDIN:&lt;br /&gt;
 import sys&lt;br /&gt;
 line = sys.stdin.readline()&lt;br /&gt;
&lt;br /&gt;
 line = input()   # use raw_input() in Python 2&lt;br /&gt;
 line = input(&#039;What is your name: &#039;)&lt;br /&gt;
 print(&amp;quot;: &amp;quot; + line.strip() + &amp;quot; :&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Read piped stdin line by line: [http://stackoverflow.com/questions/1450393/how-do-you-read-from-stdin-in-python]&lt;br /&gt;
 # cat /etc/passwd | ./readlines.py     # linux&lt;br /&gt;
 # type file.txt | python readlines.py  # windows&lt;br /&gt;
&lt;br /&gt;
 # fileinput.input() - returns fileinput object which is iterative&lt;br /&gt;
 import fileinput&lt;br /&gt;
 for line in fileinput.input():&lt;br /&gt;
     print(&amp;quot;: &amp;quot; + line + &amp;quot; :&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
 # sys.stdin.readlines() - returns list of strings&lt;br /&gt;
 import sys&lt;br /&gt;
 for line in sys.stdin.readlines():&lt;br /&gt;
     print(&amp;quot;: &amp;quot; + line + &amp;quot; :&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
 # sys.stdin - returns object which is iterative&lt;br /&gt;
 import sys&lt;br /&gt;
 for line in sys.stdin:&lt;br /&gt;
     print(&amp;quot;: &amp;quot; + line + &amp;quot; :&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
 # ugly while loop: [http://ubuntuforums.org/showthread.php?t=1092300]&lt;br /&gt;
 while True:&lt;br /&gt;
     try:&lt;br /&gt;
         s = raw_input(&amp;quot;Say something &amp;quot;)&lt;br /&gt;
     except EOFError:&lt;br /&gt;
         break&lt;br /&gt;
     print &amp;quot;: %s&amp;quot; % s&lt;br /&gt;
&lt;br /&gt;
Check if stdin has any waiting data: [http://stackoverflow.com/questions/3762881/how-do-i-check-if-stdin-has-some-data]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import sys&lt;br /&gt;
import select&lt;br /&gt;
&lt;br /&gt;
# if select.select([sys.stdin,],[],[],0.0)[0]:  # alternative old method&lt;br /&gt;
&lt;br /&gt;
if not sys.stdin.isatty():&lt;br /&gt;
    print &amp;quot;Have data!&amp;quot;&lt;br /&gt;
    print sys.stdin.readlines()&lt;br /&gt;
else:&lt;br /&gt;
    print &amp;quot;No data&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if len(sys.argv) &amp;gt; 1:&lt;br /&gt;
    message = &#039; &#039;.join(sys.argv[1:])&lt;br /&gt;
elif not sys.stdin.isatty():&lt;br /&gt;
    # read from pipe in&lt;br /&gt;
    message = sys.stdin.readline()&lt;br /&gt;
else:&lt;br /&gt;
    # read from user&lt;br /&gt;
    sys.stdout.write(&amp;quot;Message: &amp;quot;)&lt;br /&gt;
    message = raw_input().strip()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [http://docs.python.org/library/re.html Regular Expressions] ===&lt;br /&gt;
&lt;br /&gt;
Import:&lt;br /&gt;
 import re  # user regular expressions&lt;br /&gt;
&lt;br /&gt;
Match vs Search:&lt;br /&gt;
 re.match(&amp;quot;cde&amp;quot;, &amp;quot;abcdef&amp;quot;)  # no match (match searches beginning of string, first match)&lt;br /&gt;
 re.match(&amp;quot;abc&amp;quot;, &amp;quot;abcdef&amp;quot;)  # match (match searches beginning of string, first match)&lt;br /&gt;
 re.search(&amp;quot;cd&amp;quot;, &amp;quot;abcdef&amp;quot;)  # match (matches any location, first match)&lt;br /&gt;
&lt;br /&gt;
Both re.match() and re.search() return objects that are not intuitive to use.  You can check the object&#039;s group() method for what matched, but I prefer re.findall().&lt;br /&gt;
&lt;br /&gt;
Match:&lt;br /&gt;
 s = &#039;done&#039;&lt;br /&gt;
 if re.match(&#039;done|quit&#039;, s) != None  # True&lt;br /&gt;
&lt;br /&gt;
Search:&lt;br /&gt;
 s = &#039;done&#039;&lt;br /&gt;
 if re.search(&#039;do&#039;, s) != None  # True&lt;br /&gt;
&lt;br /&gt;
Replace:&lt;br /&gt;
 msg = &#039;jello world&#039;&lt;br /&gt;
 msg = re.sub(&#039;jello&#039;, &#039;hello&#039;, msg)&lt;br /&gt;
&lt;br /&gt;
For case intensive searches append 3rd parameter &amp;quot;re.I&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Find all:&lt;br /&gt;
 re.findall(&amp;quot;[a-z]+&amp;quot;, &amp;quot;aaa111bbb222&amp;quot;)       # [&#039;aaa&#039;, &#039;bbb&#039;]&lt;br /&gt;
 re.findall(&amp;quot;111([a-z]+)&amp;quot;, &amp;quot;aaa111bbb222&amp;quot;)  # [&#039;bbb&#039;]&lt;br /&gt;
 re.findall(&amp;quot;hello&amp;quot;, &amp;quot;HELLO&amp;quot;, re.I)         # [&#039;HELLO&#039;] - Case Insensitive&lt;br /&gt;
&lt;br /&gt;
Split:&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; re.split(&#039;[a-z]+&#039;,&#039;111aaa222bbb&#039;)&lt;br /&gt;
 [&#039;111&#039;, &#039;222&#039;, &#039;&#039;]&lt;br /&gt;
&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; re.split(&#039;([a-z]+)&#039;,&#039;111aaa222bbb&#039;)  # parenthesis cause return of all&lt;br /&gt;
 [&#039;111&#039;, &#039;aaa&#039;, &#039;222&#039;, &#039;bbb&#039;, &#039;&#039;]&lt;br /&gt;
&lt;br /&gt;
Replacement Substitution:&lt;br /&gt;
 # re.sub(pattern, repl, string[, count, flags])&lt;br /&gt;
 re.sub(r&#039;\\&#039;, r&#039;/&#039;, r&#039;\\data\files&#039;)&lt;br /&gt;
&lt;br /&gt;
Compiled regular express for repeated use: (performance)&lt;br /&gt;
 valid = re.compile(r&amp;quot;[0-9]+&amp;quot;)&lt;br /&gt;
 valid.match(&amp;quot;aaa111bbb&amp;quot;)               # not valid&lt;br /&gt;
 match = valid.search(&amp;quot;aaa111bbb222&amp;quot;)   # valid&lt;br /&gt;
 print(match.group())                   # what matched: &#039;111&#039;&lt;br /&gt;
&lt;br /&gt;
=== Date and Time ===&lt;br /&gt;
&lt;br /&gt;
Sleep in seconds:&lt;br /&gt;
 import time&lt;br /&gt;
 time.sleep(seconds)&lt;br /&gt;
&lt;br /&gt;
Use the following functions to convert between time representations:&lt;br /&gt;
&amp;lt;table border=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;From&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;To&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Use&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;seconds since the epoch&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;struct_time in UTC&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;gmtime()&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;seconds since the epoch&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;struct_time in local time&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;localtime()&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;struct_time in UTC&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;seconds since the epoch&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;calendar.timegm()&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;struct_time in local time&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;seconds since the epoch&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;mktime()&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Date formats:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; time.strftime(&amp;quot;%Y-%m-%d %H:%M:%S&amp;quot;, time.localtime())&lt;br /&gt;
&#039;2014-04-04 12:22:43&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; time.time()&lt;br /&gt;
1396635763.0581281&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; datetime.datetime.now()&lt;br /&gt;
datetime.datetime(2014, 4, 4, 12, 22, 43, 58456)&lt;br /&gt;
# datetime(year, month, day, hour, minute, second, microsecond)&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; time.localtime()&lt;br /&gt;
time.struct_time(tm_year=2014, tm_mon=4, tm_mday=4, tm_hour=12, tm_min=22, tm_sec=43, tm_wday=4, tm_yday=94, tm_isdst=1)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Current epoch time:&lt;br /&gt;
 int(time.time())&lt;br /&gt;
&lt;br /&gt;
Time zone offset:&lt;br /&gt;
 standard_tz_offset = - time.timezone / 3600  # 7&lt;br /&gt;
 daylight_tz_offset = - time.altzone / 3600  # 6&lt;br /&gt;
&lt;br /&gt;
Is daylight saving time: [http://stackoverflow.com/questions/2881025/python-daylight-savings-time]&lt;br /&gt;
 import time&lt;br /&gt;
 time.localtime()&lt;br /&gt;
 _.tm_isdst  # 0 or 1&lt;br /&gt;
&lt;br /&gt;
 mst_epoch_time = time.time()  # server in MST/MDT&lt;br /&gt;
 if time.localtime().tm_isdst:  # are we in daylight saving time?&lt;br /&gt;
   utc_epoch_time = mst_epoch_time + time.altzone&lt;br /&gt;
 else:&lt;br /&gt;
   utc_epoch_time = mst_epoch_time + time.timezone&lt;br /&gt;
&lt;br /&gt;
Format current time: [http://docs.python.org/2/library/time.html#time.strftime]&lt;br /&gt;
 time.strftime(&#039;%d%b%y&#039;)  # &#039;12May11&#039;&lt;br /&gt;
 time.strftime(&#039;%Y.%m.%d %H:%M:%S&#039;)  # &#039;2013.08.09 14:01:28&#039;&lt;br /&gt;
&lt;br /&gt;
Time conversions:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# epoch to str&lt;br /&gt;
epoch_time = time.time()    # 1375992088.7867229&lt;br /&gt;
dt = datetime.datetime.fromtimestamp( epoch_time )    # datetime.datetime(2013, 8, 8, 14, 1, 28, 786723)&lt;br /&gt;
date_str = dt.strftime(&amp;quot;%Y-%m-%d %H:%M:%S&amp;quot;)    # &#039;2013-08-08 14:01:28&#039;&lt;br /&gt;
tz_offset = - time.altzone / 3600&lt;br /&gt;
if tz_offset &amp;lt; 0:&lt;br /&gt;
  tz_offset_str = &amp;quot;-%02d00&amp;quot; % abs(tz_offset)&lt;br /&gt;
else:&lt;br /&gt;
  tz_offset_str = &amp;quot;+%02d00&amp;quot; % abs(tz_offset)&lt;br /&gt;
print date_str + &amp;quot; &amp;quot; + tz_offset_str  # &#039;2013-08-08 14:01:28 -0600&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# UTC epoch to str&lt;br /&gt;
gm_epoch_time = calendar.timegm(time.gmtime())    # 1375992114&lt;br /&gt;
dt = datetime.utcfromtimestamp( gm_epoch_time )    # datetime.datetime(2013, 8, 8, 20, 1, 54)&lt;br /&gt;
dt.strftime(&amp;quot;%Y-%m-%d %H:%M:%S +0000&amp;quot;)    # &#039;2013-08-08 20:01:54 +0000&#039;&lt;br /&gt;
dt.strftime(&amp;quot;%Y-%m-%dT%H:%M:%SZ&amp;quot;)    # &#039;2013-08-08 20:01:54 +0000&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Local time str to epoch&lt;br /&gt;
iso_string=&#039;2013-08-08T14:01:28&#039;&lt;br /&gt;
epoch_time = time.mktime( time.strptime( iso_string, &#039;%Y-%m-%dT%H:%M:%S&#039; ) )    # 1375992088.0&lt;br /&gt;
&lt;br /&gt;
iso_string=&#039;2013-08-08T14:01:28 MDT&#039;&lt;br /&gt;
epoch_time = time.mktime( time.strptime( iso_string, &#039;%Y-%m-%dT%H:%M:%S %Z&#039; ) )    # 1375992088.0&lt;br /&gt;
&lt;br /&gt;
# not sure how to specify numerical time zone and pull it in!&lt;br /&gt;
&lt;br /&gt;
# UTC (Zulu) str to epoch, and back again&lt;br /&gt;
iso_string = &#039;2013-08-08T20:01:54Z&#039;&lt;br /&gt;
epoch_time = calendar.timegm( time.strptime( iso_string.replace(&#039;Z&#039;, &#039;GMT&#039;), &#039;%Y-%m-%dT%H:%M:%S%Z&#039; ) )&lt;br /&gt;
print epoch_time    # 1375992114&lt;br /&gt;
print &amp;quot;%sZ&amp;quot; % datetime.utcfromtimestamp(timestamp).isoformat()  # 2013-08-08T20:01:54Z&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Convert epoch from Local to UTC&lt;br /&gt;
epoch_time = 1375992114&lt;br /&gt;
tz_offset = - time.altzone / 3600&lt;br /&gt;
gm_epoch_time = epoch_time - tz_offset * 3600    # 1376013714&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Convert epoch from UTC to Local&lt;br /&gt;
gm_epoch_time = 1376013714&lt;br /&gt;
tz_offset = - time.altzone / 3600&lt;br /&gt;
epoch_time = gm_epoch_time + tz_offset * 3600    # 1375992114&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
struct_time:&lt;br /&gt;
 time.localtime()  # local zime zone&lt;br /&gt;
 time.gmtime()     # UTC time&lt;br /&gt;
&lt;br /&gt;
 today = time.localtime()&lt;br /&gt;
 today_year = today.tm_year&lt;br /&gt;
 today_month = today.tm_mon&lt;br /&gt;
 today_day = today.tm_mday&lt;br /&gt;
&lt;br /&gt;
 time.strftime(&amp;quot;%a, %d %b %Y %H:%M:%S +0000&amp;quot;, time.gmtime())&lt;br /&gt;
&lt;br /&gt;
Zulu time to epoch time: [http://stackoverflow.com/questions/127803/how-to-parse-iso-formatted-date-in-python]&lt;br /&gt;
 s = &#039;2008-09-03T20:56:35.450686Z&#039;&lt;br /&gt;
 event_time_struct = time.strptime(s.split(&#039;.&#039;)[0]+ &amp;quot;UTC&amp;quot;, &amp;quot;%Y-%m-%dT%H:%M:%S%Z&amp;quot;)&lt;br /&gt;
 epoch_time = calendar.timegm(event_time_struct)&lt;br /&gt;
&lt;br /&gt;
Parse string to time.struct_time (like gmtime()): [http://docs.python.org/2/library/time.html#time.strptime]&lt;br /&gt;
 time.strptime(time.ctime())  # current time - default format is ctime format: &amp;quot;%a %b %d %H:%M:%S %Y&amp;quot;&lt;br /&gt;
 time.strptime(time.ctime(time.time()))  # default format is ctime format: &amp;quot;%a %b %d %H:%M:%S %Y&amp;quot;&lt;br /&gt;
 time.strptime(&amp;quot;30 Nov 00&amp;quot;, &amp;quot;%d %b %y&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Build from ticks: [http://www.tutorialspoint.com/python/python_date_time.htm]&lt;br /&gt;
 localtime = time.localtime( time.time() )  # build time.struct_time from ticks&lt;br /&gt;
 print time.asctime( localtime )  # Tue Jan 13 10:17:09 2009&lt;br /&gt;
&lt;br /&gt;
 dt = datetime.datetime.fromtimestamp( time.time() )  # build datetime.datetime struct from ticks&lt;br /&gt;
 dt.strftime(&amp;quot;%Y-%m-%d  %H:%M:%S&amp;quot;)  # &#039;2013-07-31  23:07:48&#039;&lt;br /&gt;
 time.strptime( time.time(), &amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from datetime import date&lt;br /&gt;
now = date.today()    # now = datetime.date(2003, 12,2)&lt;br /&gt;
now.strftime(&amp;quot;%m-%d-%y&amp;quot;)   # &#039;12-02-03&#039;&lt;br /&gt;
# dates support calendar arthimetic&lt;br /&gt;
birthday = date(1964, 7, 31)&lt;br /&gt;
age = now - birthday&lt;br /&gt;
age.days  # 14368&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 ts = (datetime.datetime.now().strftime(&amp;quot;%Y%m%d%H%M&amp;quot;))         # 201105191118&lt;br /&gt;
 tstxt = (datetime.datetime.now().strftime(&amp;quot;%m-%d-%Y %H:%M&amp;quot;))  # 05-19-2011 11:18&lt;br /&gt;
&lt;br /&gt;
Seconds since epoch:&lt;br /&gt;
 int(time.time())    # 1305842304&lt;br /&gt;
&lt;br /&gt;
Zulu and back again: ([http://aboutsimon.com/2013/06/05/datetime-hell-time-zone-aware-to-unix-timestamp/ Datetime hell])&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import time&lt;br /&gt;
from calendar import timegm&lt;br /&gt;
from datetime import datetime&lt;br /&gt;
 &lt;br /&gt;
if __name__ == &#039;__main__&#039;:&lt;br /&gt;
    iso_string = &#039;2013-06-05T15:19:10Z&#039;&lt;br /&gt;
 &lt;br /&gt;
    timestamp = timegm(&lt;br /&gt;
        time.strptime(&lt;br /&gt;
            iso_string.replace(&#039;Z&#039;, &#039;GMT&#039;),&lt;br /&gt;
            &#039;%Y-%m-%dT%H:%M:%S%Z&#039;&lt;br /&gt;
        )&lt;br /&gt;
    )&lt;br /&gt;
 &lt;br /&gt;
    print iso_string&lt;br /&gt;
    print timestamp&lt;br /&gt;
    print &#039;-&amp;gt; %sZ&#039; % datetime.utcfromtimestamp(timestamp).isoformat()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
http://wiki.python.org/moin/TimeTransitionsImage?action=AttachFile&amp;amp;do=get&amp;amp;target=v1.png  [http://wiki.python.org/moin/WorkingWithTime]&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* WorkingWithTime - PythonInfo Wiki - http://wiki.python.org/moin/WorkingWithTime&lt;br /&gt;
* Datetime hell. Time zone aware to UNIX timestamp. | About me and the things I do - http://aboutsimon.com/2013/06/05/datetime-hell-time-zone-aware-to-unix-timestamp/&lt;br /&gt;
* WorkingWithTime - Python Wiki - http://wiki.python.org/moin/WorkingWithTime&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
Something I cooked up...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def utc_time(self, years_offset=60):&lt;br /&gt;
        mst_epoch_time = time.time()  # server is in MST&lt;br /&gt;
        if time.localtime().tm_isdst: # are we daylight saving time?&lt;br /&gt;
            utc_epoch_time = mst_epoch_time + time.altzone&lt;br /&gt;
        else:&lt;br /&gt;
            utc_epoch_time = mst_epoch_time + time.timezone&lt;br /&gt;
        return utc_epoch_time&lt;br /&gt;
&lt;br /&gt;
    def tz_time(self, tz_offset, daylight_adjust=True):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot; return the future time based on timezone offset&lt;br /&gt;
            @tz_offset is timezone offset, eg -7 for MST&lt;br /&gt;
            @daylight_adjust is flag to auto adjust for daylight time&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        if daylight_adjust:&lt;br /&gt;
            if time.localtime().tm_isdst: # are we daylight saving time?&lt;br /&gt;
                _tz_offset = tz_offset - 1&lt;br /&gt;
            else:&lt;br /&gt;
                _tz_offset = tz_offset&lt;br /&gt;
            _utc_epoch_time = self.utc_time()&lt;br /&gt;
            _adj_time = _utc_epoch_time + _tz_offset * 60 * 60&lt;br /&gt;
            return _adj_time&lt;br /&gt;
&lt;br /&gt;
    def future_time(self, tz_offset=-7, daylight_adjust=True, years_offset=60):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot; Calculate some future year &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        _tz_time = self.tz_time(tz_offset)&lt;br /&gt;
        future_utc_epoch_time = _tz_time + years_offset * 365 * 24 * 60 * 60&lt;br /&gt;
        # account for leap years&lt;br /&gt;
        cur_year = datetime.datetime.now().year&lt;br /&gt;
        cur_year_leap = cur_year / 4&lt;br /&gt;
        future_year = cur_year + years_offset&lt;br /&gt;
        future_year_leap = future_year / 4&lt;br /&gt;
        leap_days = future_year_leap - cur_year_leap&lt;br /&gt;
        future_utc_epoch_time += leap_days * 24 * 60 * 60&lt;br /&gt;
        return future_utc_epoch_time&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Math ===&lt;br /&gt;
&lt;br /&gt;
Math Functions:&lt;br /&gt;
 import math&lt;br /&gt;
 math.ceil(x)&lt;br /&gt;
 math.floor(x)&lt;br /&gt;
 math.trunc(x)&lt;br /&gt;
 math.pow(x,y)&lt;br /&gt;
&lt;br /&gt;
 abs(x)  # built in&lt;br /&gt;
&lt;br /&gt;
=== Random ===&lt;br /&gt;
&lt;br /&gt;
 import random&lt;br /&gt;
 random.choice([&#039;a&#039;, &#039;b&#039;, &#039;c&#039;])&lt;br /&gt;
 random.sample(range(100), 10)&lt;br /&gt;
 random.random()  # random float 0 &amp;lt; x &amp;lt; 1&lt;br /&gt;
 random.randrange(3)     # integer in [0, 1, 2]&lt;br /&gt;
 random.randrange(1, 3)  # integer in [1, 2]&lt;br /&gt;
 random.randint(1, 3)    # integer in [1, 2, 3]&lt;br /&gt;
&lt;br /&gt;
=== Operating System Operations ===&lt;br /&gt;
&lt;br /&gt;
Import OS Library:&lt;br /&gt;
 import os&lt;br /&gt;
&lt;br /&gt;
Common Functions:&lt;br /&gt;
 # directory functions&lt;br /&gt;
 os.getcwd()       # get current directory&lt;br /&gt;
 os.listdir(p)     # get list of directory contents&lt;br /&gt;
 os.chdir(p)       # change directory&lt;br /&gt;
 os.mkdir(p)       # make directory&lt;br /&gt;
 os.makedirs(p)    # make directory and all intermediate&lt;br /&gt;
 os.rmdir(p)       # remove empty directory, see shutil.rmtree()&lt;br /&gt;
 os.removedirs(p)  # remove empty directories, see shutil.rmtree()&lt;br /&gt;
 os.path.exists(p) # does file/directory exist?&lt;br /&gt;
 os.path.isdir(p)  # does directory exist&lt;br /&gt;
 os.path.join(folder1, folder2, file, etc)  # portable path join&lt;br /&gt;
&lt;br /&gt;
 # file functions&lt;br /&gt;
 os.remove(p)      # remove file&lt;br /&gt;
 os.unlink(p)      # same as os.remove()&lt;br /&gt;
 os.path.exists(p) # does file/directory exist?&lt;br /&gt;
 os.path.isfile(p) # does file exist&lt;br /&gt;
 os.stat(fname)    # get file stats&lt;br /&gt;
 os.stat(fname).st_size  # file size&lt;br /&gt;
 os.link(src, dst) # create hard link&lt;br /&gt;
 os.readlink(p)    # read symbolic link&lt;br /&gt;
 os.rename(old, new) # rename/move file or directory&lt;br /&gt;
 os.tempnam(p)     # temporary unique name for target path&lt;br /&gt;
 os.tmpfile()      # create temporary file&lt;br /&gt;
 os.tmpnam()       # temporary file name&lt;br /&gt;
 os.path.getsize(filename)  # get file size&lt;br /&gt;
&lt;br /&gt;
 # system functions&lt;br /&gt;
 os.fork()         # fork process&lt;br /&gt;
 os.getpid()       # get process id&lt;br /&gt;
 os.getppid()      # get parent&#039;s process id&lt;br /&gt;
 os.kill(pid, sig) # kill a process&lt;br /&gt;
 os.getlogin()     # get user&#039;s login name&lt;br /&gt;
&lt;br /&gt;
 # execution&lt;br /&gt;
 os.system(cmd)    # output to stdout, return exit_status&lt;br /&gt;
 os.popen(cmd)     # returns a pipe to command&lt;br /&gt;
&lt;br /&gt;
Note: to get path to script:&lt;br /&gt;
 sys.path[0]&lt;br /&gt;
&lt;br /&gt;
Get directory and file names:&lt;br /&gt;
 os.path.dirname(path)  # &#039;/root/test.txt&#039; -&amp;gt; &#039;/root&#039;&lt;br /&gt;
 os.path.basename(path) # &#039;/root/test.txt&#039; -&amp;gt; &#039;test.txt&#039;&lt;br /&gt;
 os.path.splitext(path) # &#039;/root/test.test.txt&#039; -&amp;gt; (&#039;/root/test.test&#039;, &#039;.txt&#039;) - extract extention&lt;br /&gt;
 filename.split(&amp;quot;.&amp;quot;)[-1] # &#039;/root/test.test.txt&#039; -&amp;gt; &#039;txt&#039; - extract extention&lt;br /&gt;
&lt;br /&gt;
Normalize path, eliminating double slashes, etc.&lt;br /&gt;
 os.path.normpath(path)  # &#039;/root/..&#039; -&amp;gt; &#039;/&#039; or &#039;test/..&#039; -&amp;gt; &#039;.&#039;&lt;br /&gt;
 os.path.abspath(path)   # &#039;/root/..&#039; -&amp;gt; &#039;/&#039; or &#039;test/..&#039; -&amp;gt; &#039;/root/test&#039;&lt;br /&gt;
&lt;br /&gt;
List dir: (returns list)&lt;br /&gt;
 os.listdir( os.getcwd() )&lt;br /&gt;
&lt;br /&gt;
List of files:&lt;br /&gt;
 [p for p in os.listdir(os.getcwd())&lt;br /&gt;
    if os.path.isfile(p)]&lt;br /&gt;
&lt;br /&gt;
List of folders:&lt;br /&gt;
 [p for p in os.listdir(os.getcwd())&lt;br /&gt;
    if os.path.isdir(p)]&lt;br /&gt;
&lt;br /&gt;
Build path for local OS: (using appropriate slash)&lt;br /&gt;
 pathstr = os.path.join(&amp;quot;folder&amp;quot;, &amp;quot;folder&amp;quot;, &amp;quot;file_or_folder&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
File and directory management with shutil&lt;br /&gt;
 import shutil&lt;br /&gt;
 shutil.copyfile(&#039;file1&#039;, &#039;file2&#039;)&lt;br /&gt;
 shutil.move(&#039;file1&#039;, &#039;folder2/file1&#039;)&lt;br /&gt;
&lt;br /&gt;
File Wildcards:&lt;br /&gt;
 import glob&lt;br /&gt;
 glob.glob(&#039;*.py&#039;)  # return list of files&lt;br /&gt;
&lt;br /&gt;
Walk directory tree: [http://stackoverflow.com/questions/120656/directory-listing-in-python]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import os&lt;br /&gt;
for dirname, dirnames, filenames in os.walk(&#039;.&#039;):&lt;br /&gt;
    for subdirname in dirnames:&lt;br /&gt;
        print os.path.join(dirname, subdirname)&lt;br /&gt;
    for filename in filenames:&lt;br /&gt;
        print os.path.join(dirname, filename)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ugly &#039;deltree&#039; (by kenneth)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import os&lt;br /&gt;
def deltree(path):&lt;br /&gt;
    files = os.listdir(path)&lt;br /&gt;
    for file in files:&lt;br /&gt;
        file_path = os.path.join(path, file)&lt;br /&gt;
        if os.path.isdir(file_path):&lt;br /&gt;
            deltree(file_path)&lt;br /&gt;
            os.rmdir(file_path)&lt;br /&gt;
        else:&lt;br /&gt;
            os.remove(file_path)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cleaner &#039;deltree&#039; (by Kep)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import shutil&lt;br /&gt;
# Blow away (if needed), and reclone to proper version&lt;br /&gt;
if os.path.isdir(&amp;quot;xxx&amp;quot;):&lt;br /&gt;
    shutil.rmtree(&amp;quot;xxx&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== System Platform ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import platform&lt;br /&gt;
&lt;br /&gt;
if platform.system() == &amp;quot;Linux&amp;quot;:&lt;br /&gt;
 # ...&lt;br /&gt;
if platform.system() == &amp;quot;Windows&amp;quot;:&lt;br /&gt;
 # ...&lt;br /&gt;
else:&lt;br /&gt;
 # ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Temp Files ===&lt;br /&gt;
&lt;br /&gt;
 import tempfile&lt;br /&gt;
 filename = tempfile.mktemp()&lt;br /&gt;
 f = open(filename, &#039;w&#039;)&lt;br /&gt;
 ...&lt;br /&gt;
 f.close()&lt;br /&gt;
 &lt;br /&gt;
 import os&lt;br /&gt;
 os.remove(filename)  # delete temp file&lt;br /&gt;
&lt;br /&gt;
=== Pickling ===&lt;br /&gt;
&lt;br /&gt;
Pickling (serializing, making objects persistent):&lt;br /&gt;
 import pickle&lt;br /&gt;
 grades = {&#039;bob&#039; : [4, 5, 6],&lt;br /&gt;
           &#039;sue&#039; : [3, None, 7, 7]}&lt;br /&gt;
 outfile = open(fname, &#039;wb&#039;)&lt;br /&gt;
 pickle.dump(grades, outfile)&lt;br /&gt;
&lt;br /&gt;
 infile = open(fname, &#039;rb&#039;)&lt;br /&gt;
 grades = pickle.load(infile)&lt;br /&gt;
&lt;br /&gt;
=== [http://docs.python.org/library/logging.html Logging] ===&lt;br /&gt;
&lt;br /&gt;
* logging — Logging facility for Python — Python 3 documentation - https://docs.python.org/3/library/logging.html&lt;br /&gt;
* Logging HOWTO — Python Dev Version documentation - http://docs.python.org/dev/howto/logging.html&lt;br /&gt;
* Logging Cookbook — Python Dev Version documentation - http://docs.python.org/dev/howto/logging-cookbook.html&lt;br /&gt;
&lt;br /&gt;
Setup logger:&lt;br /&gt;
 import logging&lt;br /&gt;
 logging.basicConfig(level=logging.DEBUG,format=&#039;[%(asctime)s.%(msecs)03d] %(levelname)s %(filename)s(line:%(lineno)d): %(message)s&#039;)&lt;br /&gt;
&lt;br /&gt;
Log Levels:&lt;br /&gt;
 import logging&lt;br /&gt;
 msg = &amp;quot;i broke&amp;quot;&lt;br /&gt;
 logging.debug(msg)&lt;br /&gt;
 logging.info(msg)&lt;br /&gt;
 logging.warning(msg)   # WARNING:root:i broke&lt;br /&gt;
 logging.error(msg)     # ERROR:root:i broke&lt;br /&gt;
 logging.critical(msg)  # CRITICAL:root:i broke&lt;br /&gt;
&lt;br /&gt;
 log.setLevel(level)  # debug, info, warn/warning, error, critical&lt;br /&gt;
 log.setLevel(logging.DEBUG)&lt;br /&gt;
&lt;br /&gt;
A good convention to use when naming loggers is to use a module-level logger, in each module which uses logging, named as follows: [http://docs.python.org/dev/howto/logging.html]&lt;br /&gt;
 logger = logging.getLogger(__name__)&lt;br /&gt;
&lt;br /&gt;
Simple example: [http://stackoverflow.com/questions/345991/python-no-handlers-could-be-found-for-logger-opengl-error]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
log_format=&#039;%(asctime)s | %(levelname)s | %(message)s&#039;&lt;br /&gt;
log_date_format=&#039;%Y-%m-%d %H:%M:%S&#039;&lt;br /&gt;
logging.basicConfig(format=log_format, datefmt=log_date_format)&lt;br /&gt;
log = logging.getLogger(__name__)&lt;br /&gt;
log.setLevel(logging.INFO)&lt;br /&gt;
&lt;br /&gt;
log.info(&#039;hi&#039;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Formatter function:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def makeFormatter(format_str=&amp;quot;&amp;quot;, date_format=&amp;quot;%Y-%m-%d %H:%M:%S&amp;quot;):&lt;br /&gt;
    if not format_str:&lt;br /&gt;
        format_str = &amp;quot;%(asctime)s | %(levelname)s | %(filename)s:%(lineno)d:%(funcName)s | %(message)s&amp;quot;&lt;br /&gt;
    return logging.Formatter(fmt=format_str, datefmt=date_format)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Medium example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Create logger&lt;br /&gt;
log_format=&#039;%(asctime)s | %(levelname)s | %(message)s&#039;&lt;br /&gt;
log_date_format=&#039;%Y-%m-%d %H:%M:%S&#039;&lt;br /&gt;
log_formatter = logging.Formatter(fmt=log_format, datefmt=log_date_format)&lt;br /&gt;
log = logging.getLogger(__name__)&lt;br /&gt;
log.setLevel(logging.DEBUG)&lt;br /&gt;
&lt;br /&gt;
# Log to console&lt;br /&gt;
ch = logging.StreamHandler()&lt;br /&gt;
ch.setLevel(logging.INFO)&lt;br /&gt;
ch.setFormatter(log_formatter)&lt;br /&gt;
log.addHandler(ch)&lt;br /&gt;
&lt;br /&gt;
# Log to file&lt;br /&gt;
fh = logging.FileHandler(&#039;my_logger.log&#039;)&lt;br /&gt;
fh.setLevel(logging.DEBUG)&lt;br /&gt;
fh.setFormatter(log_formatter)&lt;br /&gt;
log.addHandler(fh)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Log all loggers to file - attach to root logger&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import logging&lt;br /&gt;
&lt;br /&gt;
logger = logging.getLogger(__name__)&lt;br /&gt;
&lt;br /&gt;
# Configure Logger&lt;br /&gt;
log_format=&#039;%(asctime)s | %(name)s | %(levelname)s | %(message)s&#039;&lt;br /&gt;
log_date_format=&#039;%Y-%m-%d %H:%M:%S&#039;&lt;br /&gt;
log_formatter = logging.Formatter(fmt=log_format, datefmt=log_date_format)&lt;br /&gt;
logging.basicConfig(level=logging.DEBUG, format=log_format, datefmt=log_date_format)&lt;br /&gt;
&lt;br /&gt;
# Setup Log to File handler, and attach to root logger&lt;br /&gt;
root_logger = logging.getLogger()  # Calling getLogger() without a name returns the root logger&lt;br /&gt;
fh = logging.FileHandler(&#039;logger.txt&#039;)&lt;br /&gt;
fh.setLevel(logging.DEBUG)&lt;br /&gt;
fh.setFormatter(log_formatter)&lt;br /&gt;
root_logger.addHandler(fh)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Application Setup (not basic log configuration carries across imported modules):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import logging&lt;br /&gt;
def main():&lt;br /&gt;
    logging.basicConfig(filename=&#039;myapp.log&#039;, level=logging.INFO)&lt;br /&gt;
    logging.info(&#039;Started&#039;)&lt;br /&gt;
    ...&lt;br /&gt;
    logging.info(&#039;Finished&#039;)&lt;br /&gt;
&lt;br /&gt;
if __name__ == &#039;__main__&#039;:&lt;br /&gt;
    main()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Log multiple lines:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
for line in output.splitlines():&lt;br /&gt;
    log.debug(line)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Set log level:  (warning is default)&lt;br /&gt;
 logging.basicConfig(level=logging.DEBUG)&lt;br /&gt;
&lt;br /&gt;
Set log level from string value: [http://docs.python.org/dev/howto/logging.html]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# assuming loglevel is bound to the string value obtained from the&lt;br /&gt;
# command line argument. Convert to upper case to allow the user to&lt;br /&gt;
# specify --log=DEBUG or --log=debug&lt;br /&gt;
numeric_level = getattr(logging, loglevel.upper(), None)&lt;br /&gt;
if not isinstance(numeric_level, int):&lt;br /&gt;
    raise ValueError(&#039;Invalid log level: %s&#039; % loglevel)&lt;br /&gt;
logging.basicConfig(level=numeric_level, ...)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Log to file:&lt;br /&gt;
 logging.basicConfig(filename=&#039;example.log&#039;,level=logging.DEBUG)&lt;br /&gt;
 logging.basicConfig(filename=&#039;example.log&#039;, filemode=&#039;w&#039;, level=logging.DEBUG)  # do not append&lt;br /&gt;
&lt;br /&gt;
Format output: (once set, can&#039;t be changed?)&lt;br /&gt;
 # WARNING:MESSAGE&lt;br /&gt;
 logging.basicConfig(format=&#039;%(levelname)s:%(message)s&#039;, level=logging.DEBUG)&lt;br /&gt;
&lt;br /&gt;
 # 05/23/2011 12:50:02 PM MESSAGE&lt;br /&gt;
 logging.basicConfig(format=&#039;%(asctime)s %(message)s&#039;, datefmt=&#039;%m/%d/%Y %I:%M:%S %p&#039;)&lt;br /&gt;
&lt;br /&gt;
 # 05/23/2011 12:55:28 PM : WARNING : MESSAGE&lt;br /&gt;
 logging.basicConfig(format=&#039;%(asctime)s : %(levelname)s : %(message)s&#039;, datefmt=&#039;%m/%d/%Y %I:%M:%S %p&#039;)&lt;br /&gt;
&lt;br /&gt;
 # 2011-05-23 13:05:30 : WARNING : MESSAGE&lt;br /&gt;
 logging.basicConfig(format=&#039;%(asctime)s : %(levelname)s : %(message)s&#039;, datefmt=&#039;%Y-%m-%d %H:%M:%S&#039;)&lt;br /&gt;
&lt;br /&gt;
 # 2011-05-23 13:05:30 | WARNING | FILE:FUNC | MESSAGE&lt;br /&gt;
 logging.basicConfig(format=&#039;%(asctime)s | %(levelname)s | %(filename)s:%(funcName)s | %(message)s&#039;, datefmt=&#039;%Y-%m-%d %H:%M:%S&#039;)&lt;br /&gt;
&lt;br /&gt;
Log record attributes - http://docs.python.org/library/logging.html#logrecord-attributes&lt;br /&gt;
&lt;br /&gt;
Format Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FORMAT = &#039;%(asctime)-15s %(clientip)s %(user)-8s %(message)s&#039;  # doesn&#039;t work!&lt;br /&gt;
logging.basicConfig(format=FORMAT)&lt;br /&gt;
d = { &#039;clientip&#039; : &#039;192.168.0.1&#039;, &#039;user&#039; : &#039;fbloggs&#039; }&lt;br /&gt;
logger = logging.getLogger(&#039;tcpserver&#039;)&lt;br /&gt;
logger.warning(&#039;Protocol problem: %s&#039;, &#039;connection reset&#039;, extra=d)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import logging&lt;br /&gt;
&lt;br /&gt;
# create logger with &#039;spam_application&#039;&lt;br /&gt;
logger = logging.getLogger(&#039;spam_application&#039;)&lt;br /&gt;
logger.setLevel(logging.DEBUG)&lt;br /&gt;
&lt;br /&gt;
# create file handler which logs even debug messages&lt;br /&gt;
fh = logging.FileHandler(&#039;spam.log&#039;)&lt;br /&gt;
fh.setLevel(logging.DEBUG)&lt;br /&gt;
&lt;br /&gt;
# create console handler with a higher log level&lt;br /&gt;
ch = logging.StreamHandler()&lt;br /&gt;
ch.setLevel(logging.ERROR)&lt;br /&gt;
&lt;br /&gt;
# create formatter and add it to the handlers&lt;br /&gt;
formatter = logging.Formatter(&#039;%(asctime)s - %(name)s - %(levelname)s - %(message)s&#039;)&lt;br /&gt;
fh.setFormatter(formatter)&lt;br /&gt;
ch.setFormatter(formatter)&lt;br /&gt;
&lt;br /&gt;
# add the handlers to the logger&lt;br /&gt;
logger.addHandler(fh)&lt;br /&gt;
logger.addHandler(ch)&lt;br /&gt;
&lt;br /&gt;
logger.info(&#039;Message to loggers and handlers&#039;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Templating ===&lt;br /&gt;
&lt;br /&gt;
 from string import Template&lt;br /&gt;
 t = Template(&#039;${name}&#039;s fav dish is $food&#039;)&lt;br /&gt;
 t.substitute(name = &#039;ken&#039;, food = &#039;beans&#039;) # throws exception if missing one, but can have more&lt;br /&gt;
 t.safe_substitute(name = &#039;ken&#039;)  # will fill in what it can&lt;br /&gt;
&lt;br /&gt;
Change delimiter:&lt;br /&gt;
 class MYT(Template):&lt;br /&gt;
   delimiter = &#039;%&#039;&lt;br /&gt;
 minput = input(&amp;quot;File name format (%d - date, %s - size): &amp;quot;)&lt;br /&gt;
 myt = MYT(minput)&lt;br /&gt;
 myt.substitute(%d=date, %s=size)&lt;br /&gt;
&lt;br /&gt;
=== [http://docs.python.org/library/threading.html Threading] ===&lt;br /&gt;
&lt;br /&gt;
Basic thread: [http://softwareramblings.com/2008/06/running-functions-as-threads-in-python.html]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import thread&lt;br /&gt;
 &lt;br /&gt;
def someFunc():&lt;br /&gt;
    print &amp;quot;someFunc was called&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
thread.start_new_thread(someFunc, ())&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
More complete basic thread:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import thread&lt;br /&gt;
import threading&lt;br /&gt;
import time&lt;br /&gt;
&lt;br /&gt;
def run_thread (threadname, sleeptime):&lt;br /&gt;
 print &amp;quot;Thread start: &amp;quot; + threadname&lt;br /&gt;
 time.sleep(sleeptime)&lt;br /&gt;
 print &amp;quot;Thread end: &amp;quot; + threadname&lt;br /&gt;
 thread.interrupt_main()   # throw keyboard interrupt to kill main program&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
 thread.start_new_thread(run_thread, (&amp;quot;Thread1&amp;quot;, 3))&lt;br /&gt;
 try:&lt;br /&gt;
     while 1:&lt;br /&gt;
         pass&lt;br /&gt;
 except:&lt;br /&gt;
     print &amp;quot;Thread1 exited....&amp;quot; &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Can use a global counter instead of exception to track number of threads:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import thread&lt;br /&gt;
import threading&lt;br /&gt;
import time&lt;br /&gt;
&lt;br /&gt;
threadcount = 3&lt;br /&gt;
&lt;br /&gt;
def run_thread (threadname, sleeptime):&lt;br /&gt;
  global threadcount&lt;br /&gt;
  print &amp;quot;Thread start: &amp;quot; + threadname&lt;br /&gt;
  time.sleep(sleeptime)&lt;br /&gt;
  print &amp;quot;Thread end: &amp;quot; + threadname&lt;br /&gt;
  threadcount -= 1&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
  thread.start_new_thread(run_thread, (&amp;quot;Thread1&amp;quot;, 3))&lt;br /&gt;
  thread.start_new_thread(run_thread, (&amp;quot;Thread2&amp;quot;, 4))&lt;br /&gt;
  thread.start_new_thread(run_thread, (&amp;quot;Thread3&amp;quot;, 2))&lt;br /&gt;
  while 1:&lt;br /&gt;
    if threadcount == 0:&lt;br /&gt;
      break&lt;br /&gt;
    else:&lt;br /&gt;
      pass&lt;br /&gt;
  print &amp;quot;completed&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
Thread object: [http://softwareramblings.com/2008/06/running-functions-as-threads-in-python.html]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import threading&lt;br /&gt;
 &lt;br /&gt;
t1 = threading.Thread(target=someFunc)&lt;br /&gt;
#  with parameters: Thread(target=myfunction, args=(&#039;MyStringHere&#039;,1)).start()&lt;br /&gt;
t1.start()&lt;br /&gt;
t1.join()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Basic threading with parameters:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import threading&lt;br /&gt;
t = threading.Thread(None, someFunc, None, (param1, param2))&lt;br /&gt;
t.start()&lt;br /&gt;
t.join()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
t = threading.Thread(target=client_recv, args=(s, name))&lt;br /&gt;
while True:&lt;br /&gt;
  t.join(timeout=2)&lt;br /&gt;
  if t.isAlive():&lt;br /&gt;
    print &amp;quot;Thread is dead...&amp;quot;&lt;br /&gt;
    break&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Threading as a class: [http://softwareramblings.com/2008/06/running-functions-as-threads-in-python.html]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import threading&lt;br /&gt;
 &lt;br /&gt;
class FuncThread(threading.Thread):&lt;br /&gt;
    def __init__(self, target, *args):&lt;br /&gt;
        self._target = target&lt;br /&gt;
        self._args = args&lt;br /&gt;
        threading.Thread.__init__(self)&lt;br /&gt;
 &lt;br /&gt;
    def run(self):&lt;br /&gt;
        self._target(*self._args)&lt;br /&gt;
 &lt;br /&gt;
# Example usage&lt;br /&gt;
def someOtherFunc(data, key):&lt;br /&gt;
    print &amp;quot;someOtherFunc was called : data=%s; key=%s&amp;quot; % (str(data), str(key))&lt;br /&gt;
 &lt;br /&gt;
t1 = FuncThread(someOtherFunc, [1,2], 6)&lt;br /&gt;
t1.start()&lt;br /&gt;
t1.join()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Threading as a class #2:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import threading&lt;br /&gt;
import time&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
class MyT(threading.Thread):&lt;br /&gt;
  def __init__(self, name, time):&lt;br /&gt;
    threading.Thread.__init__(self)&lt;br /&gt;
    self.name = name&lt;br /&gt;
    self.time = time&lt;br /&gt;
  def run(self):&lt;br /&gt;
    print(&amp;quot;Thread Start: &amp;quot; + self.name)&lt;br /&gt;
    for i in range(self.time):&lt;br /&gt;
      print(&amp;quot;[&amp;quot; + self.name + &amp;quot;]&amp;quot;, end=&#039;&#039;)&lt;br /&gt;
      sys.stdout.flush()&lt;br /&gt;
      time.sleep(1)&lt;br /&gt;
    print(&amp;quot;Thread Stop: &amp;quot; + self.name)&lt;br /&gt;
&lt;br /&gt;
myt1 = MyT(&#039;1&#039;, 10)&lt;br /&gt;
myt1.start()&lt;br /&gt;
&lt;br /&gt;
myt2 = MyT(&#039;2&#039;, 15)&lt;br /&gt;
myt2.start()&lt;br /&gt;
&lt;br /&gt;
myt3 = MyT(&#039;3&#039;, 5)&lt;br /&gt;
myt3.start()&lt;br /&gt;
&lt;br /&gt;
myt4 = MyT(&#039;4&#039;, 10)&lt;br /&gt;
myt4.start()&lt;br /&gt;
&lt;br /&gt;
myt1.join()&lt;br /&gt;
myt2.join()&lt;br /&gt;
myt3.join()&lt;br /&gt;
myt4.join()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Locking:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
lock=thread.allocate_lock()&lt;br /&gt;
&lt;br /&gt;
# pass lock to thread, and use in thread as such:&lt;br /&gt;
lock.acquire()&lt;br /&gt;
#some operation&lt;br /&gt;
lock.release()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Returning data from a thread (using a [http://docs.python.org/library/queue.html queue]): [http://stackoverflow.com/questions/1886090/return-value-from-thread] [http://stackoverflow.com/questions/2829329/catch-a-threads-exception-in-the-caller-thread-in-python]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Pass exception back to parent&lt;br /&gt;
import sys&lt;br /&gt;
import threading&lt;br /&gt;
import Queue&lt;br /&gt;
&lt;br /&gt;
class ExcThread(threading.Thread):&lt;br /&gt;
    def __init__(self, bucket):&lt;br /&gt;
        threading.Thread.__init__(self)&lt;br /&gt;
        self.bucket = bucket&lt;br /&gt;
    def run(self):&lt;br /&gt;
        try:&lt;br /&gt;
            raise Exception(&#039;An error occured here.&#039;)&lt;br /&gt;
        except Exception:&lt;br /&gt;
            self.bucket.put(sys.exc_info())&lt;br /&gt;
&lt;br /&gt;
def main():&lt;br /&gt;
    bucket = Queue.Queue()&lt;br /&gt;
    thread_obj = ExcThread(bucket)&lt;br /&gt;
    thread_obj.start()&lt;br /&gt;
    while True:&lt;br /&gt;
        try:&lt;br /&gt;
            exc = bucket.get(block=False)&lt;br /&gt;
        except Queue.Empty:&lt;br /&gt;
            pass&lt;br /&gt;
        else:&lt;br /&gt;
            exc_type, exc_obj, exc_trace = exc&lt;br /&gt;
            # deal with the exception&lt;br /&gt;
            print &amp;quot;Exception Caught:&amp;quot;, exc_type, exc_obj&lt;br /&gt;
            print &amp;quot;Exception Trace:&amp;quot;, exc_trace&lt;br /&gt;
        thread_obj.join(0.1)&lt;br /&gt;
        if thread_obj.isAlive():&lt;br /&gt;
            continue&lt;br /&gt;
        else:&lt;br /&gt;
            break&lt;br /&gt;
&lt;br /&gt;
if __name__ == &#039;__main__&#039;:&lt;br /&gt;
    main()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Exception Caught: &amp;lt;type &#039;exceptions.Exception&#039;&amp;gt; An error occured here.&lt;br /&gt;
Exception Trace: &amp;lt;traceback object at 0x2b2230a285f0&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Another Exception catching queue example: (kenneth&#039;s example)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# thread function&lt;br /&gt;
def run_thread(queue, item):&lt;br /&gt;
  ...&lt;br /&gt;
  queue.put( Exception(&amp;quot;Failure on item:&amp;quot; + item) )&lt;br /&gt;
&lt;br /&gt;
threads = []&lt;br /&gt;
queue = Queue.Queue()&lt;br /&gt;
&lt;br /&gt;
# start threads&lt;br /&gt;
for item in items:&lt;br /&gt;
  t = Thread(None, run_thread, None, (queue, item))&lt;br /&gt;
  t.start()&lt;br /&gt;
  threads.append(t)&lt;br /&gt;
&lt;br /&gt;
# wait for threads&lt;br /&gt;
for t in threads:&lt;br /&gt;
  t.join()&lt;br /&gt;
&lt;br /&gt;
# catch and reraise exceptions&lt;br /&gt;
while not queue.empty():&lt;br /&gt;
  raise(queue.get())&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Returning data from a thread (using a callback function): [http://stackoverflow.com/questions/1886090/return-value-from-thread]&lt;br /&gt;
:&amp;quot;Another approach is to pass a callback function to the thread. This gives a simple, safe and flexible way to return a value to the parent, anytime from the new thread.&amp;quot;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import threading&lt;br /&gt;
import time&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
class MyThread(threading.Thread):&lt;br /&gt;
    def __init__(self, cb):&lt;br /&gt;
        threading.Thread.__init__(self)&lt;br /&gt;
        self.callback = cb&lt;br /&gt;
    def run(self):&lt;br /&gt;
        for i in range(10):&lt;br /&gt;
            self.callback(i)&lt;br /&gt;
            time.sleep(1)&lt;br /&gt;
&lt;br /&gt;
def count(x):&lt;br /&gt;
    print x&lt;br /&gt;
    sys.stdout.flush()&lt;br /&gt;
&lt;br /&gt;
t = MyThread(count)&lt;br /&gt;
t.start()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* 16.2. threading — Higher-level threading interface — Python v2.7.1 documentation - http://docs.python.org/library/threading.html&lt;br /&gt;
* An Introduction to Thread Programming - http://www.prasannatech.net/2008/08/introduction-to-thread-programming.html&lt;br /&gt;
* Python - Multithreaded Programming - http://www.tutorialspoint.com/python/python_multithreading.htm&lt;br /&gt;
* Running Functions as Threads in Python « Software Ramblings - http://softwareramblings.com/2008/06/running-functions-as-threads-in-python.html&lt;br /&gt;
* Understanding Threading in Python LG #107 - http://linuxgazette.net/107/pai.html&lt;br /&gt;
* multithreading - Simple threading in Python 2.6 using thread.start_new_thread() - Stack Overflow - http://stackoverflow.com/questions/849674/simple-threading-in-python-2-6-using-thread-start-new-thread&lt;br /&gt;
* python - Return value from thread - Stack Overflow - http://stackoverflow.com/questions/1886090/return-value-from-thread&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
Interrupt main thread:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# source: http://stackoverflow.com/questions/4591917/python-how-to-quit-cli-when-stuck-in-blocking-raw-input&lt;br /&gt;
&lt;br /&gt;
import thread&lt;br /&gt;
import time&lt;br /&gt;
&lt;br /&gt;
def main():&lt;br /&gt;
    try:&lt;br /&gt;
        m = thread.start_new_thread(killable_input, tuple())&lt;br /&gt;
        while 1:&lt;br /&gt;
            time.sleep(0.1) &lt;br /&gt;
    except KeyboardInterrupt:&lt;br /&gt;
        print &amp;quot;exception&amp;quot; &lt;br /&gt;
&lt;br /&gt;
def killable_input():&lt;br /&gt;
    w = thread.start_new_thread(normal_input, tuple())&lt;br /&gt;
    i = thread.start_new_thread(wait_sometime, tuple())&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def normal_input():&lt;br /&gt;
    s = raw_input(&amp;quot;input:&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def wait_sometime():&lt;br /&gt;
    time.sleep(4) # or any other condition to kill the thread&lt;br /&gt;
    print &amp;quot;too slow, killing imput&amp;quot;&lt;br /&gt;
    thread.interrupt_main()&lt;br /&gt;
&lt;br /&gt;
if __name__ == &#039;__main__&#039;:&lt;br /&gt;
    main()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== urllib ===&lt;br /&gt;
&lt;br /&gt;
See [[Python/urllib]]&lt;br /&gt;
&lt;br /&gt;
=== Command line arguments ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import sys&lt;br /&gt;
for x in sys.argv:&lt;br /&gt;
    print x&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Execute other python script ===&lt;br /&gt;
&lt;br /&gt;
 import sys&lt;br /&gt;
 sys.argv = [&#039;&#039;, &#039;my&#039;, &#039;args&#039;, &#039;here&#039;]&lt;br /&gt;
 execfile(&#039;myscript.py&#039;)  # does not support arguments directly&lt;br /&gt;
&lt;br /&gt;
=== Exit Code ===&lt;br /&gt;
&lt;br /&gt;
sys.exit(n) http://docs.python.org/library/sys.html:&lt;br /&gt;
 import sys&lt;br /&gt;
 sys.exit(1)  # exit code of 1 (default is 0)&lt;br /&gt;
 sys.exit(&amp;quot;some error&amp;quot;)  # exit code of 1, and message displayed&lt;br /&gt;
&lt;br /&gt;
=== [http://docs.python.org/library/syslog.html syslog] ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import syslog&lt;br /&gt;
syslog.openlog(&#039;[WATER]&#039;)&lt;br /&gt;
syslog.syslog(&#039;Processing started&#039;)&lt;br /&gt;
if error:&lt;br /&gt;
    syslog.syslog(syslog.LOG_ERR, &#039;Processing started&#039;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import syslog&lt;br /&gt;
syslog.openlog(&#039;[WATER]&#039;)&lt;br /&gt;
def log(msg):&lt;br /&gt;
    syslog.syslog(str(msg))&lt;br /&gt;
log(&amp;quot;Starting...&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Subprocess ===&lt;br /&gt;
&lt;br /&gt;
Subprocess - http://docs.python.org/library/subprocess.html&lt;br /&gt;
&lt;br /&gt;
Methods of subprocess (or external command execution):&lt;br /&gt;
* subprocess (only method to rule/replace all others)&lt;br /&gt;
* os.system&lt;br /&gt;
* os.spawn*&lt;br /&gt;
* os.popen*&lt;br /&gt;
* popen2.*&lt;br /&gt;
* commands.*&lt;br /&gt;
&lt;br /&gt;
My New Favorite:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import subprocess&lt;br /&gt;
class Run(object):&lt;br /&gt;
    class RC(int):&lt;br /&gt;
        pass&lt;br /&gt;
    def __new__(cls, cmd, *args, **kwargs):&lt;br /&gt;
        p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)&lt;br /&gt;
        rc = cls.RC(p.wait())&lt;br /&gt;
        rc.output = &amp;quot;\n&amp;quot;.join(p.stdout.readlines())&lt;br /&gt;
        rc.error = &amp;quot;\n&amp;quot;.join(p.stderr.readlines())&lt;br /&gt;
        return rc&lt;br /&gt;
&lt;br /&gt;
if Run(&amp;quot;some command&amp;quot;): print &amp;quot;do something&amp;quot;  # on rc of not 0 (negative or positive)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
My Favorite:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def exe(cmd):&lt;br /&gt;
    p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)&lt;br /&gt;
    #output = &amp;quot; | &amp;quot;.join(p.stdout.readlines())&lt;br /&gt;
    output = &amp;quot;\n&amp;quot;.join(p.stdout.readlines())&lt;br /&gt;
    rc = p.wait()&lt;br /&gt;
    return (rc, output)&lt;br /&gt;
&lt;br /&gt;
def exe_checked(cmd, checked=True):&lt;br /&gt;
    p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)&lt;br /&gt;
    #output = &amp;quot; | &amp;quot;.join(p.stdout.readlines())&lt;br /&gt;
    output = &amp;quot;\n&amp;quot;.join(p.stdout.readlines())&lt;br /&gt;
    rc = p.wait()&lt;br /&gt;
    if rc and checked:&lt;br /&gt;
        raise Exception(&amp;quot;Command returned non zero [{0}]: {1}&amp;quot;.format(rc, cmd)&lt;br /&gt;
    return (rc, output)&lt;br /&gt;
&lt;br /&gt;
def exe_with_stderr(cmd):&lt;br /&gt;
    p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subproc&lt;br /&gt;
ess.PIPE)&lt;br /&gt;
    output = &amp;quot; | &amp;quot;.join(p.stdout.readlines())&lt;br /&gt;
    outputerr = &amp;quot; | &amp;quot;.join(p.stderr.readlines())&lt;br /&gt;
    rc = p.wait()&lt;br /&gt;
    return (rc, output, outputerr)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def exec_program(cmd):&lt;br /&gt;
    s = subprocess.Popen(cmd.split(), stdout=subprocess.PIPE, stderr=subprocess.PIPE)&lt;br /&gt;
    stdout, stderr = s.communicate()&lt;br /&gt;
    result = s.wait()&lt;br /&gt;
    return stdout, stderr, result&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pass along output and return true error code:&lt;br /&gt;
 import subprocess&lt;br /&gt;
 retcode = subprocess.call([&amp;quot;ls&amp;quot;, &amp;quot;-l&amp;quot;])  # true return code, output sent to STDOUT&lt;br /&gt;
&lt;br /&gt;
 retcode = subprocess.call([&amp;quot;foo.sh&amp;quot;,&amp;quot;args&amp;quot;],shell=True)  # Execute in shell, with shell processing&lt;br /&gt;
 retcode = subprocess.call([&#039;C:\\Temp\\a b c\\Notepad.exe&#039;])&lt;br /&gt;
 retcode = subprocess.call([&amp;quot;D:/Python24/Python.exe&amp;quot;, &amp;quot;Skripta.py&amp;quot;, &amp;quot;arg1&amp;quot;, &amp;quot;arg2&amp;quot;])&lt;br /&gt;
&lt;br /&gt;
Note: shell=True is equivalent to: subprocess.Popen([&#039;/bin/sh&#039;, &#039;-c&#039;, args[0], args[1], ...])&lt;br /&gt;
&lt;br /&gt;
Process STDOUT and STDERR and get return code:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
import subprocess&lt;br /&gt;
import string&lt;br /&gt;
&lt;br /&gt;
cmd = &amp;quot;cat /etc/passwd | grep ken&amp;quot;&lt;br /&gt;
p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) # stderr=subprocess.STDOUT to combine&lt;br /&gt;
&lt;br /&gt;
out = string.join(p.stdout.readlines())&lt;br /&gt;
outerr = string.join(p.stderr.readlines())&lt;br /&gt;
retcode = str(p.wait())&lt;br /&gt;
&lt;br /&gt;
print(&amp;quot;STDOUT: &amp;quot; + out)&lt;br /&gt;
print(&amp;quot;STDERR: &amp;quot; + outerr)&lt;br /&gt;
print(&amp;quot;RETCODE: &amp;quot; + retcode)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Above with stderr redirected to stdout (combined):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import subprocess&lt;br /&gt;
p = subprocess.Popen(&#039;ls&#039;, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)&lt;br /&gt;
for line in p.stdout.readlines():&lt;br /&gt;
    print line,&lt;br /&gt;
retval = p.wait()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Replacing shell backtick: [http://docs.python.org/library/subprocess.html]&lt;br /&gt;
 # shell code:&lt;br /&gt;
 # OUTPUT=`mycmd myarg`&lt;br /&gt;
 from subprocess import Popen&lt;br /&gt;
 output = Popen([&amp;quot;mycmd&amp;quot;, &amp;quot;myarg&amp;quot;], stdout=PIPE).communicate()[0]&lt;br /&gt;
&lt;br /&gt;
Replacing shell pipeline  [http://docs.python.org/library/subprocess.html]&lt;br /&gt;
 # shell code:&lt;br /&gt;
 # OUTPUT=`dmesg | grep hda`&lt;br /&gt;
 from subprocess import Popen&lt;br /&gt;
 p1 = Popen([&amp;quot;dmesg&amp;quot;], stdout=PIPE)&lt;br /&gt;
 p2 = Popen([&amp;quot;grep&amp;quot;, &amp;quot;hda&amp;quot;], stdin=p1.stdout, stdout=PIPE)&lt;br /&gt;
 p1.stdout.close()  # Allow p1 to receive a SIGPIPE if p2 exits.&lt;br /&gt;
 output = p2.communicate()[0]&lt;br /&gt;
&lt;br /&gt;
Replacing os.system(): [http://docs.python.org/library/subprocess.html]&lt;br /&gt;
 # old:&lt;br /&gt;
 sts = os.system(&amp;quot;mycmd&amp;quot; + &amp;quot; myarg&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
 # new:&lt;br /&gt;
 p = Popen(&amp;quot;mycmd&amp;quot; + &amp;quot; myarg&amp;quot;, shell=True)&lt;br /&gt;
 sts = os.waitpid(p.pid, 0)[1]&lt;br /&gt;
&lt;br /&gt;
Control an executed process:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cmd = &amp;quot;/usr/bin/java -Xms256M -Xmx1024M -jar minecraft_server.jar nogui&amp;quot;&lt;br /&gt;
&lt;br /&gt;
p = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE,&lt;br /&gt;
        stdout=subprocess.PIPE, stderr=subprocess.STDOUT)&lt;br /&gt;
&lt;br /&gt;
# cycle while process continues alive&lt;br /&gt;
while p.poll() == None:&lt;br /&gt;
&lt;br /&gt;
  # check if input&lt;br /&gt;
  if select.select([p.stdout.fileno()], [], [], 1)[0]:&lt;br /&gt;
    while select.select([p.stdout.fileno()], [], [], .1)[0]:&lt;br /&gt;
        line = p.stdout.readline()&lt;br /&gt;
        # ... process&lt;br /&gt;
&lt;br /&gt;
  # write something to process&lt;br /&gt;
  p.stdin.write(&amp;quot;tp %s %s\n&amp;quot; % (user1, user2))&lt;br /&gt;
&lt;br /&gt;
  ...&lt;br /&gt;
&lt;br /&gt;
  # time to force a quit: (choose which you need)&lt;br /&gt;
  p.kill()  # SIGKILL&lt;br /&gt;
  p.terminate()  # SIGTERM&lt;br /&gt;
  os.kill(p.pid, signal.SIGTERM)  # same as first, but not as clean&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Other Command Execution ====&lt;br /&gt;
&lt;br /&gt;
Old method with os.system(): [http://docs.python.org/library/os.html]&lt;br /&gt;
 import os&lt;br /&gt;
 encoded_wait_code = os.system(&amp;quot;some command&amp;quot;)  # output sent to STDOUT&lt;br /&gt;
 # Note: returns code of 0 if command returns 0, but wait() encoded value for all other values&lt;br /&gt;
&lt;br /&gt;
Quick and dirty old method (prints stderr, captures stdout)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import os&lt;br /&gt;
out = string.join( os.popen(cmd).readlines() )&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Quick and dirty old method (prints stderr, captures stdout, captures ugly wait() encoded return code)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import os&lt;br /&gt;
p = os.popen(cmd)&lt;br /&gt;
stdout = &amp;quot;&amp;quot;.join( p.readlines() )&lt;br /&gt;
encoded_wait_code = p.close()  # None if 0&lt;br /&gt;
rcode = os.WEXITSTATUS(ugly_rcode) # fix ugly wait() encoded rcode&lt;br /&gt;
print(stdout)&lt;br /&gt;
print(rcode)&lt;br /&gt;
&lt;br /&gt;
if os.popen(cmd).close():&lt;br /&gt;
  print &amp;quot;error with cmd: %s&amp;quot; % cmd&lt;br /&gt;
  sys.exit(1)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
???:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
os.spawnvp(os.P_WAIT,&amp;quot;/usr/bin/mplayer&amp;quot;,[&amp;quot;&amp;quot;,&amp;quot;-ao&amp;quot;,&amp;quot;pcm&amp;quot;,file])&lt;br /&gt;
# or &lt;br /&gt;
os.spawnvp(os.P_NOWAIT,&amp;quot;/usr/bin/mplayer&amp;quot;,[&amp;quot;&amp;quot;,&amp;quot;-ao&amp;quot;,&amp;quot;pcm&amp;quot;,file])&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Replacing os.system(): [http://docs.python.org/library/subprocess.html]&lt;br /&gt;
 # old:&lt;br /&gt;
 sts = os.system(&amp;quot;mycmd&amp;quot; + &amp;quot; myarg&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
 # new:&lt;br /&gt;
 p = Popen(&amp;quot;mycmd&amp;quot; + &amp;quot; myarg&amp;quot;, shell=True)&lt;br /&gt;
 sts = os.waitpid(p.pid, 0)[1]&lt;br /&gt;
&lt;br /&gt;
More realistic example replacing os.system(): [http://docs.python.org/library/subprocess.html]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
try:&lt;br /&gt;
    retcode = call(&amp;quot;mycmd&amp;quot; + &amp;quot; myarg&amp;quot;, shell=True)&lt;br /&gt;
    if retcode &amp;lt; 0:&lt;br /&gt;
        print &amp;gt;&amp;gt;sys.stderr, &amp;quot;Child was terminated by signal&amp;quot;, -retcode&lt;br /&gt;
    else:&lt;br /&gt;
        print &amp;gt;&amp;gt;sys.stderr, &amp;quot;Child returned&amp;quot;, retcode&lt;br /&gt;
except OSError, e:&lt;br /&gt;
    print &amp;gt;&amp;gt;sys.stderr, &amp;quot;Execution failed:&amp;quot;, e&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== select ====&lt;br /&gt;
&lt;br /&gt;
Select:&lt;br /&gt;
&lt;br /&gt;
select.select(rlist, wlist, xlist[, timeout])&lt;br /&gt;
: This is a straightforward interface to the Unix select() system call. The first three arguments are sequences of ‘waitable objects’: either integers representing file descriptors or objects with a parameterless method named fileno() returning such an integer&lt;br /&gt;
: The optional timeout argument specifies a time-out as a floating point number in seconds. When the timeout argument is omitted the function blocks until at least one file descriptor is ready. A time-out value of zero specifies a poll and never blocks.&lt;br /&gt;
&lt;br /&gt;
 if select.select([sys.stdin.fileno()], [], [], .1)[0]:&lt;br /&gt;
     line = p.stdout.readline()&lt;br /&gt;
&lt;br /&gt;
==== full wrapped execution ====&lt;br /&gt;
&lt;br /&gt;
Process timeout (by Kenneth):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import subprocess&lt;br /&gt;
import time&lt;br /&gt;
import os&lt;br /&gt;
import signal&lt;br /&gt;
&lt;br /&gt;
def cmd(cmd, timeout=300, retry=0):&lt;br /&gt;
    # Execute command, time progress, and kill on timeout&lt;br /&gt;
&lt;br /&gt;
    # (status, output) = commands.getstatusoutput(cmd)&lt;br /&gt;
    start_time = None&lt;br /&gt;
    status = None&lt;br /&gt;
    output = None&lt;br /&gt;
    for retry_count in range(retry+1):&lt;br /&gt;
        if retry_count &amp;gt; 0:&lt;br /&gt;
            print(&amp;quot;RETRY: &amp;quot; + str(retry_count) + &amp;quot; &amp;quot; + cmd)&lt;br /&gt;
        start_time = time.time()&lt;br /&gt;
        p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE,&lt;br /&gt;
                stderr=subprocess.STDOUT)&lt;br /&gt;
        timeout_fail = False&lt;br /&gt;
        while p.poll() == None:&lt;br /&gt;
            if time.time() - start_time &amp;gt; timeout:&lt;br /&gt;
                # kill process&lt;br /&gt;
                print(&amp;quot;TIMEOUT: &amp;quot; + str(timeout) + &amp;quot;sec - killing (&amp;quot; + str(p.pid) + &amp;quot;) - &amp;quot; + cmd)&lt;br /&gt;
                try:&lt;br /&gt;
                    os.kill(p.pid, signal.SIGTERM)&lt;br /&gt;
                except OSError as e:&lt;br /&gt;
                    print(&amp;quot;Kill exception: &amp;quot; + str(e))&lt;br /&gt;
                timeout_fail = True&lt;br /&gt;
                break&lt;br /&gt;
            #print(&amp;quot;.&amp;quot;)&lt;br /&gt;
            time.sleep(1)&lt;br /&gt;
        status = p.poll()&lt;br /&gt;
        output = p.stdout.read()&lt;br /&gt;
        if timeout_fail == False:&lt;br /&gt;
            break&lt;br /&gt;
    seconds = int(time.time() - start_time)&lt;br /&gt;
    return (status, output, seconds)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
Process input and output wrapper (from minecraft):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import subprocess&lt;br /&gt;
import select&lt;br /&gt;
import re&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
cmd = &amp;quot;/usr/bin/java -Xms256M -Xmx1024M -jar minecraft_server.jar nogui&amp;quot;&lt;br /&gt;
&lt;br /&gt;
p = subprocess.Popen(cmd, shell=True,&lt;br /&gt;
        stdin=subprocess.PIPE,&lt;br /&gt;
        stdout=subprocess.PIPE,&lt;br /&gt;
        stderr=subprocess.STDOUT)&lt;br /&gt;
&lt;br /&gt;
# cycle while process continues alive&lt;br /&gt;
while p.poll() == None:&lt;br /&gt;
&lt;br /&gt;
    if select.select([p.stdout.fileno()], [], [], 1)[0]:&lt;br /&gt;
        while select.select([p.stdout.fileno()], [], [], .1)[0]:&lt;br /&gt;
            line = p.stdout.readline()&lt;br /&gt;
            # &amp;lt;kiloforce&amp;gt; -tp joe&lt;br /&gt;
            match = re.findall(&amp;quot;&amp;lt;(.*)&amp;gt; -tp (.*)&amp;quot;, line)&lt;br /&gt;
            if match:&lt;br /&gt;
                user1 = match[0][0]&lt;br /&gt;
                user2 = match[0][1]&lt;br /&gt;
                print &amp;quot;&amp;gt;&amp;gt; ACTION: Teleporting %s to %s&amp;quot; % (user1, user2)&lt;br /&gt;
                p.stdin.write(&amp;quot;tp %s %s\n&amp;quot; % (user1, user2))&lt;br /&gt;
            if line:&lt;br /&gt;
                print &amp;quot;&amp;gt;&amp;gt; SERVER: %s&amp;quot; % line.strip()&lt;br /&gt;
            else:&lt;br /&gt;
                print &amp;quot;The server died!&amp;quot;&lt;br /&gt;
                sys.exit(1)&lt;br /&gt;
&lt;br /&gt;
    if select.select([sys.stdin.fileno()], [], [], .1)[0]:&lt;br /&gt;
        line = sys.stdin.readline()&lt;br /&gt;
        print &amp;quot;&amp;gt;&amp;gt; CONSOLE: %s&amp;quot; % line.strip()&lt;br /&gt;
        p.stdin.write(&amp;quot;%s&amp;quot; % line)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Command With Timeout ====&lt;br /&gt;
&lt;br /&gt;
python - Using module &#039;subprocess&#039; with timeout - Stack Overflow - http://stackoverflow.com/questions/1191374/using-module-subprocess-with-timeout&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import subprocess, threading&lt;br /&gt;
&lt;br /&gt;
class Command(object):&lt;br /&gt;
    def __init__(self, cmd):&lt;br /&gt;
        self.cmd = cmd&lt;br /&gt;
        self.process = None&lt;br /&gt;
&lt;br /&gt;
    def run(self, timeout):&lt;br /&gt;
        def target():&lt;br /&gt;
            print &#039;Thread started&#039;&lt;br /&gt;
            self.process = subprocess.Popen(self.cmd, shell=True)&lt;br /&gt;
            self.process.communicate()&lt;br /&gt;
            print &#039;Thread finished&#039;&lt;br /&gt;
&lt;br /&gt;
        thread = threading.Thread(target=target)&lt;br /&gt;
        thread.start()&lt;br /&gt;
&lt;br /&gt;
        thread.join(timeout)&lt;br /&gt;
        if thread.is_alive():&lt;br /&gt;
            print &#039;Terminating process&#039;&lt;br /&gt;
            self.process.terminate()&lt;br /&gt;
            thread.join()&lt;br /&gt;
        print self.process.returncode&lt;br /&gt;
&lt;br /&gt;
command = Command(&amp;quot;echo &#039;Process started&#039;; sleep 2; echo &#039;Process finished&#039;&amp;quot;)&lt;br /&gt;
command.run(timeout=3)&lt;br /&gt;
command.run(timeout=1)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
My version:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import subprocess&lt;br /&gt;
import threading&lt;br /&gt;
&lt;br /&gt;
class Command(object):&lt;br /&gt;
    def __init__(self, cmd, capture=False, shell=True):&lt;br /&gt;
        self.cmd = cmd&lt;br /&gt;
        self.process = None&lt;br /&gt;
        self.thread = None&lt;br /&gt;
        self.shell = shell&lt;br /&gt;
        if type(cmd) == list:&lt;br /&gt;
            self.shell = False&lt;br /&gt;
        self.rc = None&lt;br /&gt;
        self.pid = None&lt;br /&gt;
        self.stdout = None&lt;br /&gt;
        self.stderr = None&lt;br /&gt;
        self.capture = capture  # capture stdout?&lt;br /&gt;
&lt;br /&gt;
    def run(self, timeout=None, wait=True):&lt;br /&gt;
        def target():&lt;br /&gt;
            print &#039;&amp;gt;&amp;gt; Thread started (%s)&#039; % self.cmd&lt;br /&gt;
            if self.capture:&lt;br /&gt;
                self.process = subprocess.Popen(self.cmd, shell=self.shell, stdout=subprocess.PIPE, stderr=subprocess.PIPE)&lt;br /&gt;
            else:&lt;br /&gt;
                self.process = subprocess.Popen(self.cmd, shell=self.shell)&lt;br /&gt;
            print &#039;&amp;gt;&amp;gt; Thread PID: %d&#039; % self.process.pid&lt;br /&gt;
            self.pid = self.process.pid&lt;br /&gt;
            self.stdout, self.stderr = self.process.communicate()&lt;br /&gt;
            self.rc = self.process.returncode&lt;br /&gt;
            print &#039;&amp;gt;&amp;gt; Thread finished: %d&#039; % self.rc&lt;br /&gt;
&lt;br /&gt;
        self.thread = threading.Thread(target=target)&lt;br /&gt;
        self.thread.start()&lt;br /&gt;
&lt;br /&gt;
        if wait:&lt;br /&gt;
            self.wait(timeout)&lt;br /&gt;
        return self  # so you can do: c = Command().run()&lt;br /&gt;
&lt;br /&gt;
    def wait(self, timeout=None):&lt;br /&gt;
        print &#039;&amp;gt;&amp;gt; Waiting for thread...&#039;&lt;br /&gt;
        if timeout:&lt;br /&gt;
            self.thread.join(timeout)&lt;br /&gt;
        else:&lt;br /&gt;
            self.thread.join()&lt;br /&gt;
        if self.thread.is_alive():&lt;br /&gt;
            print &#039;&amp;gt;&amp;gt; Terminating process&#039;&lt;br /&gt;
            self.process.terminate()&lt;br /&gt;
            self.rc = self.process.returncode&lt;br /&gt;
            self.thread.join()&lt;br /&gt;
            if self.thread.is_alive():&lt;br /&gt;
                print &#039;&amp;gt;&amp;gt; Failed to terminate&#039;&lt;br /&gt;
        else:&lt;br /&gt;
            print &#039;&amp;gt;&amp;gt; Thread completed&#039;&lt;br /&gt;
        #print self.process.returncode&lt;br /&gt;
&lt;br /&gt;
    def is_alive(self ):&lt;br /&gt;
        return self.thread.is_alive()&lt;br /&gt;
&lt;br /&gt;
command = Command(&#039;do something&#039;).run()&lt;br /&gt;
&lt;br /&gt;
command2 = Command([&#039;do&#039;, &#039;something&#039;, &#039;long&#039;]).run(wait=False)&lt;br /&gt;
command2.wait(timeout=10)&lt;br /&gt;
&lt;br /&gt;
command3 = Command(&#039;want output&#039;, capture=True).run()&lt;br /&gt;
print command3.stdout&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== System call ===&lt;br /&gt;
&lt;br /&gt;
 os.system(&amp;quot;some_command with args&amp;quot;)&lt;br /&gt;
 os.system(&amp;quot;some_command &amp;lt; input_file | another_command &amp;gt; output_file&amp;quot;)&lt;br /&gt;
 stream = os.popen(&amp;quot;some_command with args&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Here&#039;s a summary of the ways to call external programs and the advantages and disadvantages of each:&lt;br /&gt;
&lt;br /&gt;
1.&lt;br /&gt;
: os.system(&amp;quot;some_command with args&amp;quot;) passes the command and arguments to your system&#039;s shell. This is nice because you can actually run multiple commands at once in this manner and set up pipes and input/output redirection. For example,&lt;br /&gt;
: os.system(&amp;quot;some_command &amp;lt; input_file | another_command &amp;gt; output_file&amp;quot;)&lt;br /&gt;
: However, while this is convenient, you have to manually handle the escaping of shell characters such as spaces, etc. On the other hand, this also lets you run commands which are simply shell commands and not actually external programs.&lt;br /&gt;
: http://docs.python.org/lib/os-process.html&lt;br /&gt;
&lt;br /&gt;
2.&lt;br /&gt;
: stream = os.popen(&amp;quot;some_command with args&amp;quot;) will do the same thing as os.system except that it gives you a file-like object that you can use to access standard input/output for that process. There are 3 other variants of popen that all handle the i/o slightly differently. If you pass everything as a string, then your command is passed to the shell; if you pass them as a list then you don&#039;t need to worry about escaping anything.&lt;br /&gt;
: http://docs.python.org/lib/os-newstreams.html&lt;br /&gt;
&lt;br /&gt;
3.&lt;br /&gt;
: The Popen class of the subprocess module. This is intended as a replacement for os.popen but has the downside of being slightly more complicated by virtue of being so comprehensive. For example, you&#039;d say&lt;br /&gt;
: print Popen(&amp;quot;echo Hello World&amp;quot;, stdout=PIPE, shell=True).stdout.read()&lt;br /&gt;
: instead of&lt;br /&gt;
: print os.popen(&amp;quot;echo Hello World&amp;quot;).read()&lt;br /&gt;
: but it is nice to have all of the options there in one unified class instead of 4 different popen functions.&lt;br /&gt;
: http://docs.python.org/lib/node528.html&lt;br /&gt;
&lt;br /&gt;
4.&lt;br /&gt;
: The call function from the subprocess module. This is basically just like the Popen class and takes all of the same arguments, but it simply wait until the command completes and gives you the return code. For example:&lt;br /&gt;
: return_code = call(&amp;quot;echo Hello World&amp;quot;, shell=True)&lt;br /&gt;
: http://docs.python.org/lib/node529.html&lt;br /&gt;
&lt;br /&gt;
5.&lt;br /&gt;
: The os module also has all of the fork/exec/spawn functions that you&#039;d have in a C program, but I don&#039;t recommend using them directly.&lt;br /&gt;
&lt;br /&gt;
: The subprocess module should probably be what you use.&lt;br /&gt;
&lt;br /&gt;
Source: [http://stackoverflow.com/questions/89228/how-to-call-external-command-in-python]&lt;br /&gt;
&lt;br /&gt;
== Advanced Code ==&lt;br /&gt;
&lt;br /&gt;
=== Executing Code from Command Line ===&lt;br /&gt;
&lt;br /&gt;
 python -c [cmd]&lt;br /&gt;
 # -c cmd : program passed in as string (terminates option list)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python -c &amp;quot;import sys;exec(sys.stdin.read())&amp;quot; &amp;lt;&amp;lt; &amp;quot;EOF&amp;quot;&lt;br /&gt;
def test1():&lt;br /&gt;
  print &amp;quot;test1&amp;quot;&lt;br /&gt;
test1()&lt;br /&gt;
print &amp;quot;test&amp;quot;&lt;br /&gt;
EOF&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Integer Return Code Class ===&lt;br /&gt;
&lt;br /&gt;
Python3 version:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class RC(int):&lt;br /&gt;
  def __new__(cls, rc, stdout=&#039;&#039;, stderr=&#039;&#039;):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;We can&#039;t use use __init__ because int is immutable.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    return super(RC, cls).__new__(cls, rc)&lt;br /&gt;
  def __init__(self, rc, stdout=&#039;&#039;, stderr=&#039;&#039;):&lt;br /&gt;
    super().__init__()&lt;br /&gt;
    self.rc = rc  # redundant&lt;br /&gt;
    self.stdout = stdout&lt;br /&gt;
    self.stderr = stderr&lt;br /&gt;
  def __repr__(self):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;Optional string output&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    return &amp;quot;(%s, &#039;%s&#039;, &#039;%s&#039;)&amp;quot; % (self.rc, self.stdout, self.stderr)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Python2 version:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class RC(int):&lt;br /&gt;
  def __new__(cls, rc, stdout=&#039;&#039;, stderr=&#039;&#039;):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;We can&#039;t use use __init__ because int is immutable.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    return super(RC, cls).__new__(cls, rc)&lt;br /&gt;
  def __init__(self, rc, stdout=&#039;&#039;, stderr=&#039;&#039;):&lt;br /&gt;
    super(self.__class__, self).__init__(rc)&lt;br /&gt;
    self.rc = rc  # redundant&lt;br /&gt;
    self.stdout = stdout&lt;br /&gt;
    self.stderr = stderr&lt;br /&gt;
  def __repr__(self):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;Optional string output&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    return &amp;quot;(%s, &#039;%s&#039;, &#039;%s&#039;)&amp;quot; % (self, self.stdout, self.stderr)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
sample:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; rc1 = RC(5)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; rc2 = RC(0, &#039;out&#039;, &#039;err&#039;)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; rc1&lt;br /&gt;
(5, &#039;&#039;, &#039;&#039;)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; rc2&lt;br /&gt;
(5, &#039;out&#039;, &#039;err&#039;)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; rc2.stdout&lt;br /&gt;
&#039;out&#039;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; int(rc1)&lt;br /&gt;
5&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; 0 + rc1&lt;br /&gt;
5&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; if rc1 &amp;lt;= 5:  print &amp;quot;yes&amp;quot;&lt;br /&gt;
...&lt;br /&gt;
yes&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; if rc2:  print &amp;quot;non-zero&amp;quot;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Smart Execute ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class RC(int):&lt;br /&gt;
    def __new__(cls, rc, output=&#039;&#039;):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;We can&#039;t use use __init__ because int is immutable.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        return super(RC, cls).__new__(cls, rc)&lt;br /&gt;
    def __init__(self, rc, output=&#039;&#039;):&lt;br /&gt;
        super().__init__()&lt;br /&gt;
        self.rc = rc  # redundant&lt;br /&gt;
        self.output = output&lt;br /&gt;
    def __repr__(self):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Optional string output&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        return &amp;quot;(%s, &#039;%s&#039;)&amp;quot; % (self.rc, self.output)&lt;br /&gt;
&lt;br /&gt;
def smart_execute(cmd, display=True, checked=False):&lt;br /&gt;
    output = &amp;quot;&amp;quot;&lt;br /&gt;
    process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, bufsize=1, shell=True, encoding=&#039;utf-8&#039;)&lt;br /&gt;
    for c in iter(lambda: process.stdout.read(1), &amp;quot;&amp;quot;):&lt;br /&gt;
        if display:&lt;br /&gt;
            sys.stdout.buffer.write(c.encode(&#039;utf-8&#039;))&lt;br /&gt;
        output += c&lt;br /&gt;
    process.stdout.close()&lt;br /&gt;
    rc = process.wait()&lt;br /&gt;
    if checked and rc:&lt;br /&gt;
        raise subprocess.CalledProcessError(ret, cmd)&lt;br /&gt;
    return RC(rc, output.strip())&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Not smart version:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def execute(cmd, return_output=False):&lt;br /&gt;
    out = &amp;quot;&amp;quot;&lt;br /&gt;
    process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, bufsize=1, shell=True, encoding=&#039;utf-8&#039;)&lt;br /&gt;
    for c in iter(lambda: process.stdout.read(1), &amp;quot;&amp;quot;):&lt;br /&gt;
        sys.stdout.buffer.write(c.encode(&#039;utf-8&#039;))&lt;br /&gt;
        if return_output:&lt;br /&gt;
            out += c&lt;br /&gt;
    process.stdout.close()&lt;br /&gt;
    ret = process.wait()&lt;br /&gt;
    if ret:&lt;br /&gt;
        raise subprocess.CalledProcessError(ret, cmd)&lt;br /&gt;
    if return_output:&lt;br /&gt;
        return out.strip()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== select ===&lt;br /&gt;
&lt;br /&gt;
usage: select.select(rlist, wlist, xlist[, timeout]) [http://docs.python.org/2/library/select.html]&lt;br /&gt;
* rlist: wait until ready for reading&lt;br /&gt;
* wlist: wait until ready for writing&lt;br /&gt;
* xlist: wait for an “exceptional condition” (see the manual page for what your system considers such a condition)&lt;br /&gt;
* The optional timeout argument specifies a time-out as a floating point number in seconds.&lt;br /&gt;
&lt;br /&gt;
 if select.select([p.stdout.fileno()], [], [], 1)[0]:&lt;br /&gt;
&lt;br /&gt;
=== ANSI Color ===&lt;br /&gt;
&lt;br /&gt;
* ANSI escape code - http://en.wikipedia.org/wiki/ANSI_escape_code&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
unicode - Print in terminal with colors using Python? - Stack Overflow - https://stackoverflow.com/questions/287871/print-in-terminal-with-colors-using-python&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class bcolors:&lt;br /&gt;
    HEADER = &#039;\033[95m&#039;&lt;br /&gt;
    OKBLUE = &#039;\033[94m&#039;&lt;br /&gt;
    OKGREEN = &#039;\033[92m&#039;&lt;br /&gt;
    WARNING = &#039;\033[93m&#039;&lt;br /&gt;
    FAIL = &#039;\033[91m&#039;&lt;br /&gt;
    ENDC = &#039;\033[0m&#039;&lt;br /&gt;
    BOLD = &#039;\033[1m&#039;&lt;br /&gt;
    UNDERLINE = &#039;\033[4m&#039;&lt;br /&gt;
&lt;br /&gt;
print bcolors.WARNING + &amp;quot;Warning: No active frommets remain. Continue?&amp;quot; + bcolors.ENDC&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class colors:&lt;br /&gt;
  black = 0&lt;br /&gt;
  red = 1&lt;br /&gt;
  green = 2&lt;br /&gt;
  yellow = 3&lt;br /&gt;
  blue = 4&lt;br /&gt;
  magenta = 5&lt;br /&gt;
  cyan = 6&lt;br /&gt;
  white = 7&lt;br /&gt;
  fg = 30  # foreground add&lt;br /&gt;
  bg = 40  # background add&lt;br /&gt;
  bfg = 90  # bold foreground add&lt;br /&gt;
  bbg = 100  # bold background add&lt;br /&gt;
&lt;br /&gt;
print &#039;\033[%dm red foreground \033[0m&#039; % (colors.red + colors.fg)&lt;br /&gt;
print &#039;\033[%dm bold red foreground \033[0m&#039; % (colors.red + colors.bfg)&lt;br /&gt;
print &#039;\033[%dm blue background \033[0m&#039; % (colors.blue + colors.bg)&lt;br /&gt;
print &#039;\033[%dm bold blue background \033[0m&#039; % (colors.blue + colors.bbg)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
Before you start spouting escape sequences, you should check that stdout is a tty. You can do this with sys.stdout.isatty()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sys.stdout.isatty()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def hilite(string, status, bold):&lt;br /&gt;
    attr = []&lt;br /&gt;
    if status:&lt;br /&gt;
        # green&lt;br /&gt;
        attr.append(&#039;32&#039;)&lt;br /&gt;
    else:&lt;br /&gt;
        # red&lt;br /&gt;
        attr.append(&#039;31&#039;)&lt;br /&gt;
    if bold:&lt;br /&gt;
        attr.append(&#039;1&#039;)&lt;br /&gt;
    return &#039;\x1b[%sm%s\x1b[0m&#039; % (&#039;;&#039;.join(attr), string)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Python | change text color in shell - Stack Overflow - https://stackoverflow.com/questions/2330245/python-change-text-color-in-shell&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
For reference, a small bash script which prints a table of escape sequences: colortable16.sh: ([http://www.frexx.de/xterm-256-notes/ The 256 color mode of xterm], [http://plug.org/pipermail/plug/2008-March/016821.html The 90s called; they want their 256 colors back])&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
&lt;br /&gt;
# prints a color table of 8bg * 8fg * 2 states (regular/bold)&lt;br /&gt;
echo&lt;br /&gt;
echo Table for 16-color terminal escape sequences.&lt;br /&gt;
echo Replace ESC with \\033 in bash.&lt;br /&gt;
echo&lt;br /&gt;
echo &amp;quot;Background | Foreground colors&amp;quot;&lt;br /&gt;
echo &amp;quot;---------------------------------------------------------------------&amp;quot;&lt;br /&gt;
for((bg=40;bg&amp;lt;=47;bg++)); do&lt;br /&gt;
	for((bold=0;bold&amp;lt;=1;bold++)) do&lt;br /&gt;
		echo -en &amp;quot;\033[0m&amp;quot;&amp;quot; ESC[${bg}m   | &amp;quot;&lt;br /&gt;
		for((fg=30;fg&amp;lt;=37;fg++)); do&lt;br /&gt;
			if [ $bold == &amp;quot;0&amp;quot; ]; then&lt;br /&gt;
				echo -en &amp;quot;\033[${bg}m\033[${fg}m [${fg}m  &amp;quot;&lt;br /&gt;
			else&lt;br /&gt;
				echo -en &amp;quot;\033[${bg}m\033[1;${fg}m [1;${fg}m&amp;quot;&lt;br /&gt;
			fi&lt;br /&gt;
		done&lt;br /&gt;
		echo -e &amp;quot;\033[0m&amp;quot;&lt;br /&gt;
	done&lt;br /&gt;
	echo &amp;quot;--------------------------------------------------------------------- &amp;quot;&lt;br /&gt;
done&lt;br /&gt;
&lt;br /&gt;
echo&lt;br /&gt;
echo&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Python version: (modified by me)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
# prints a color table of 8bg * 8fg * 2 states (regular/bold)&lt;br /&gt;
print&lt;br /&gt;
print &amp;quot;Table for 16-color terminal escape sequences.&amp;quot;&lt;br /&gt;
print &amp;quot;Replace ESC with \\033 in bash.&amp;quot;&lt;br /&gt;
print&lt;br /&gt;
print &amp;quot;Background | Foreground colors&amp;quot;&lt;br /&gt;
print &amp;quot;---------------------------------------------------------------------&amp;quot;&lt;br /&gt;
for bg in range(40, 47+1):&lt;br /&gt;
  for bold in range(0, 1+1):&lt;br /&gt;
                sys.stdout.write(&amp;quot;\033[0m&amp;quot;&amp;quot; ESC[{bg}m   | &amp;quot;.format(bg=bg))&lt;br /&gt;
                for fg in range(30, 37+1):&lt;br /&gt;
                        if bold == 0:&lt;br /&gt;
                                sys.stdout.write(&amp;quot;\033[{bg}m\033[{fg}m [{fg}m  &amp;quot;.format(bg=bg, fg=fg))&lt;br /&gt;
                        else:&lt;br /&gt;
                                sys.stdout.write(&amp;quot;\033[{bg}m\033[1;{fg}m [1;{fg}m&amp;quot;.format(bg=bg, fg=fg))&lt;br /&gt;
                sys.stdout.write(&amp;quot;\033[0m\n&amp;quot;)&lt;br /&gt;
  print &amp;quot;--------------------------------------------------------------------- &amp;quot;&lt;br /&gt;
&lt;br /&gt;
print&lt;br /&gt;
print&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Execute External Application ===&lt;br /&gt;
&lt;br /&gt;
Execute program: (and send output to STDOUT)&lt;br /&gt;
 encoded_wait_code = os.system(&#039;mkdir mydir&#039;)  # output sent to STDOUT&lt;br /&gt;
&lt;br /&gt;
Get output and ugly return code: (STDERR goes to STDOUT)&lt;br /&gt;
 p = os.popen(cmd)&lt;br /&gt;
 print p.readlines()&lt;br /&gt;
 encoded_wait_code = p.close()&lt;br /&gt;
&lt;br /&gt;
Execute other python script&lt;br /&gt;
 import sys&lt;br /&gt;
 sys.argv = [, &#039;my&#039;, &#039;args&#039;, &#039;here&#039;]&lt;br /&gt;
 execfile(&#039;myscript.py&#039;)  # does not support arguments directly&lt;br /&gt;
&lt;br /&gt;
Subprocess:&lt;br /&gt;
* See [[#Subprocess]]&lt;br /&gt;
&lt;br /&gt;
=== Program Layout ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
PackageName/&lt;br /&gt;
    README&lt;br /&gt;
    setup.py&lt;br /&gt;
    bin/&lt;br /&gt;
        script&lt;br /&gt;
    docs/&lt;br /&gt;
    test/  # some include in package_name&lt;br /&gt;
    pacakgename/&lt;br /&gt;
        __init__.py&lt;br /&gt;
        code1.py&lt;br /&gt;
        subpackage/&lt;br /&gt;
            __init__.py&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== __init__.py ===&lt;br /&gt;
&lt;br /&gt;
Purpose: Makes the folder into a package library&lt;br /&gt;
&lt;br /&gt;
NOTE: This file is most commonly blank&lt;br /&gt;
&lt;br /&gt;
Good place to put your package functions.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# ken/__init__.py&lt;br /&gt;
def load():&lt;br /&gt;
  ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import ken&lt;br /&gt;
ken.load()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Can import other modules to then use as package modules:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# ken/__init__.py&lt;br /&gt;
from ken.client import Server&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import ken&lt;br /&gt;
ken.Server()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Good place to put your Exceptions.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class MyException(Exception):&lt;br /&gt;
  &amp;quot;&amp;quot;&amp;quot; My Error Exception &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use the __all__ to specify what gets imported on &#039;from package import *&#039;&lt;br /&gt;
  __all__ = [&#039;func1&#039;, &#039;func2&#039;]&lt;br /&gt;
&lt;br /&gt;
=== Metadata ===&lt;br /&gt;
&lt;br /&gt;
 VERSION = (0, 2, 1)&lt;br /&gt;
or&lt;br /&gt;
 __version__ = &#039;0.2.1&#039;&lt;br /&gt;
&lt;br /&gt;
Also See [[#pydoc]]&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
 __version__ = &#039;1.10&#039;&lt;br /&gt;
 __author__ = &#039;Joshua Roesslein&#039;&lt;br /&gt;
 __license__ = &#039;MIT&#039;&lt;br /&gt;
&lt;br /&gt;
=== setup.py ===&lt;br /&gt;
&lt;br /&gt;
See [[#Distributing Python Modules with Distutils]]&lt;br /&gt;
&lt;br /&gt;
=== Distributing Python Modules with Distutils ===&lt;br /&gt;
&lt;br /&gt;
Distributing Python Modules — http://docs.python.org/distutils/index.html&lt;br /&gt;
&lt;br /&gt;
Uses setup.py for package installation.&lt;br /&gt;
 python setup.py install&lt;br /&gt;
&lt;br /&gt;
==== Simple example ====&lt;br /&gt;
&lt;br /&gt;
To install foo.py:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from distutils.core import setup&lt;br /&gt;
setup(name=&#039;foo&#039;,&lt;br /&gt;
      version=&#039;1.0&#039;,&lt;br /&gt;
      py_modules=[&#039;foo&#039;],&lt;br /&gt;
      )&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Source: http://docs.python.org/distutils/introduction.html&lt;br /&gt;
&lt;br /&gt;
==== klib example ====&lt;br /&gt;
&lt;br /&gt;
klib setup.py:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from distutils.core import setup&lt;br /&gt;
&lt;br /&gt;
setup(name = &amp;quot;klib&amp;quot;,&lt;br /&gt;
    version = &amp;quot;101&amp;quot;,&lt;br /&gt;
    description = &amp;quot;klib library&amp;quot;,&lt;br /&gt;
    url = &amp;quot;http://www.oeey.com/klib&amp;quot;,&lt;br /&gt;
    author = &amp;quot;Kenneth&amp;quot;,&lt;br /&gt;
    author_email = &amp;quot;kenneth@oeey.com&amp;quot;,&lt;br /&gt;
    license = &amp;quot;Kenneth License&amp;quot;,&lt;br /&gt;
    long_description = &amp;quot;&amp;quot;&amp;quot;Really long text here.&amp;quot;&amp;quot;&amp;quot;,&lt;br /&gt;
    platforms = &amp;quot;Any Platform&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
    packages = [&#039;klib&#039;,&#039;klib.messenger&#039;],&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Installed to:&lt;br /&gt;
 /opt/python26/lib/python2.6/site-packages/klib/&lt;br /&gt;
 /opt/python26/lib/python2.6/site-packages/klib-100-py2.6.egg-info&lt;br /&gt;
&lt;br /&gt;
Metadata: (/opt/python26/lib/python2.6/site-packages/klib-101-py2.6.egg-info)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Metadata-Version: 1.0&lt;br /&gt;
Name: klib&lt;br /&gt;
Version: 101&lt;br /&gt;
Summary: klib library&lt;br /&gt;
Home-page: http://www.oeey.com/klib&lt;br /&gt;
Author: Kenneth&lt;br /&gt;
Author-email: kenneth@oeey.com&lt;br /&gt;
License: Kenneth License&lt;br /&gt;
Description: Really long text here.&lt;br /&gt;
Platform: Any platform&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Any fields not included will be marked:&lt;br /&gt;
 Platform: UNKNOWN&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* 2. Writing the Setup Script — Python v2.7.2 documentation - http://docs.python.org/distutils/setupscript.html&lt;br /&gt;
* http://wiki.python.org/moin/Distutils/Tutorial&lt;br /&gt;
&lt;br /&gt;
==== Uninstall Package ====&lt;br /&gt;
&lt;br /&gt;
Collect files during install:&lt;br /&gt;
 python setup.py install --record install-record.txt&lt;br /&gt;
 sudo rm $(cat install-record.txt)&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* installation - python setup.py uninstall - Stack Overflow - http://stackoverflow.com/questions/1550226/python-setup-py-uninstall&lt;br /&gt;
&lt;br /&gt;
=== Distributing Python Modules with Setuptools ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
import setuptools&lt;br /&gt;
&lt;br /&gt;
setuptools.setup(name=&amp;quot;tweepy&amp;quot;,&lt;br /&gt;
      version=&amp;quot;1.10&amp;quot;,&lt;br /&gt;
      description=&amp;quot;Twitter library for python&amp;quot;,&lt;br /&gt;
      license=&amp;quot;MIT&amp;quot;,&lt;br /&gt;
      author=&amp;quot;Joshua Roesslein&amp;quot;,&lt;br /&gt;
      author_email=&amp;quot;tweepy@googlegroups.com&amp;quot;,&lt;br /&gt;
      url=&amp;quot;http://github.com/tweepy/tweepy&amp;quot;,&lt;br /&gt;
      packages = setuptools.find_packages(),&lt;br /&gt;
      keywords= &amp;quot;twitter library&amp;quot;,&lt;br /&gt;
      zip_safe = True)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Decorators ===&lt;br /&gt;
&lt;br /&gt;
Decorators wrap functions&lt;br /&gt;
&lt;br /&gt;
Function Counter: [http://stackoverflow.com/questions/739654/understanding-python-decorators]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def fcount(func):&lt;br /&gt;
    def wrapper(*args, **kw):&lt;br /&gt;
        wrapper.count = wrapper.count + 1&lt;br /&gt;
        return func(*args, **kw)&lt;br /&gt;
    wrapper.count = 0&lt;br /&gt;
    return wrapper&lt;br /&gt;
&lt;br /&gt;
@fcount&lt;br /&gt;
def f(n):&lt;br /&gt;
    return n*n&lt;br /&gt;
&lt;br /&gt;
print &amp;quot;f.count = &amp;quot;, f.count&lt;br /&gt;
print &amp;quot;f(10) = &amp;quot;, f(10)&lt;br /&gt;
print &amp;quot;f.count = &amp;quot;, f.count&lt;br /&gt;
print &amp;quot;f(3) = &amp;quot;, f(3)&lt;br /&gt;
print &amp;quot;f.count = &amp;quot;, f.count&lt;br /&gt;
print &amp;quot;f(12) = &amp;quot;, f(12)&lt;br /&gt;
print &amp;quot;f.count = &amp;quot;, f.count&lt;br /&gt;
print &amp;quot;f(15) = &amp;quot;, f(15)&lt;br /&gt;
print &amp;quot;f.count = &amp;quot;, f.count&lt;br /&gt;
&lt;br /&gt;
# Output:&lt;br /&gt;
# f.count =  0&lt;br /&gt;
# f(10) =  100&lt;br /&gt;
# f.count =  1&lt;br /&gt;
# f(3) =  9&lt;br /&gt;
# f.count =  2&lt;br /&gt;
# f(12) =  144&lt;br /&gt;
# f.count =  3&lt;br /&gt;
# f(15) =  225&lt;br /&gt;
# f.count =  4&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Great reference: Understanding Python decorators - Stack Overflow - http://stackoverflow.com/questions/739654/understanding-python-decorators&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Example 1:&lt;br /&gt;
 @dec1&lt;br /&gt;
 def func(arg1, arg2, ...): pass&lt;br /&gt;
&lt;br /&gt;
 # equivalent to:&lt;br /&gt;
 def func(arg1, arg2, ...): pass&lt;br /&gt;
 func = dec1(func)&lt;br /&gt;
&lt;br /&gt;
Example 2:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
@dec2&lt;br /&gt;
@dec1&lt;br /&gt;
def func(arg1, arg2, ...):&lt;br /&gt;
    pass&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# equivalent to:&lt;br /&gt;
def func(arg1, arg2, ...):&lt;br /&gt;
    pass&lt;br /&gt;
func = dec2(dec1(func))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example 3:&lt;br /&gt;
 @decomaker(argA, argB, ...)&lt;br /&gt;
 def func(arg1, arg2, ...):&lt;br /&gt;
     pass&lt;br /&gt;
&lt;br /&gt;
 # equivalent to:&lt;br /&gt;
 func = decomaker(argA, argB, ...)(func)&lt;br /&gt;
&lt;br /&gt;
 # example:&lt;br /&gt;
 @accepts(int,int)&lt;br /&gt;
 @returns(float)&lt;br /&gt;
 def bar(low,high):&lt;br /&gt;
     pass&lt;br /&gt;
&lt;br /&gt;
Example 4: (overrides and ignores passed in function - bad, unless desired)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def spamrun(fn):&lt;br /&gt;
    def sayspam(*args):&lt;br /&gt;
        print &amp;quot;spam, spam, spam&amp;quot;&lt;br /&gt;
    return sayspam&lt;br /&gt;
&lt;br /&gt;
@spamrun&lt;br /&gt;
def useful(a, b):&lt;br /&gt;
    print a**2 + b**2&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example 5: (Decorator that modifies behavior of undecorated func)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def addspam(fn):&lt;br /&gt;
    def new(*args):&lt;br /&gt;
        print &amp;quot;spam, spam, spam&amp;quot;&lt;br /&gt;
        return fn(*args)&lt;br /&gt;
    return new&lt;br /&gt;
&lt;br /&gt;
@addspam&lt;br /&gt;
def useful(a, b):&lt;br /&gt;
    print a**2 + b**2&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
My Example 1: (print args and continue to function)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def showargs(fn):&lt;br /&gt;
    def doshowargs(*args, **kw):&lt;br /&gt;
        print &amp;quot;Args for:&amp;quot;, fn.__name__, args, kw&lt;br /&gt;
        return fn(*args, **kw)&lt;br /&gt;
    return doshowargs&lt;br /&gt;
&lt;br /&gt;
@showargs&lt;br /&gt;
def useful(a, b):&lt;br /&gt;
    print a**2 + b**2&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Another Example: [http://stackoverflow.com/questions/739654/understanding-python-decorators]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def makebold(fn):&lt;br /&gt;
    def wrapped(*args, **kw):&lt;br /&gt;
        return &amp;quot;&amp;lt;b&amp;gt;&amp;quot; + fn(*args, **kw) + &amp;quot;&amp;lt;/b&amp;gt;&amp;quot;&lt;br /&gt;
    return wrapped&lt;br /&gt;
&lt;br /&gt;
def makeitalic(fn):&lt;br /&gt;
    def wrapped(*args, **kw):&lt;br /&gt;
        return &amp;quot;&amp;lt;i&amp;gt;&amp;quot; + fn(*args, **kw) + &amp;quot;&amp;lt;/i&amp;gt;&amp;quot;&lt;br /&gt;
    return wrapped&lt;br /&gt;
&lt;br /&gt;
@makebold&lt;br /&gt;
@makeitalic&lt;br /&gt;
def hello(msg):&lt;br /&gt;
    return msg&lt;br /&gt;
&lt;br /&gt;
print hello(&amp;quot;hello world&amp;quot;)&lt;br /&gt;
# output: &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;hello world&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* PEP 318 -- Decorators for Functions and Methods - http://www.python.org/dev/peps/pep-0318/&lt;br /&gt;
* Charming Python: Decorators make magic easy - http://www.ibm.com/developerworks/linux/library/l-cpdecor/index.html&lt;br /&gt;
* What are some common uses for Python decorators? - Stack Overflow - http://stackoverflow.com/questions/489720/what-are-some-common-uses-for-python-decorators&lt;br /&gt;
* Understanding Python decorators - Stack Overflow - http://stackoverflow.com/questions/739654/understanding-python-decorators&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
Utah Python July 2013 Meeting - Decorator Examples: [https://www.youtube.com/watch?v=uh9uhzitdvw]&lt;br /&gt;
&lt;br /&gt;
Example of uses:&lt;br /&gt;
* Count function calls&lt;br /&gt;
* Add additional output (debugging)&lt;br /&gt;
* Timing code&lt;br /&gt;
* Thread synchronization (locks)&lt;br /&gt;
* Type checking&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
## Simple wrapping call&lt;br /&gt;
def shout(f):&lt;br /&gt;
    def wrapper(*args):&lt;br /&gt;
        print(&#039;This is before {name}&#039;.format(name=f.__name__))&lt;br /&gt;
        ret = f(*args)&lt;br /&gt;
        print(&#039;This is after {name}&#039;.format(name=f.__name__))&lt;br /&gt;
        return ret&lt;br /&gt;
    wrapper.__name__ = f.__name__&lt;br /&gt;
    return wrapper&lt;br /&gt;
&lt;br /&gt;
@shout&lt;br /&gt;
def echo(text):&lt;br /&gt;
    print(text)&lt;br /&gt;
&lt;br /&gt;
echo(&#039;this is a test&#039;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
## Counting function calls&lt;br /&gt;
def count(f):&lt;br /&gt;
    def wrapper(*args):&lt;br /&gt;
        wrapper.counter += 1&lt;br /&gt;
        print(&amp;quot;Function called {count} times&amp;quot;.format(count=wrapper.counter))&lt;br /&gt;
        return f(*args)&lt;br /&gt;
    wrapper.counter = 0&lt;br /&gt;
    # change wrapper name, or it will just be &#039;wrapper&#039; (for inspection)&lt;br /&gt;
    wrapper.__name__ = f.__name__&lt;br /&gt;
    return wrapper&lt;br /&gt;
&lt;br /&gt;
@count&lt;br /&gt;
def donothing():&lt;br /&gt;
    pass&lt;br /&gt;
&lt;br /&gt;
donothing()&lt;br /&gt;
donothing()&lt;br /&gt;
print(&amp;quot;Function called a total of {count} times&amp;quot;.format(count=donothing.counter))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
## Timing your code&lt;br /&gt;
import time&lt;br /&gt;
&lt;br /&gt;
def timer(f):&lt;br /&gt;
    def wrapper(*arg):&lt;br /&gt;
        t = time.time()&lt;br /&gt;
        ret = f(*arg)&lt;br /&gt;
        print(&amp;quot;Took {elapsedtime} seconds&amp;quot;.format(elapsedtime=time.time()-t))&lt;br /&gt;
        return ret&lt;br /&gt;
    return wrapper&lt;br /&gt;
&lt;br /&gt;
@timer&lt;br /&gt;
def fact(n):&lt;br /&gt;
    prod = 1&lt;br /&gt;
    while n &amp;gt; 0:&lt;br /&gt;
        prod *= n&lt;br /&gt;
        n -= 1&lt;br /&gt;
    return prod&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
total = fact(10000)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
## Synchronization&lt;br /&gt;
import threading&lt;br /&gt;
&lt;br /&gt;
def synchronized(lock):&lt;br /&gt;
    def wrap(f):&lt;br /&gt;
        def wrapper(*args, **kwargs):&lt;br /&gt;
            lock.acquire()&lt;br /&gt;
            try:&lt;br /&gt;
                return f(*args, **kwargs)&lt;br /&gt;
            finally:&lt;br /&gt;
                lock.release()&lt;br /&gt;
        return wrapper&lt;br /&gt;
    return wrap&lt;br /&gt;
&lt;br /&gt;
mylock = threading.Lock()&lt;br /&gt;
&lt;br /&gt;
@synchronized(mylock)&lt;br /&gt;
def myfunc():&lt;br /&gt;
    pass&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
## Type checking&lt;br /&gt;
def myMethod(ID, name):&lt;br /&gt;
    &#039;&#039;&#039; Old way &#039;&#039;&#039;&lt;br /&gt;
    if not (isinstance(ID, &#039;uint&#039;) and isinstance(name, &#039;utf8string&#039;)):&lt;br /&gt;
        raise Exception()&lt;br /&gt;
&lt;br /&gt;
def accepts(*typeargs):&lt;br /&gt;
    &#039;&#039;&#039; Decorator way &#039;&#039;&#039;&lt;br /&gt;
    def wrap(f):&lt;br /&gt;
        def wrapper(*args):&lt;br /&gt;
            for a, t in zip(args, typeargs):&lt;br /&gt;
                if not isinstance(a, t):&lt;br /&gt;
                    raise Exception(&#039;{a} not of type {t}&#039;.format(a=a, t=t))&lt;br /&gt;
            return f(*args)&lt;br /&gt;
        return wrapper&lt;br /&gt;
    return wrap&lt;br /&gt;
&lt;br /&gt;
@accepts(int)&lt;br /&gt;
def add1(n):&lt;br /&gt;
    return n + 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
## Memoize&lt;br /&gt;
def memoize(f):&lt;br /&gt;
    def wrapper(*args):&lt;br /&gt;
        if not wrapper.ret:&lt;br /&gt;
            wrapper.ret = f(*args)&lt;br /&gt;
        return wrapper.ret&lt;br /&gt;
    wrapper.ret = False&lt;br /&gt;
    wrapper.__name__ = f.__name__&lt;br /&gt;
    return wrapper&lt;br /&gt;
&lt;br /&gt;
import time&lt;br /&gt;
&lt;br /&gt;
@memoize&lt;br /&gt;
def sumto10():&lt;br /&gt;
    count = 0&lt;br /&gt;
    sum = 0&lt;br /&gt;
    while count &amp;lt; 10:&lt;br /&gt;
        sum += count&lt;br /&gt;
        time.sleep(1)&lt;br /&gt;
        count += 1&lt;br /&gt;
    return sum&lt;br /&gt;
&lt;br /&gt;
# first time will count slow&lt;br /&gt;
print sumto10()&lt;br /&gt;
# second time will return cached value instantly&lt;br /&gt;
print sumto10()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Memoize: &amp;quot;Caches a function&#039;s return value each time it is called. If called later with the same arguments, the cached value is returned (not reevaluated)&amp;quot; [http://wiki.python.org/moin/PythonDecoratorLibrary#Memoize]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
## Nested decorators&lt;br /&gt;
import time&lt;br /&gt;
@shout&lt;br /&gt;
@memoize&lt;br /&gt;
def test1():&lt;br /&gt;
  print &amp;quot;calculating&amp;quot;&lt;br /&gt;
  time.sleep(3)&lt;br /&gt;
  return 100&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Order is important!  For tested decorators the execution order is from the top to the bottom.  If you reverse @shout and @memoize, the @shout will not run because of the way @memoize was written.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
## registry&lt;br /&gt;
registry = []&lt;br /&gt;
# can also decorate decorators:&lt;br /&gt;
@shout&lt;br /&gt;
def registry(f):&lt;br /&gt;
    registry.append(f)&lt;br /&gt;
    return f&lt;br /&gt;
&lt;br /&gt;
@register&lt;br /&gt;
def test2():&lt;br /&gt;
    pass&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Decorator is just a function that returns a function.&lt;br /&gt;
&lt;br /&gt;
Can use functools to automatically update decorator wrappers with __name__, etc [http://docs.python.org/2/library/functools.html]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
## Auto syntax sygar the wrapper for you&lt;br /&gt;
import functools&lt;br /&gt;
def my_decorator(f):&lt;br /&gt;
    @functools.wraps(f)&lt;br /&gt;
    def wrapper(*args, **kwds):&lt;br /&gt;
        print &#039;Calling decorated function&#039;&lt;br /&gt;
        return f(*args, **kwds)&lt;br /&gt;
    return wrapper&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Class Method Decorators ===&lt;br /&gt;
&lt;br /&gt;
Static methods: [http://docs.python.org/library/functions.html#staticmethod]&lt;br /&gt;
: Similar to C++ and Java static methods&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class C:&lt;br /&gt;
  @staticmethod&lt;br /&gt;
  def say(msg):&lt;br /&gt;
    print(msg)&lt;br /&gt;
&lt;br /&gt;
C.say(&#039;hi&#039;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Class method: [http://docs.python.org/library/functions.html#classmethod]&lt;br /&gt;
: A class method receives the class as implicit first argument, just like an instance method receives the instance.&lt;br /&gt;
: Class methods are different than C++ or Java static methods. If you want those, see staticmethod() in this section.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    @classmethod&lt;br /&gt;
    def setup_parser(cls, parser):&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See also [[#Class Properties]]&lt;br /&gt;
&lt;br /&gt;
=== Class Properties ===&lt;br /&gt;
&lt;br /&gt;
Properties: (not using decorators)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class C(object):&lt;br /&gt;
    def __init__(self):&lt;br /&gt;
        self._x = None&lt;br /&gt;
    def getx(self):&lt;br /&gt;
        print(&amp;quot;get x&amp;quot;)&lt;br /&gt;
        return self._x&lt;br /&gt;
    def setx(self, value):&lt;br /&gt;
        print(&amp;quot;set x&amp;quot;)&lt;br /&gt;
        self._x = value&lt;br /&gt;
    def delx(self):&lt;br /&gt;
        print(&amp;quot;del x&amp;quot;)&lt;br /&gt;
        del self._x&lt;br /&gt;
    x = property(getx, setx, delx, &amp;quot;I&#039;m the &#039;x&#039; property.&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#usage&lt;br /&gt;
c = C()&lt;br /&gt;
c.x = 5&lt;br /&gt;
print(c.x)&lt;br /&gt;
del(c.x)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Getter and Setter Property Decorators: [http://docs.python.org/library/functions.html#property]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class C(object):    # make sure to inherit from object for these properties to work!&lt;br /&gt;
    def __init__(self):&lt;br /&gt;
        self._x = None&lt;br /&gt;
    &lt;br /&gt;
    @property&lt;br /&gt;
    def x(self):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;I&#039;m the &#039;x&#039; property.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        print(&amp;quot;get x&amp;quot;)&lt;br /&gt;
        return self._x&lt;br /&gt;
    &lt;br /&gt;
    @x.setter   # python &amp;gt;= 2.6&lt;br /&gt;
    def x(self, value):&lt;br /&gt;
        print(&amp;quot;set x&amp;quot;)&lt;br /&gt;
        self._x = value&lt;br /&gt;
    &lt;br /&gt;
    @x.deleter  # python &amp;gt;= 2.6&lt;br /&gt;
    def x(self):&lt;br /&gt;
        print(&amp;quot;del x&amp;quot;)&lt;br /&gt;
        del self._x&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#usage&lt;br /&gt;
c = C()&lt;br /&gt;
c.x = 5&lt;br /&gt;
print(c.x)&lt;br /&gt;
del(c.x)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: If you don&#039;t add the @x.setter, the property will be read only, and will throw a &amp;quot;AttributeError: can&#039;t set attribute&amp;quot; if attempted to be set.&lt;br /&gt;
&lt;br /&gt;
Using x.getter example: [http://wiki.python.org/moin/AlternativeDescriptionOfProperty]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Cls(object):&lt;br /&gt;
    def __init__(self):&lt;br /&gt;
        self._x = 100&lt;br /&gt;
&lt;br /&gt;
    x = property()&lt;br /&gt;
&lt;br /&gt;
    @x.getter&lt;br /&gt;
    def x(self):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;I&#039;m the &#039;x&#039; property.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        return self._x&lt;br /&gt;
&lt;br /&gt;
    @x.setter&lt;br /&gt;
    def x(self, value):&lt;br /&gt;
        self._x = value&lt;br /&gt;
&lt;br /&gt;
    @x.deleter&lt;br /&gt;
    def x(self):&lt;br /&gt;
        del self._x&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Custom Decorators ===&lt;br /&gt;
&lt;br /&gt;
decorator&lt;br /&gt;
 @dec1&lt;br /&gt;
 def func(arg1, arg2, ...): pass&lt;br /&gt;
&lt;br /&gt;
equivalent to:&lt;br /&gt;
 def func(arg1, arg2, ...): pass&lt;br /&gt;
 func = dec1(func)&lt;br /&gt;
&lt;br /&gt;
Basic layout (names are arbitrary):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def my_decorator(function_name):&lt;br /&gt;
  # update wrapper.__doc__ and .func_name&lt;br /&gt;
  # or @functools.wraps(my_wrapper)&lt;br /&gt;
  def mywrapper(*args, **kw):&lt;br /&gt;
    # do something before&lt;br /&gt;
    result = function_name(*args, **kw)&lt;br /&gt;
    # do something after&lt;br /&gt;
    return result&lt;br /&gt;
  return my_wrapper&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def limit(length):&lt;br /&gt;
  def decorator(function):&lt;br /&gt;
    def wrapper(*args, **kw):&lt;br /&gt;
      result = function(*args, **kw)&lt;br /&gt;
      result = result[:length]&lt;br /&gt;
      return result&lt;br /&gt;
    return wrapper&lt;br /&gt;
  return decorator&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
@limit(3)&lt;br /&gt;
def echo(foo):  return foo&lt;br /&gt;
&lt;br /&gt;
echo(&#039;123456&#039;)  # &#039;123&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== assert ===&lt;br /&gt;
&lt;br /&gt;
 assert True&lt;br /&gt;
 assert False  # exception&lt;br /&gt;
 assert 1 == 1&lt;br /&gt;
 assert 1 == 2, &amp;quot;some message&amp;quot;  # AssertionError: some message&lt;br /&gt;
&lt;br /&gt;
=== Snake Case ===&lt;br /&gt;
&lt;br /&gt;
Convert Camel Case to Snake Case: [http://stackoverflow.com/questions/1175208/elegant-python-function-to-convert-camelcase-to-snake-case]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def snake_case(name):&lt;br /&gt;
    s1 = re.sub(&#039;(.)([A-Z][a-z]+)&#039;, r&#039;\1_\2&#039;, name)&lt;br /&gt;
    return re.sub(&#039;([a-z0-9])([A-Z])&#039;, r&#039;\1_\2&#039;, s1).lower()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; convert(&#039;CamelCase&#039;)&lt;br /&gt;
&#039;camel_case&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Camel Case ===&lt;br /&gt;
&lt;br /&gt;
Camel Case: [http://stackoverflow.com/questions/8347048/camelcase-every-string-any-standard-library]&lt;br /&gt;
&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; &#039;&#039;.join(x for x in &#039;make IT camel CaSe&#039;.title() if not x.isspace())&lt;br /&gt;
 &#039;MakeItCamelCase&#039;&lt;br /&gt;
&lt;br /&gt;
To titleize a sentence:&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; &amp;quot;this is a test&amp;quot;.title()&lt;br /&gt;
 &amp;quot;This Is A Test&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Lambda ===&lt;br /&gt;
&lt;br /&gt;
Simple functions&lt;br /&gt;
 mul = lambda a, b: a * b&lt;br /&gt;
&lt;br /&gt;
 # equivalent to:&lt;br /&gt;
 def mul(a, b):&lt;br /&gt;
   return a * b&lt;br /&gt;
&lt;br /&gt;
Sort usage:&lt;br /&gt;
 data = [dict(number=x) for x in &#039;036149&#039;]&lt;br /&gt;
 data.sort(key=lambda x: float(x[&#039;number&#039;]))&lt;br /&gt;
&lt;br /&gt;
Compare usage:&lt;br /&gt;
 data = [dict(number=x) for x in &#039;036149&#039;]&lt;br /&gt;
 data.sort(cmp=lambda x,y: cmp(x[&#039;number&#039;], y[&#039;number&#039;]))&lt;br /&gt;
&lt;br /&gt;
Boolean:&lt;br /&gt;
 lambda x: x % 3 == 0&lt;br /&gt;
&lt;br /&gt;
Multiple parameter:&lt;br /&gt;
 lambda x, y: x + y&lt;br /&gt;
&lt;br /&gt;
Call another function:&lt;br /&gt;
 lambda word: len(word)&lt;br /&gt;
&lt;br /&gt;
Strings:&lt;br /&gt;
 lambda line: line.split()[2]&lt;br /&gt;
&lt;br /&gt;
Embedded:&lt;br /&gt;
 def transform(n):&lt;br /&gt;
    return lambda x: x + n&lt;br /&gt;
&lt;br /&gt;
No parameters:&lt;br /&gt;
 lambda: 1&lt;br /&gt;
&lt;br /&gt;
Default parameters:&lt;br /&gt;
 lambda x=1: x+1&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* Python: Lambda Functions - http://www.secnetix.de/olli/Python/lambda_functions.hawk&lt;br /&gt;
&lt;br /&gt;
=== Map ===&lt;br /&gt;
&lt;br /&gt;
Apply a function to items of a sequence:&lt;br /&gt;
 map(str, range(3))   # [&#039;0&#039;, &#039;1&#039;, &#039;2&#039;]&lt;br /&gt;
&lt;br /&gt;
Note: list comprehensions can replace map and filter&lt;br /&gt;
&lt;br /&gt;
=== Reduce ===&lt;br /&gt;
&lt;br /&gt;
Apply a function to pairs of the sequence:&lt;br /&gt;
 import operator&lt;br /&gt;
 reduce(operator.mul, [1,2,3,4])   # 24   - ((1*2)*3)*4)&lt;br /&gt;
&lt;br /&gt;
Note: sum or for loop can replace reduce&lt;br /&gt;
&lt;br /&gt;
=== Filter ===&lt;br /&gt;
&lt;br /&gt;
Return a sequence of items for which function(item) is True&lt;br /&gt;
 filter(lambda x: x &amp;gt;= 0, [0, -1, 3])  # [0, 3]&lt;br /&gt;
&lt;br /&gt;
Note: list comprehensions can replace map and filter&lt;br /&gt;
&lt;br /&gt;
Find matching items in two lists:&lt;br /&gt;
 a = [&#039;a&#039;,&#039;b&#039;,&#039;c&#039;]&lt;br /&gt;
 b = [&#039;c&#039;,&#039;d&#039;]&lt;br /&gt;
 filter(lambda x: x in a, b)  # returns only &#039;c&#039; as it is in both lists&lt;br /&gt;
&lt;br /&gt;
=== List comprehension ===&lt;br /&gt;
&lt;br /&gt;
Nothing more than Syntactic Sugar&lt;br /&gt;
&lt;br /&gt;
5. Data Structures — Python v2.7.5 documentation - http://docs.python.org/2/tutorial/datastructures.html#list-comprehensions&lt;br /&gt;
: &amp;quot;List comprehensions provide a concise way to create lists.&amp;quot;&lt;br /&gt;
: &amp;quot;A list comprehension consists of &#039;&#039;&#039;brackets&#039;&#039;&#039; containing an &#039;&#039;&#039;expression&#039;&#039;&#039; followed by a &#039;&#039;&#039;for clause&#039;&#039;&#039;, then &#039;&#039;&#039;zero or more for or if clauses&#039;&#039;&#039;. &amp;quot;&lt;br /&gt;
&lt;br /&gt;
Remove newlines from each item in a list:&lt;br /&gt;
 mylist = [x.strip() for x in mylist]&lt;br /&gt;
&lt;br /&gt;
Simple:&lt;br /&gt;
 doubled = [x*2 for x in mylist]&lt;br /&gt;
 squares = [x**2 for x in range(10)]&lt;br /&gt;
&lt;br /&gt;
If:&lt;br /&gt;
 [ 2*x for x in range(1,10) if x &amp;gt;= 5 ]&lt;br /&gt;
&lt;br /&gt;
Complex:&lt;br /&gt;
 [(x, y) for x in [1,2,3] for y in [3,1,4] if x != y]&lt;br /&gt;
&lt;br /&gt;
Expanding PI:&lt;br /&gt;
 [str(round(pi, i)) for i in range(1, 6)]&lt;br /&gt;
&lt;br /&gt;
Return list of words&lt;br /&gt;
 my_list = [current_word.lower() for current_word in words]&lt;br /&gt;
&lt;br /&gt;
Utah Python July 2013 Meeting: (http://basepi.net)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Iterative&lt;br /&gt;
squares = []&lt;br /&gt;
for x in range(10):&lt;br /&gt;
    squares.append(x**2)&lt;br /&gt;
# [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]&lt;br /&gt;
&lt;br /&gt;
## Functional&lt;br /&gt;
squares = map(lambda x: x**2, range(10))&lt;br /&gt;
&lt;br /&gt;
## List comprehension&lt;br /&gt;
squares = [x**2 for x in range(10)]&lt;br /&gt;
even_squares = [x**2 for x in range(10) if x%2 == 0]&lt;br /&gt;
&lt;br /&gt;
# get hash of strings in list:&lt;br /&gt;
import sha&lt;br /&gt;
strings = [&#039;Python is cool!&#039;, &#039;I love python&#039;]&lt;br /&gt;
hashes = [sha.sha(x).digest() for x in strings]&lt;br /&gt;
&lt;br /&gt;
# flatten matrix:&lt;br /&gt;
matrix = [[1, 2, 3], [4, 5, 6]]&lt;br /&gt;
[x for row in matrix for x in row]&lt;br /&gt;
# [1, 2, 3, 4, 5, 6]&lt;br /&gt;
&lt;br /&gt;
# build matrix:&lt;br /&gt;
[(x,y) for x in range(10) for y in range(10)]&lt;br /&gt;
# matrix of not both odd and not both even&lt;br /&gt;
[(x,y) for x in range(10) for y in range(10) if x%2 != y%2]&lt;br /&gt;
&lt;br /&gt;
# suck lines of files into list, ignoring commented lines&lt;br /&gt;
[line.strip().split(&amp;quot;\t&amp;quot;) for line in open(&amp;quot;my_file.tab&amp;quot;)&lt;br /&gt;
    if not line.startswith(&#039;#&#039;)]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* 5.1.4. List Comprehensions - Data Structures — Python v2.7.2 documentation - http://docs.python.org/tutorial/datastructures.html#list-comprehensions&lt;br /&gt;
* Utah Python July 2013 Meeting - YouTube - https://www.youtube.com/watch?v=uh9uhzitdvw [http://basepi.net]&lt;br /&gt;
&lt;br /&gt;
=== [http://docs.python.org/reference/expressions#calls Mass Parameter Passing] ===&lt;br /&gt;
&lt;br /&gt;
Using: *args and **kw&lt;br /&gt;
* *args a tuple of remaining unnamed parameters&lt;br /&gt;
* **kw a dictionary of remaining named parameters&lt;br /&gt;
&lt;br /&gt;
 def param_func(a, b=&#039;b&#039;, *args, **kw):&lt;br /&gt;
   print( [a, b, args, kw] )&lt;br /&gt;
&lt;br /&gt;
WARNING: If not careful, this can result in this error: &amp;quot;TypeError: param_func() got multiple values for keyword argument &#039;myvar&#039;&amp;quot;.  Might be better to just use:&lt;br /&gt;
&lt;br /&gt;
 def param_func(*args, **kw):&lt;br /&gt;
   print( [args, kw] )&lt;br /&gt;
&lt;br /&gt;
 param_func(1, 2, 3, 4, 5)  # [1, 2, (3, 4, 5), {}]&lt;br /&gt;
 param_func(1, 2, 3, 4, 5, joe=&#039;test&#039;)  # [1, 2, (3, 4, 5), {&#039;joe&#039;: &#039;test&#039;}]&lt;br /&gt;
 mylist = (&amp;quot;a&amp;quot;, &amp;quot;c&amp;quot;, &amp;quot;g&amp;quot;, &amp;quot;h&amp;quot;, 5)&lt;br /&gt;
 param_func(mylist)  # [(&#039;a&#039;, &#039;c&#039;, &#039;g&#039;, &#039;h&#039;, 5), &#039;b&#039;, (), {}]&lt;br /&gt;
 param_func(*mylist)  # [&#039;a&#039;, &#039;c&#039;, (&#039;g&#039;, &#039;h&#039;, 5), {}]  *tricky*&lt;br /&gt;
 Note: *mydict will strip out just keys and treat like list&lt;br /&gt;
 Note: **mydict will treat like named parameters&lt;br /&gt;
&lt;br /&gt;
 def mywrapper(*args, **kw):&lt;br /&gt;
   # do something before&lt;br /&gt;
   result = function_name(*args, **kw)&lt;br /&gt;
&lt;br /&gt;
Passing arbitrary parameters:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def fun2(**kw):&lt;br /&gt;
  print kw  # {&#039;a&#039;: &#039;1&#039;, &#039;b&#039;: &#039;2&#039;, &#039;c&#039;: &#039;3&#039;}&lt;br /&gt;
&lt;br /&gt;
def fun1(c=&#039;3&#039;, **kw):&lt;br /&gt;
 print kw  # {&#039;a&#039;: &#039;1&#039;, &#039;b&#039;: &#039;2&#039;}&lt;br /&gt;
 fun2(c=&#039;3&#039;, **kw)&lt;br /&gt;
&lt;br /&gt;
fun1(a=&#039;1&#039;, b=&#039;2&#039;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [http://www.python.org/dev/peps/pep-0234/ Iteration Protocol] ===&lt;br /&gt;
&lt;br /&gt;
[http://www.python.org/dev/peps/pep-0234/ PEP 234 -- Iterators]&lt;br /&gt;
&lt;br /&gt;
Making a class iterable:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class mycount(object):&lt;br /&gt;
  def __init__(self, max):&lt;br /&gt;
    self.x = 0&lt;br /&gt;
    self.max = max&lt;br /&gt;
  def __iter__(self):  # return object that implements __next__() or next()&lt;br /&gt;
    return self&lt;br /&gt;
  def next(self):&lt;br /&gt;
    if self.x &amp;lt; self.max:&lt;br /&gt;
      self.x += 1&lt;br /&gt;
      return self.x&lt;br /&gt;
    else:&lt;br /&gt;
      self.x = 0&lt;br /&gt;
      raise StopIteration()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 for i in mycount(10): print i     # 1 ... 10&lt;br /&gt;
 print [x for x in mycount(10) ]   # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]&lt;br /&gt;
&lt;br /&gt;
 c = mycount(10)&lt;br /&gt;
 for i in c: print i    # 1 ... 10&lt;br /&gt;
 [ x for x in c ]       # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]&lt;br /&gt;
&lt;br /&gt;
=== Generators ===&lt;br /&gt;
&lt;br /&gt;
Generators are functions that return to their previous state (using &#039;yield&#039;) when iterated over, which can be used in for loops.&lt;br /&gt;
&lt;br /&gt;
==== Yield ====&lt;br /&gt;
&lt;br /&gt;
Improve on Iterators:&lt;br /&gt;
* Infinite data (infinite iterators)&lt;br /&gt;
* Memory-intensive iteration&lt;br /&gt;
* Cooperative Multi-threading&lt;br /&gt;
&lt;br /&gt;
Generators are functions that return to their previous state when iterated over, which can be used in for loops.&lt;br /&gt;
&lt;br /&gt;
Note: Generators throw StopIteration when completed&lt;br /&gt;
&lt;br /&gt;
Note: the &#039;yield&#039; keyword will stash away the state of the function and return the value. (Continuations)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def gen_range(end):&lt;br /&gt;
  cur = 0&lt;br /&gt;
  while cur &amp;lt; end:&lt;br /&gt;
    yield cur&lt;br /&gt;
    # return here next time&lt;br /&gt;
    cur += 1&lt;br /&gt;
&lt;br /&gt;
# for loop iteration&lt;br /&gt;
for i in gen_range(10):  print i&lt;br /&gt;
&lt;br /&gt;
# manual iteration&lt;br /&gt;
my_gen = gen_range(10)&lt;br /&gt;
try:&lt;br /&gt;
  while True:&lt;br /&gt;
    print my_gen.next()&lt;br /&gt;
except StopIteration:&lt;br /&gt;
  pass&lt;br /&gt;
&lt;br /&gt;
# list comprehension&lt;br /&gt;
numbers = [x for x in gen_range(10)]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: one can place an empty &#039;return&#039; in a generator if needed.  A &#039;return&#039; with argument is invalid.&lt;br /&gt;
&lt;br /&gt;
Making a class generate:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class mycount(object):&lt;br /&gt;
  def __init__(self, max):&lt;br /&gt;
    self.max = max&lt;br /&gt;
  def __iter__(self):&lt;br /&gt;
    return self.next()      # change here&lt;br /&gt;
  def next(self):           # change here&lt;br /&gt;
    x = 0&lt;br /&gt;
    while x &amp;lt; self.max:&lt;br /&gt;
      x += 1&lt;br /&gt;
      yield x&lt;br /&gt;
&lt;br /&gt;
for i in mycount(10): print i     # 1 ... 10&lt;br /&gt;
print [x for x in mycount(10) ]   # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]&lt;br /&gt;
&lt;br /&gt;
c = mycount(10)&lt;br /&gt;
for i in c: print i    # 1 ... 10&lt;br /&gt;
[ x for x in c ]       # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]&lt;br /&gt;
&lt;br /&gt;
itr = mycount(10).next()&lt;br /&gt;
itr.next()  # 1&lt;br /&gt;
itr.next()  # 2  - eventually throws StopIteration exception&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Utah Python July 2013 Meeting: [https://www.youtube.com/watch?v=uh9uhzitdvw] [http://basepi.net]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
* Iterators are used to traverse a list&lt;br /&gt;
* Generators are more powerful Iterators&lt;br /&gt;
&lt;br /&gt;
# simple &#039;n&#039; number in functional form&lt;br /&gt;
def firstn(n):&lt;br /&gt;
    num = 0&lt;br /&gt;
    nums = []&lt;br /&gt;
    while num &amp;lt; n:&lt;br /&gt;
        nums.append(num)&lt;br /&gt;
        num += 1&lt;br /&gt;
    return nums&lt;br /&gt;
&lt;br /&gt;
# simple &#039;n&#039; number in generator form&lt;br /&gt;
def firstn(n):&lt;br /&gt;
    num = 0&lt;br /&gt;
    while num &amp;lt; n:&lt;br /&gt;
        yield num&lt;br /&gt;
        num += 1&lt;br /&gt;
&lt;br /&gt;
-&lt;br /&gt;
&lt;br /&gt;
# Infinite list generator&lt;br /&gt;
def counter():&lt;br /&gt;
    num = 0&lt;br /&gt;
    while True:&lt;br /&gt;
        yield num&lt;br /&gt;
        num += 1&lt;br /&gt;
&lt;br /&gt;
# Fibbonacci generator&lt;br /&gt;
def fib():&lt;br /&gt;
    num1 = 0&lt;br /&gt;
    num2 = 1&lt;br /&gt;
    yield num1&lt;br /&gt;
    while True:&lt;br /&gt;
        num1, num2 = num2, num1 + num2&lt;br /&gt;
        yield num1&lt;br /&gt;
&lt;br /&gt;
# Fibbonacci generator 2&lt;br /&gt;
def fib(n):&lt;br /&gt;
    num1 = 0&lt;br /&gt;
    num2 = 1&lt;br /&gt;
    count = 0&lt;br /&gt;
    yield num1&lt;br /&gt;
    while count &amp;lt; n:&lt;br /&gt;
        count += 1&lt;br /&gt;
        num1, num2 = num2, num1 + num2&lt;br /&gt;
        yield num1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Utah Python July 2013 Meeting: [https://www.youtube.com/watch?v=uh9uhzitdvw] [http://basepi.net]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
## Cooperative Multi-Threading:&lt;br /&gt;
# Cooperative multithreading relies on the threads themselves to relinquish control once they are at a stopping point.&lt;br /&gt;
&lt;br /&gt;
def mythread(name):&lt;br /&gt;
    print(&#039;Starting Thread: {name}...&#039;.format(name=name))&lt;br /&gt;
    counter = 10&lt;br /&gt;
    while counter &amp;gt; 0:&lt;br /&gt;
        print(&#039;Thread: {name} doing some work!&#039;.format(name=name))&lt;br /&gt;
        counter -= 1&lt;br /&gt;
        yield&lt;br /&gt;
&lt;br /&gt;
thread1 = mythread(&#039;Alice&#039;)&lt;br /&gt;
thread2 = mythread(&#039;Bob&#039;)&lt;br /&gt;
thread3 = mythread(&#039;Trudy&#039;)&lt;br /&gt;
&lt;br /&gt;
try:&lt;br /&gt;
    while True:&lt;br /&gt;
        thread1.next()&lt;br /&gt;
        thread2.next()&lt;br /&gt;
        thread3.next()&lt;br /&gt;
except StopIteration:&lt;br /&gt;
    pass&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* Utah Python July 2013 Meeting: [https://www.youtube.com/watch?v=uh9uhzitdvw] [http://basepi.net]&lt;br /&gt;
** http://files.basepi.net/talks/pyarmory.zip&lt;br /&gt;
&lt;br /&gt;
=== dunder methods ===&lt;br /&gt;
&lt;br /&gt;
Some dunder (double under) methods determine what will happen when + (__add__) or other similar numerical symbols used.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class str_add(object):&lt;br /&gt;
    def __init__(self, name):&lt;br /&gt;
        self.name = name&lt;br /&gt;
    def __add__(self, other):&lt;br /&gt;
        self.name += other.name&lt;br /&gt;
        return self&lt;br /&gt;
        # note: only need to return self if you want to go beyond &#039;a + b&#039;&lt;br /&gt;
&lt;br /&gt;
a = str_add(&#039;a_&#039;)&lt;br /&gt;
b = str_add(&#039;b_&#039;)&lt;br /&gt;
c = str_add(&#039;c_&#039;)&lt;br /&gt;
d = a + b + c&lt;br /&gt;
print(a.name)  # a_b_c_&lt;br /&gt;
print(b.name)  # b_&lt;br /&gt;
print(c.name)  # c_&lt;br /&gt;
print(d.name)  # a_b_c_&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Other common methods to override:&lt;br /&gt;
* __add__ for +&lt;br /&gt;
* __sub__ for -&lt;br /&gt;
* __mul__ for *&lt;br /&gt;
* __div__ for /&lt;br /&gt;
* __mod__ for %&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* Emulating numeric types - http://docs.python.org/2/reference/datamodel.html#emulating-numeric-types&lt;br /&gt;
&lt;br /&gt;
=== [http://docs.python.org/library/doctest.html doctest] ===&lt;br /&gt;
&lt;br /&gt;
test.py:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
This is the &amp;quot;example&amp;quot; module.&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; double(5)&lt;br /&gt;
10&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
def double(n):&lt;br /&gt;
  &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  This is double function&lt;br /&gt;
&lt;br /&gt;
  &amp;gt;&amp;gt;&amp;gt; double(3)&lt;br /&gt;
  6&lt;br /&gt;
  &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  return n * 2&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
    import doctest&lt;br /&gt;
    doctest.testmod()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== unittest ===&lt;br /&gt;
&lt;br /&gt;
 unittest.TestCase&lt;br /&gt;
&lt;br /&gt;
Here is a short script to test three functions from the random module:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import random&lt;br /&gt;
import unittest&lt;br /&gt;
&lt;br /&gt;
class TestSequenceFunctions(unittest.TestCase):&lt;br /&gt;
&lt;br /&gt;
    def setUp(self):&lt;br /&gt;
        self.seq = range(10)&lt;br /&gt;
&lt;br /&gt;
    def test_shuffle(self):&lt;br /&gt;
        # make sure the shuffled sequence does not lose any elements&lt;br /&gt;
        random.shuffle(self.seq)&lt;br /&gt;
        self.seq.sort()&lt;br /&gt;
        self.assertEqual(self.seq, range(10))&lt;br /&gt;
&lt;br /&gt;
        # should raise an exception for an immutable sequence&lt;br /&gt;
        self.assertRaises(TypeError, random.shuffle, (1,2,3))&lt;br /&gt;
&lt;br /&gt;
    def test_choice(self):&lt;br /&gt;
        element = random.choice(self.seq)&lt;br /&gt;
        self.assertTrue(element in self.seq)&lt;br /&gt;
&lt;br /&gt;
    def test_sample(self):&lt;br /&gt;
        with self.assertRaises(ValueError):&lt;br /&gt;
            random.sample(self.seq, 20)&lt;br /&gt;
        for element in random.sample(self.seq, 5):&lt;br /&gt;
            self.assertTrue(element in self.seq)&lt;br /&gt;
&lt;br /&gt;
if __name__ == &#039;__main__&#039;:&lt;br /&gt;
    unittest.main()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The unittest module can be used from the command line to run tests from modules, classes or even individual test methods:&lt;br /&gt;
 python -m unittest test_module1 test_module2&lt;br /&gt;
 python -m unittest test_module.TestClass&lt;br /&gt;
 python -m unittest test_module.TestClass.test_method&lt;br /&gt;
 python -m unittest -v test_module  # verbose&lt;br /&gt;
 python -m unittest -h   # help&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* 25.3. unittest — Unit testing framework — Python v2.7.4 documentation - http://docs.python.org/2/library/unittest.html&lt;br /&gt;
* Python Debugging Tips - Google Drive - https://docs.google.com/presentation/d/130Wl--IzbDh9ymF6KHMu0WrsIwz6k32pav1gFbsw7NI/edit?usp=sharing&lt;br /&gt;
&lt;br /&gt;
=== Internet Access ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Python 3&lt;br /&gt;
from urllib.request import urlopen&lt;br /&gt;
for line in urlopen(&#039;http://tycho.usno.navy.mil/cgi-bin/timer.pl&#039;):&lt;br /&gt;
  line = line.decode(&#039;utf-8&#039;)&lt;br /&gt;
  if &#039;EST&#039; in line or &#039;EDT&#039; in line:  # look for eastern time&lt;br /&gt;
    print(line)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Simple SMTP ===&lt;br /&gt;
&lt;br /&gt;
Requires local STMP server.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import smtplib&lt;br /&gt;
server = smtplib.SMTP(&amp;quot;localhost&amp;quot;)&lt;br /&gt;
server.sendmail(&#039;mrken@demo.oeey.com&#039;, &#039;kenneth@demo.oeey.com&#039;,&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;To: kenneth@demo.oeey.com&lt;br /&gt;
From: mrken@demo.oeey.com&lt;br /&gt;
Subject: This is fun&lt;br /&gt;
&lt;br /&gt;
Beware of the dog.&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;)&lt;br /&gt;
server.quit()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
s = smtplib.SMTP(smtp_server)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
with TLS:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
s = smtplib.SMTP(&amp;quot;smtp.gmail.com&amp;quot;,587)&lt;br /&gt;
s.ehlo()&lt;br /&gt;
s.starttls()&lt;br /&gt;
s.ehlo()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
SSL:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
s = smtplib.SMTP_SSL(&#039;smtp.mail.yahoo.com&#039;, 465)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Data Compress ===&lt;br /&gt;
&lt;br /&gt;
zlib, gzip, bz2, zipfile, tarfile&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import zlib&lt;br /&gt;
s = b&#039;hello world&#039;  # only in python &amp;gt;3&lt;br /&gt;
len(s)&lt;br /&gt;
t = zlib.compress(s)&lt;br /&gt;
zlib.decompress(t)&lt;br /&gt;
zlib.crc32(s)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== gzip ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import gzip&lt;br /&gt;
content = &amp;quot;Lots of content here&amp;quot;&lt;br /&gt;
f = gzip.open(&#039;file.txt.gz&#039;, &#039;wb&#039;)&lt;br /&gt;
f.write(content)&lt;br /&gt;
f.close()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import gzip&lt;br /&gt;
f_in = open(&#039;file.txt&#039;, &#039;rb&#039;)&lt;br /&gt;
f_out = gzip.open(&#039;file.txt.gz&#039;, &#039;wb&#039;)&lt;br /&gt;
f_out.writelines(f_in)&lt;br /&gt;
f_out.close()&lt;br /&gt;
f_in.close()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Performance Timer ===&lt;br /&gt;
&lt;br /&gt;
Time a task repeated 10 times:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from timeit import Timer&lt;br /&gt;
Timer(&#039;t=a; a=b; b=t&#039;, &#039;a=1; b=2&#039;).timeit()&lt;br /&gt;
Timer(&#039;print(&amp;quot;hi&amp;quot;)&#039;).timeit(10)  # repeat 10 times and time&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Simple method:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
start_time = int(time.time())&lt;br /&gt;
... task ...&lt;br /&gt;
compute_time = int(time.time()) - start_time&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Python Version Check ===&lt;br /&gt;
&lt;br /&gt;
Solution:&lt;br /&gt;
&lt;br /&gt;
__init__.py:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Check Python Version:&lt;br /&gt;
import sys&lt;br /&gt;
assert sys.version_info &amp;gt;= (2, 6, 0), &#039;requires Python 2.6 or higher&#039;&lt;br /&gt;
del sys&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
resulting error if not &amp;gt; 2.6:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import nucleon&lt;br /&gt;
Traceback (most recent call last):&lt;br /&gt;
  File &amp;quot;&amp;lt;stdin&amp;gt;&amp;quot;, line 1, in ?&lt;br /&gt;
  File &amp;quot;nucleon/__init__.py&amp;quot;, line 9, in ?&lt;br /&gt;
    assert sys.version_info &amp;gt;= (2, 6, 0), &#039;nucleon requires Python 2.6 or higher&#039;&lt;br /&gt;
AssertionError: nucleon requires Python 2.6 or higher&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Other solutions:&lt;br /&gt;
&lt;br /&gt;
Note: this will throw syntax error on 2.4 due to ternary&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import sys&lt;br /&gt;
if sys.version_info &amp;lt; (2, 4):&lt;br /&gt;
    raise &amp;quot;must use python 2.5 or greater&amp;quot;&lt;br /&gt;
else:&lt;br /&gt;
    # syntax error in 2.4, ok in 2.5&lt;br /&gt;
    x = 1 if True else 2&lt;br /&gt;
    print x&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
maybe solution:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
try:&lt;br /&gt;
  eval(&amp;quot;1 if True else 2&amp;quot;)&lt;br /&gt;
except SyntaxError:&lt;br /&gt;
  # doesn&#039;t have ternary&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; try:&lt;br /&gt;
...     from my_module import twoPointSixCode&lt;br /&gt;
... except Exception: &lt;br /&gt;
...     print &amp;quot;can&#039;t import, probably because your python is too old!&amp;quot;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/env/python&lt;br /&gt;
import sys&lt;br /&gt;
if sys.version_info&amp;lt;(2,6,0):&lt;br /&gt;
  sys.stderr.write(&amp;quot;You need python 2.6 or later to run this script\n&amp;quot;)&lt;br /&gt;
  exit(1)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import sys&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; sys.hexversion  # hex printed as integer&lt;br /&gt;
33817584&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; &#039;%x&#039; % sys.hexversion  # output as hex, not zero fill  2.4.3&lt;br /&gt;
&#039;20403f0&#039;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; sys.hexversion &amp;lt; 0x02060000  # test if version less than 2.6&lt;br /&gt;
True&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; print &amp;quot;0x%08x&amp;quot; % sys.hexversion  # print as hex and zero fill and prepend &#039;0x&#039;&lt;br /&gt;
0x020403f0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import sys&lt;br /&gt;
if sys.hexversion &amp;lt; 0x02060500:&lt;br /&gt;
    print &amp;gt;&amp;gt; sys.stderr, &amp;quot;This script requires python 2.6.5 or higher.&amp;quot;&lt;br /&gt;
    exit(1)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import sys&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; sys.version_info&lt;br /&gt;
(2, 6, 4, &#039;final&#039;, 0)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; if not sys.version_info[:2] == (2, 6):&lt;br /&gt;
...    print &amp;quot;Error, I need python 2.6&amp;quot;&lt;br /&gt;
... else:&lt;br /&gt;
...    from my_module import twoPointSixCode&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* http://stackoverflow.com/questions/446052/python-best-way-to-check-for-python-version-in-program-that-uses-new-language-fe&lt;br /&gt;
* http://stackoverflow.com/questions/1093322/how-do-i-check-what-version-of-python-is-running-my-script&lt;br /&gt;
&lt;br /&gt;
=== [http://docs.python.org/library/struct.html Struct - Binary Data Record Layout] ===&lt;br /&gt;
&lt;br /&gt;
Format Characters:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Format	C Type		Python type 	Standard size&lt;br /&gt;
x	pad byte	no value	  	 &lt;br /&gt;
c	char		str of len 1	1	 &lt;br /&gt;
b	signed char	integer		1&lt;br /&gt;
B	unsigned char	integer 	1&lt;br /&gt;
?	_Bool		bool 		1&lt;br /&gt;
h	short		integer 	2&lt;br /&gt;
H	unsigned short 	integer 	2&lt;br /&gt;
i	int		integer 	4&lt;br /&gt;
I	unsigned int 	integer 	4&lt;br /&gt;
l	long		integer 	4&lt;br /&gt;
L	unsigned long	integer		4&lt;br /&gt;
q	long long	integer		8&lt;br /&gt;
Q	unsigned long long    integer	8&lt;br /&gt;
f	float		float		4&lt;br /&gt;
d	double		float		8&lt;br /&gt;
s	char[]		string&lt;br /&gt;
p	char[]		string&lt;br /&gt;
P	void *		integer&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 H  # two byte unassigned number&lt;br /&gt;
 I  # four byte unassigned number&lt;br /&gt;
 &amp;lt;  # standard size and in little-endian byte order&lt;br /&gt;
&lt;br /&gt;
 import struct&lt;br /&gt;
 data = struct.pack(&#039;&amp;lt;IIIHH&#039;, 1, 2, 3, 4, 5)&lt;br /&gt;
 # data = &#039;\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x04\x00\x05\x00&#039;&lt;br /&gt;
 &lt;br /&gt;
 fields = struct.unpack(&#039;&amp;lt;IIIHH&#039;, data)&lt;br /&gt;
 # fields = (1L, 2L, 3L, 4, 5)&lt;br /&gt;
 # using splice: fields = struct.unpack(&#039;&amp;lt;IIIHH&#039;, data[start:start+16])&lt;br /&gt;
 &lt;br /&gt;
 f1, f2, f3, f4, f5 = fields&lt;br /&gt;
 &lt;br /&gt;
 hex(f1)  # hex a field:&lt;br /&gt;
 #  &#039;0x1L&#039;&lt;br /&gt;
&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; struct.pack(&amp;quot;&amp;lt;5sh&amp;quot;, &amp;quot;helloo&amp;quot;, 11)&lt;br /&gt;
 &#039;hello\x0b\x00&#039;&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; struct.unpack(&amp;quot;&amp;lt;5sh&amp;quot;, &#039;hello\x0b\x00&#039;)&lt;br /&gt;
 (&#039;hello&#039;, 11)&lt;br /&gt;
&lt;br /&gt;
=== pdb interactive debugger ===&lt;br /&gt;
&lt;br /&gt;
 # uncomment the following to use the interactive debugger:&lt;br /&gt;
 # import pdb; pdb.set_trace()&lt;br /&gt;
&lt;br /&gt;
=== [http://docs.python.org/library/telnetlib.html Telnet] ===&lt;br /&gt;
&lt;br /&gt;
create:&lt;br /&gt;
 class telnetlib.Telnet([host[, port[, timeout]]])&lt;br /&gt;
&lt;br /&gt;
Note: The instance is initially not connected by default; the open() method must be used to establish a connection. Alternatively, the host name and optional port number can be passed to the constructor, to, in which case the connection to the server will be established before the constructor returns.&lt;br /&gt;
&lt;br /&gt;
open if not initially done so:&lt;br /&gt;
 Telnet.open(host[, port[, timeout]])&lt;br /&gt;
&lt;br /&gt;
Functions:&lt;br /&gt;
 Telnet.read_until(expected[, timeout])   # Read until a given string, expected, is encountered or until timeout seconds have passed.&lt;br /&gt;
                                          # on timeout return whatever is in queue, possibly empty string&lt;br /&gt;
 Telnet.close()         # close connection&lt;br /&gt;
 Telnet.read_all()      # Read all data until EOF; block until connection closed.&lt;br /&gt;
 Telnet.write(buffer)   # Write a string to the socket, doubling any IAC characters. This can block if the connection is blocked.&lt;br /&gt;
 Telnet.expect(list[, timeout])  # Read until one from a list of a regular expressions matches.&lt;br /&gt;
                        # Return a tuple of three items: the index in the list of matches; the match object; and the text read to match.&lt;br /&gt;
&lt;br /&gt;
Read until end of line:&lt;br /&gt;
 line = tn.read_until(&amp;quot;\n&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import getpass&lt;br /&gt;
import sys&lt;br /&gt;
import telnetlib&lt;br /&gt;
&lt;br /&gt;
HOST = &amp;quot;localhost&amp;quot;&lt;br /&gt;
user = raw_input(&amp;quot;Enter your remote account: &amp;quot;)&lt;br /&gt;
password = getpass.getpass()&lt;br /&gt;
&lt;br /&gt;
tn = telnetlib.Telnet(HOST)&lt;br /&gt;
&lt;br /&gt;
tn.read_until(&amp;quot;login: &amp;quot;)&lt;br /&gt;
tn.write(user + &amp;quot;\n&amp;quot;)&lt;br /&gt;
if password:&lt;br /&gt;
    tn.read_until(&amp;quot;Password: &amp;quot;)&lt;br /&gt;
    tn.write(password + &amp;quot;\n&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
tn.write(&amp;quot;ls\n&amp;quot;)&lt;br /&gt;
tn.write(&amp;quot;exit\n&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
print tn.read_all()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
&lt;br /&gt;
import sys&lt;br /&gt;
import telnetlib&lt;br /&gt;
&lt;br /&gt;
HOST = &amp;quot;216.119.193.252&amp;quot;&lt;br /&gt;
USER = &amp;quot;admin&amp;quot;&lt;br /&gt;
PASS = &amp;quot;@lt12345&amp;quot;&lt;br /&gt;
&lt;br /&gt;
tn = telnetlib.Telnet(HOST)&lt;br /&gt;
&lt;br /&gt;
tn.read_until(&amp;quot;login: &amp;quot;)&lt;br /&gt;
tn.write(USER + &amp;quot;\n&amp;quot;)&lt;br /&gt;
tn.read_until(&amp;quot;Password: &amp;quot;)&lt;br /&gt;
tn.write(PASS + &amp;quot;\n&amp;quot;)&lt;br /&gt;
tn.read_until(&amp;quot;# &amp;quot;)&lt;br /&gt;
&lt;br /&gt;
tn.write(&amp;quot;terminal length 0\n&amp;quot;)&lt;br /&gt;
tn.read_until(&amp;quot;# &amp;quot;)&lt;br /&gt;
&lt;br /&gt;
tn.write(&amp;quot;show running-config\n&amp;quot;)&lt;br /&gt;
configlines = tn.read_until(&amp;quot;# &amp;quot;)&lt;br /&gt;
&lt;br /&gt;
tn.write(&amp;quot;exit\n&amp;quot;)&lt;br /&gt;
tn.read_all()&lt;br /&gt;
&lt;br /&gt;
print(configlines)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== SSH ===&lt;br /&gt;
&lt;br /&gt;
Cheap method:&lt;br /&gt;
 os.system(&#039;ssh user@server command&#039;)&lt;br /&gt;
&lt;br /&gt;
SecureShell - PythonInfo Wiki - http://wiki.python.org/moin/SecureShell&lt;br /&gt;
: There are several ways to use Secure Shell (SSH) in Python&lt;br /&gt;
* pyssh - http://pyssh.sourceforge.net/&lt;br /&gt;
* paramiko - Paramiko is a native Python implementation of SSH. - http://www.lag.net/paramiko/&lt;br /&gt;
* conch - conch is another native implementation of SSH and part of the Twisted Matrix project - http://twistedmatrix.com/projects/conch &lt;br /&gt;
* SSH wrapper - Some tools just wrap around existing ssh/sftp implementations&lt;br /&gt;
** keyphrene - http://www.keyphrene.com/products/org.keyphrene/&lt;br /&gt;
** keyphrene SSH wrapper - http://membres.lycos.fr/fredp/python/pyscp.html&lt;br /&gt;
* Fabric - http://docs.fabfile.org/en/1.4.0/index.html&lt;br /&gt;
* pexpect - Noah.org - http://www.noah.org/wiki/Pexpect&lt;br /&gt;
&lt;br /&gt;
SFTP:&lt;br /&gt;
* SFTP in Python: Really Simple SSH | The best of Zeth - http://zeth.net/post/332/&lt;br /&gt;
&lt;br /&gt;
pexpect:&lt;br /&gt;
 wget http://pexpect.sourceforge.net/pexpect-2.3.tar.gz&lt;br /&gt;
 tar xzf pexpect-2.3.tar.gz&lt;br /&gt;
 cd pexpect-2.3&lt;br /&gt;
 sudo python ./setup.py install&lt;br /&gt;
&lt;br /&gt;
=== SFTP ===&lt;br /&gt;
&lt;br /&gt;
SFTP in Python? (platform independent) - Stack Overflow - http://stackoverflow.com/questions/432385/sftp-in-python-platform-independent&lt;br /&gt;
&lt;br /&gt;
paramiko: ssh2 protocol for python - http://www.lag.net/paramiko/&lt;br /&gt;
&lt;br /&gt;
 pip install paramiko&lt;br /&gt;
&lt;br /&gt;
 mkdir -p ~/.src ; cd ~/.src&lt;br /&gt;
 wget http://www.lag.net/paramiko/download/paramiko-1.7.7.1.zip&lt;br /&gt;
 unzip paramiko-1.7.7.1.zip&lt;br /&gt;
 cd paramiko-1.7.7.1&lt;br /&gt;
 python setup.py install&lt;br /&gt;
&lt;br /&gt;
SFTP Methods:&lt;br /&gt;
* chdir&lt;br /&gt;
* chmod&lt;br /&gt;
* chown&lt;br /&gt;
* close&lt;br /&gt;
* file&lt;br /&gt;
* from_transport&lt;br /&gt;
* get&lt;br /&gt;
* get_channel&lt;br /&gt;
* getcwd&lt;br /&gt;
* listdir&lt;br /&gt;
* listdir_attr&lt;br /&gt;
* logger&lt;br /&gt;
* lstat&lt;br /&gt;
* mkdir&lt;br /&gt;
* normalize&lt;br /&gt;
* open&lt;br /&gt;
* put&lt;br /&gt;
* readlink&lt;br /&gt;
* remove&lt;br /&gt;
* rename&lt;br /&gt;
* request_number&lt;br /&gt;
* rmdir&lt;br /&gt;
* sock&lt;br /&gt;
* stat&lt;br /&gt;
* symlink&lt;br /&gt;
* truncate&lt;br /&gt;
* ultra_debug&lt;br /&gt;
* unlink&lt;br /&gt;
* utime&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import paramiko&lt;br /&gt;
&lt;br /&gt;
host = &amp;quot;THEHOST.com&amp;quot;                    #hard-coded&lt;br /&gt;
port = 22&lt;br /&gt;
transport = paramiko.Transport((host, port))&lt;br /&gt;
&lt;br /&gt;
password = &amp;quot;THEPASSWORD&amp;quot;                #hard-coded&lt;br /&gt;
username = &amp;quot;THEUSERNAME&amp;quot;                #hard-coded&lt;br /&gt;
transport.connect(username = username, password = password)&lt;br /&gt;
&lt;br /&gt;
sftp = paramiko.SFTPClient.from_transport(transport)&lt;br /&gt;
&lt;br /&gt;
import sys&lt;br /&gt;
path = &#039;./THETARGETDIRECTORY/&#039; + sys.argv[1]    #hard-coded&lt;br /&gt;
localpath = sys.argv[1]&lt;br /&gt;
sftp.put(localpath, path)&lt;br /&gt;
&lt;br /&gt;
sftp.close()&lt;br /&gt;
transport.close()&lt;br /&gt;
print &#039;Upload done.&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
VMware Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
&lt;br /&gt;
import paramiko&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
host = &amp;quot;sftp2.engx.vmware.com&amp;quot;&lt;br /&gt;
port = 443&lt;br /&gt;
transport = paramiko.Transport((host, port))&lt;br /&gt;
&lt;br /&gt;
username = &amp;quot;xxxx&amp;quot;&lt;br /&gt;
password = &amp;quot;xxx&amp;quot;&lt;br /&gt;
transport.connect(username = username, password = password)&lt;br /&gt;
&lt;br /&gt;
sftp = paramiko.SFTPClient.from_transport(transport)&lt;br /&gt;
&lt;br /&gt;
print dir(sftp)&lt;br /&gt;
&lt;br /&gt;
print sftp.chdir(&amp;quot;build-uploader&amp;quot;)&lt;br /&gt;
print sftp.listdir()&lt;br /&gt;
&lt;br /&gt;
sftp.close()&lt;br /&gt;
transport.close()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== paramiko ===&lt;br /&gt;
&lt;br /&gt;
See [[Python/paramiko]]&lt;br /&gt;
&lt;br /&gt;
=== [http://docs.python.org/library/getpass.html Get Password] ===&lt;br /&gt;
&lt;br /&gt;
Prompt for password:&lt;br /&gt;
 getpass.getpass(prompt=&#039;Password: &#039;)&lt;br /&gt;
&lt;br /&gt;
 import getpass&lt;br /&gt;
 user = raw_input(&amp;quot;Enter your remote account: &amp;quot;)&lt;br /&gt;
 password = getpass.getpass()&lt;br /&gt;
&lt;br /&gt;
=== [http://docs.python.org/library/configparser.html ini files] ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ini_filename = &#039;my.ini&#039;&lt;br /&gt;
&lt;br /&gt;
import ConfigParser&lt;br /&gt;
parser = ConfigParser.SafeConfigParser()&lt;br /&gt;
parser.read(ini_filename)&lt;br /&gt;
&lt;br /&gt;
sections = parser.sections() # get sections&lt;br /&gt;
for section in sections:&lt;br /&gt;
  print &amp;quot;[&amp;quot; + section + &amp;quot;]&amp;quot;&lt;br /&gt;
  for name, value in parser.items(section):&lt;br /&gt;
    print name + &amp;quot; = &amp;quot; + value&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if parser.has_option(section, option):&lt;br /&gt;
  print( parser.get(section, option) )&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To have the option names not convert to lower case:&lt;br /&gt;
 parser.optionxform = str&lt;br /&gt;
&lt;br /&gt;
Ignore section: [http://stackoverflow.com/questions/2885190/using-pythons-configparser-to-read-a-file-without-section-name]&lt;br /&gt;
 ini_str = &#039;[root]\n&#039; + open(ini_path, &#039;r&#039;).read()&lt;br /&gt;
 ini_fp = StringIO.StringIO(ini_str)&lt;br /&gt;
 config = ConfigParser.RawConfigParser()&lt;br /&gt;
 config.readfp(ini_fp)&lt;br /&gt;
&lt;br /&gt;
Get option:&lt;br /&gt;
 config.has_option(&#039;root&#039;, &#039;some_key&#039;)&lt;br /&gt;
 config.get(&#039;root&#039;, &#039;some_key&#039;)&lt;br /&gt;
&lt;br /&gt;
 config.items(&#039;root&#039;)  # list of Key Value tuples&lt;br /&gt;
&lt;br /&gt;
=== optparse - Option Parser ===&lt;br /&gt;
&lt;br /&gt;
[http://docs.python.org/library/optparse.html - Option Parser&lt;br /&gt;
&lt;br /&gt;
Note: Deprecated since version 2.7: The optparse module is deprecated and will not be developed further; development will continue with the argparse module.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import optparse&lt;br /&gt;
parser = optparse.OptionParser()&lt;br /&gt;
&lt;br /&gt;
parser.add_option(&#039;--name&#039;, default=None)&lt;br /&gt;
&lt;br /&gt;
parser.add_option(&lt;br /&gt;
    &#039;-l&#039;, &#039;--loglevel&#039;,&lt;br /&gt;
    help=&#039;Log Level (default: info)&#039;,&lt;br /&gt;
    default=&amp;quot;info&amp;quot;, action=&#039;store&#039;, type=&#039;string&#039;)&lt;br /&gt;
&lt;br /&gt;
(options, args) = parser.parse_args()&lt;br /&gt;
&lt;br /&gt;
# if no parameters passed show help&lt;br /&gt;
if len(sys.argv) == 1:&lt;br /&gt;
    parser.print_help()&lt;br /&gt;
    sys.exit(1)&lt;br /&gt;
&lt;br /&gt;
# if a stand alone parameter passed, override option&lt;br /&gt;
if args:&lt;br /&gt;
  options.target = args[0]&lt;br /&gt;
&lt;br /&gt;
# show option:&lt;br /&gt;
print(options.loglevel)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: Order is important when listing add_options!&lt;br /&gt;
&lt;br /&gt;
Pretty Description:&lt;br /&gt;
 parser = optparse.OptionParser(description=&amp;quot;Purpose: to do something&amp;quot;)&lt;br /&gt;
 # or&lt;br /&gt;
 parser.description = &amp;quot;Purpose: to do something&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Parse arguments:&lt;br /&gt;
 (options, args) = parser.parse_args()&lt;br /&gt;
Note: If you like, you can pass a custom argument list to parse_args(), but that’s rarely necessary: by default it uses sys.argv[1:].&lt;br /&gt;
&lt;br /&gt;
Change Usage Message:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
usage = &amp;quot;%prog [options]&amp;quot;  # default message&lt;br /&gt;
# Usage: &amp;lt;prog&amp;gt; [options]&amp;quot;  # where &amp;lt;prog&amp;gt; is replaced with the script name&lt;br /&gt;
&lt;br /&gt;
parser = OptionParser(usage=usage)&lt;br /&gt;
# or&lt;br /&gt;
parser.usage = usage  # default message&lt;br /&gt;
# or&lt;br /&gt;
parser.set_usage(usage)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Remove option: (does not remove default value from &#039;options&#039; variable!!! - stupid!)&lt;br /&gt;
 parser.remove_option(&#039;--loglevel&#039;)&lt;br /&gt;
&lt;br /&gt;
Modify an option: (changes are saved to parser automatically, unless in an option group)&lt;br /&gt;
 option = parser.get_option(&#039;--loglevel&#039;)&lt;br /&gt;
 option.help = &#039;something else&#039;&lt;br /&gt;
 option.default = &#039;debug&#039;&lt;br /&gt;
&lt;br /&gt;
 # or&lt;br /&gt;
 parser.remove_option(&amp;quot;--loglevel&amp;quot;)&lt;br /&gt;
 parser.add_option(&amp;quot;--loglevel&amp;quot;, help=&amp;quot;something else&amp;quot;, default=&amp;quot;info&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Modify an option in an option group:&lt;br /&gt;
 opt_group = parser.get_option_group(&amp;quot;--loglevel&amp;quot;)&lt;br /&gt;
 opt_group.remove_option(&amp;quot;--loglevel&amp;quot;)&lt;br /&gt;
 opt_group.add_option(&amp;quot;--loglevel&amp;quot;, help=&amp;quot;something else&amp;quot;, default=&amp;quot;info&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Types: &amp;quot;string&amp;quot;, &amp;quot;int&amp;quot;, &amp;quot;long&amp;quot;, &amp;quot;choice&amp;quot;, &amp;quot;float&amp;quot; and &amp;quot;complex&amp;quot; [http://docs.python.org/library/optparse.html#optparse-standard-option-types]&lt;br /&gt;
Defaults:&lt;br /&gt;
* Default actions is &#039;store&#039;.&lt;br /&gt;
* Default type is &#039;string&#039;.&lt;br /&gt;
* Default dest is the long name of the parameter (or short name if no long name provided)&lt;br /&gt;
* Default value is None&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from optparse import OptionParser&lt;br /&gt;
[...]&lt;br /&gt;
parser = OptionParser()&lt;br /&gt;
&lt;br /&gt;
# string&lt;br /&gt;
parser.add_option(&amp;quot;-f&amp;quot;, &amp;quot;--file&amp;quot;, dest=&amp;quot;filename&amp;quot;,&lt;br /&gt;
                  help=&amp;quot;write report to FILE&amp;quot;, metavar=&amp;quot;FILE&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
# boolean - action is what to do when flag found&lt;br /&gt;
parser.add_option(&amp;quot;-q&amp;quot;, &amp;quot;--quiet&amp;quot;,&lt;br /&gt;
                  action=&amp;quot;store_true&amp;quot;, dest=&amp;quot;verbose&amp;quot;, default=False,&lt;br /&gt;
                  help=&amp;quot;don&#039;t print status messages to stdout&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
# integer&lt;br /&gt;
parser.add_option(&lt;br /&gt;
    &amp;quot;-m&amp;quot;, &amp;quot;--minutes&amp;quot;,&lt;br /&gt;
    help=&amp;quot;Minutes (default: 60)&amp;quot;,&lt;br /&gt;
    default=60, type=&#039;int&#039;)&lt;br /&gt;
&lt;br /&gt;
(options, args) = parser.parse_args()&lt;br /&gt;
&lt;br /&gt;
print &amp;quot;Filename: &amp;quot; + options.filename&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
fake handling of required option:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if not option.filename:&lt;br /&gt;
    parser.print_help()&lt;br /&gt;
    parser.error(&amp;quot;filename is required&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
change default usage:&lt;br /&gt;
  parser = OptionParser(usage=&amp;quot;Usage: %prog [args] arg1 arg2&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Really ugly way to print help usage  :-(&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def Usage():&lt;br /&gt;
    pname = sys.argv[0]&lt;br /&gt;
    cmd=&#039;%s -h&#039; % (pname)&lt;br /&gt;
    os.system(cmd)&lt;br /&gt;
&lt;br /&gt;
if (len(sys.argv) &amp;lt; 2):&lt;br /&gt;
    Usage()&lt;br /&gt;
    sys.exit(1)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Groups:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#  OptionGroup(parser, title, description=None)&lt;br /&gt;
group = OptionGroup(parser, &amp;quot;Dangerous Options&amp;quot;,&lt;br /&gt;
                    &amp;quot;Caution: use these options at your own risk.  &amp;quot;&lt;br /&gt;
                    &amp;quot;It is believed that some of them bite.&amp;quot;)&lt;br /&gt;
group.add_option(&amp;quot;-g&amp;quot;, action=&amp;quot;store_true&amp;quot;, help=&amp;quot;Group option.&amp;quot;)&lt;br /&gt;
parser.add_option_group(group)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hide an option:&lt;br /&gt;
* Option.help&lt;br /&gt;
: &amp;quot;Help text to print for this option when listing all available options after the user supplies a help option (such as --help). If no help text is supplied, the option will be listed without help text. To hide this option, use the special value optparse.SUPPRESS_HELP.&amp;quot;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
parser.add_option(&amp;quot;--secret&amp;quot;, help=SUPPRESS_HELP)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Issues with Option Parser:&lt;br /&gt;
* No handling for positional arguments&lt;br /&gt;
* No adding help for positional arguments&lt;br /&gt;
* No handling for required field&lt;br /&gt;
&lt;br /&gt;
=== argparse ===&lt;br /&gt;
&lt;br /&gt;
argparse - http://docs.python.org/library/argparse.html&lt;br /&gt;
&lt;br /&gt;
argparse — Parser for command-line options, arguments and sub-commands&lt;br /&gt;
&lt;br /&gt;
NOTE: MUCH MORE POWERFUL THAN OPTION PARSER!&lt;br /&gt;
&lt;br /&gt;
Note: New in version 2.7.&lt;br /&gt;
&lt;br /&gt;
Installation on &amp;lt;= 2.6&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Install argparse: - http://code.google.com/p/argparse/&lt;br /&gt;
# REQUIRES SETUPTOOLS&lt;br /&gt;
mkdir -p ~/.src ; cd ~/.src&lt;br /&gt;
wget http://argparse.googlecode.com/files/argparse-1.2.1.tar.gz&lt;br /&gt;
tar -zvxf argparse-1.2.1.tar.gz&lt;br /&gt;
cd argparse-1.2.1&lt;br /&gt;
sudo python setup.py install&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The argparse module makes it easy to write user-friendly command-line interfaces. The program defines what arguments it requires, and argparse will figure out how to parse those out of sys.argv. The argparse module also automatically generates help and usage messages and issues errors when users give the program invalid arguments.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import argparse&lt;br /&gt;
&lt;br /&gt;
parser = argparse.ArgumentParser(description=&#039;Process some integers.&#039;)&lt;br /&gt;
parser.add_argument(&#039;integers&#039;, metavar=&#039;N&#039;, type=int, nargs=&#039;+&#039;,&lt;br /&gt;
                   help=&#039;an integer for the accumulator&#039;)&lt;br /&gt;
parser.add_argument(&#039;--sum&#039;, dest=&#039;accumulate&#039;, action=&#039;store_const&#039;,&lt;br /&gt;
                   const=sum, default=max,&lt;br /&gt;
                   help=&#039;sum the integers (default: find the max)&#039;)&lt;br /&gt;
&lt;br /&gt;
args = parser.parse_args()&lt;br /&gt;
print args.accumulate(args.integers)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import argparse&lt;br /&gt;
&lt;br /&gt;
argparser = demoproject.util.argparse.ArgumentParser(&lt;br /&gt;
    usage=&#039;Kick off demoproject benchmarks.&#039;)&lt;br /&gt;
argparser.add_argument(&lt;br /&gt;
    &#039;--card&#039;,&lt;br /&gt;
    help=&#039;What cards to run on.  Depends on Jenkins NODE_LABEL environment&#039;&lt;br /&gt;
        &#039;variable for correct mappings.&#039;)&lt;br /&gt;
argparser.add_argument(&lt;br /&gt;
    &#039;--suite&#039;, metavar=&#039;SUITE&#039;,&lt;br /&gt;
    help=&#039;Specify the appropriate benchmark suite as defined in &#039;&lt;br /&gt;
        &#039;the benchmark ini file.  Defaults to standard_perf&#039;,&lt;br /&gt;
    default=&#039;standard_perf&#039;)&lt;br /&gt;
args = argparser.parse_args()&lt;br /&gt;
&lt;br /&gt;
print args.card&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Remove an argument: [http://stackoverflow.com/questions/32807319/disable-remove-argument-in-argparse]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def remove_options(parser, options):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot; remove_options(parser, [&#039;--some-option&#039;, &#039;--some-option2&#039;]) &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    for option in options:&lt;br /&gt;
        for action in parser._actions:&lt;br /&gt;
            if vars(action)[&#039;option_strings&#039;][0] == option:&lt;br /&gt;
                parser._handle_conflict_resolve(None,[(option,action)])&lt;br /&gt;
                break&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [http://docs.python.org/library/commands.html commands] ===&lt;br /&gt;
&lt;br /&gt;
35.16. commands — Utilities for running commands — Python v2.7.1 documentation - http://docs.python.org/library/commands.html&lt;br /&gt;
&lt;br /&gt;
Note: Deprecated since version 2.6: The commands module has been removed in Python 3.0. Use the subprocess module instead.&lt;br /&gt;
&lt;br /&gt;
The commands module contains wrapper functions for os.popen() which take a system command as a string and return any output generated by the command and, optionally, the exit status.&lt;br /&gt;
&lt;br /&gt;
Get status and output:&lt;br /&gt;
 status, output = commands.getstatusoutput(cmd)&lt;br /&gt;
&lt;br /&gt;
Get output ignoring status:&lt;br /&gt;
 output = commands.getoutput(cmd)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
NOTE: DO NOT USE getstatus() AS IT DOES NOT DO WHAT YOU THINK IT DOES!&lt;br /&gt;
 status = commands.getstatus(file)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import commands&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; commands.getstatusoutput(&#039;ls /bin/ls&#039;)&lt;br /&gt;
(0, &#039;/bin/ls&#039;)&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; commands.getstatusoutput(&#039;cat /bin/junk&#039;)&lt;br /&gt;
(256, &#039;cat: /bin/junk: No such file or directory&#039;)&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; commands.getstatusoutput(&#039;/bin/junk&#039;)&lt;br /&gt;
(256, &#039;sh: /bin/junk: not found&#039;)&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; commands.getoutput(&#039;ls /bin/ls&#039;)&lt;br /&gt;
&#039;/bin/ls&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; commands.getstatus(&#039;/bin/ls&#039;)&lt;br /&gt;
&#039;-rwxr-xr-x  1 root        13352 Oct 14  1994 /bin/ls&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [http://docs.python.org/library/_winreg.html Windows Registry] ===&lt;br /&gt;
&lt;br /&gt;
Note: The _winreg module has been renamed to winreg in Python 3.0.&lt;br /&gt;
&lt;br /&gt;
* 32.3. winreg – Windows registry access — Python v3.2 documentation - http://docs.python.org/py3k/library/winreg.html&lt;br /&gt;
* 34.3. _winreg – Windows registry access — Python v2.7.1 documentation - http://docs.python.org/library/_winreg.html&lt;br /&gt;
&lt;br /&gt;
Read from registry:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from _winreg import *&lt;br /&gt;
key = OpenKey(HKEY_LOCAL_MACHINE, r&#039;Software\Microsoft\Outlook Express&#039;, 0, KEY_ALL_ACCESS)&lt;br /&gt;
QueryValueEx(key, &amp;quot;InstallRoot&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Write to registry:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
keyVal = r&#039;Software\Microsoft\Internet Explorer\Main&#039;&lt;br /&gt;
try:&lt;br /&gt;
    key = OpenKey(HKEY_CURRENT_USER, keyVal, 0, KEY_ALL_ACCESS)&lt;br /&gt;
except:&lt;br /&gt;
    key = CreateKey(HKEY_CURRENT_USER, keyVal)&lt;br /&gt;
SetValueEx(key, &amp;quot;Start Page&amp;quot;, 0, REG_SZ, &amp;quot;http://www.blog.pythonlibrary.org/&amp;quot;)&lt;br /&gt;
CloseKey(key)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Enumerate registry keys:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from _winreg import EnumKey, HKEY_USERS&lt;br /&gt;
 &lt;br /&gt;
try:&lt;br /&gt;
    i = 0&lt;br /&gt;
    while True:&lt;br /&gt;
        subkey = EnumKey(HKEY_USERS, i)&lt;br /&gt;
        print subkey&lt;br /&gt;
        i += 1&lt;br /&gt;
except WindowsError:&lt;br /&gt;
    # WindowsError: [Errno 259] No more data is available    &lt;br /&gt;
    pass&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Another enumeration example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# File: winreg-example-1.py&lt;br /&gt;
&lt;br /&gt;
import _winreg&lt;br /&gt;
&lt;br /&gt;
explorer = _winreg.OpenKey(&lt;br /&gt;
    _winreg.HKEY_CURRENT_USER,&lt;br /&gt;
    &amp;quot;Software\\Microsoft\\Windows\\CurrentVersion\\Explorer&amp;quot;&lt;br /&gt;
    )&lt;br /&gt;
&lt;br /&gt;
# list values owned by this registry key&lt;br /&gt;
try:&lt;br /&gt;
    i = 0&lt;br /&gt;
    while 1:&lt;br /&gt;
        name, value, type = _winreg.EnumValue(explorer, i)&lt;br /&gt;
        print repr(name),&lt;br /&gt;
        i += 1&lt;br /&gt;
except WindowsError:&lt;br /&gt;
    print&lt;br /&gt;
&lt;br /&gt;
value, type = _winreg.QueryValueEx(explorer, &amp;quot;Logon User Name&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
print&lt;br /&gt;
print &amp;quot;user is&amp;quot;, repr(value)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Enable Remote Desktop Example: (by Kenneth)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from _winreg import *&lt;br /&gt;
key = OpenKey(HKEY_LOCAL_MACHINE, r&#039;SYSTEM\CurrentControlSet\Control\Terminal Server&#039;, 0, KEY_ALL_ACCESS)&lt;br /&gt;
SetValueEx(key, &amp;quot;fDenyTSConnections&amp;quot;, 0, REG_DWORD, 0)&lt;br /&gt;
ValueTypeTuple = QueryValueEx(key, &amp;quot;fDenyTSConnections&amp;quot;)   # (0, 4)&lt;br /&gt;
print(&amp;quot;Please reboot the system to complete the changes&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* Python’s _winreg: Editing the Windows Registry « The Mouse Vs. The Python - http://www.blog.pythonlibrary.org/2010/03/20/pythons-_winreg-editing-the-windows-registry/&lt;br /&gt;
&lt;br /&gt;
=== JSON ===&lt;br /&gt;
&lt;br /&gt;
JSON - http://docs.python.org/library/json.html&lt;br /&gt;
&lt;br /&gt;
ENCODING TO JSON STRING (type str)&lt;br /&gt;
&lt;br /&gt;
 import json&lt;br /&gt;
 json.dumps([&#039;foo&#039;, {&#039;bar&#039;: (&#039;baz&#039;, None, 1.0, 2)}])&lt;br /&gt;
 # &#039;[&amp;quot;foo&amp;quot;, {&amp;quot;bar&amp;quot;: [&amp;quot;baz&amp;quot;, null, 1.0, 2]}]&#039;&lt;br /&gt;
&lt;br /&gt;
compact encoding:&lt;br /&gt;
 import json&lt;br /&gt;
 json.dumps([1,2,3,{&#039;4&#039;: 5, &#039;6&#039;: 7}], separators=(&#039;,&#039;,&#039;:&#039;))&lt;br /&gt;
 # &#039;[1,2,3,{&amp;quot;4&amp;quot;:5,&amp;quot;6&amp;quot;:7}]&#039;&lt;br /&gt;
&lt;br /&gt;
Pretty printing:&lt;br /&gt;
 import json&lt;br /&gt;
 print json.dumps({&#039;4&#039;: 5, &#039;6&#039;: 7}, sort_keys=True, indent=4)&lt;br /&gt;
 # {&lt;br /&gt;
 #     &amp;quot;4&amp;quot;: 5,&lt;br /&gt;
 #     &amp;quot;6&amp;quot;: 7&lt;br /&gt;
 # }&lt;br /&gt;
&lt;br /&gt;
DECODING JSON STRING TO PYTHON LIST OR DICTIONARY OBJECT&lt;br /&gt;
&lt;br /&gt;
 import json&lt;br /&gt;
 json.loads(&#039;[&amp;quot;foo&amp;quot;, {&amp;quot;bar&amp;quot;:[&amp;quot;baz&amp;quot;, null, 1.0, 2]}]&#039;)&lt;br /&gt;
 # [u&#039;foo&#039;, {u&#039;bar&#039;: [u&#039;baz&#039;, None, 1.0, 2]}]&lt;br /&gt;
&lt;br /&gt;
Load from file:&lt;br /&gt;
 f = open(filename)&lt;br /&gt;
 j = json.load(f)&lt;br /&gt;
 print j[&amp;quot;kind&amp;quot;]  # &amp;quot;dual-controller-adapter&amp;quot;&lt;br /&gt;
 #{&lt;br /&gt;
 #   &amp;quot;kind&amp;quot;: &amp;quot;dual-controller-adapter&amp;quot;,&lt;br /&gt;
 #}&lt;br /&gt;
&lt;br /&gt;
From Command Line:&lt;br /&gt;
 echo &#039;{&amp;quot;foo&amp;quot;: &amp;quot;lorem&amp;quot;, &amp;quot;bar&amp;quot;: &amp;quot;ipsum&amp;quot;}&#039; | python -mjson.tool&lt;br /&gt;
&lt;br /&gt;
 # get value&lt;br /&gt;
 echo &#039;{&amp;quot;test&amp;quot;:1,&amp;quot;test2&amp;quot;:2}&#039; | python -c &#039;import sys,json;data=json.loads(sys.stdin.read()); print data[&amp;quot;test&amp;quot;]&#039;&lt;br /&gt;
&lt;br /&gt;
 # read large file&lt;br /&gt;
 python -c &amp;quot;import json;f=open(&#039;file.json&#039;);data=json.load(f);print json.dumps(data,indent=2)&amp;quot;&lt;br /&gt;
 python -c &amp;quot;import json;print json.dumps(json.load(open(&#039;file.json&#039;)),indent=2)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Load from web:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import httplib&lt;br /&gt;
import json&lt;br /&gt;
&lt;br /&gt;
def get_http_json(server, path):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot; This performs an HTTP GET against a server and path and returns the&lt;br /&gt;
        resulting page data.&lt;br /&gt;
&lt;br /&gt;
        server The server we&#039;re hitting, e.g. demo.com&lt;br /&gt;
        path   The path we&#039;re hitting, e.g. api/part/MA12345/&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    connection = httplib.HTTPConnection(server)&lt;br /&gt;
    try:&lt;br /&gt;
        url = &#039;http://%s/%s&#039; % (server, path)&lt;br /&gt;
        print &#039;Querying url %s&#039; % url&lt;br /&gt;
        connection.request(&#039;GET&#039;, url)&lt;br /&gt;
        response = connection.getresponse()&lt;br /&gt;
        if response.status == httplib.OK:&lt;br /&gt;
            return json.loads(response.read())&lt;br /&gt;
        else:&lt;br /&gt;
            print &#039;Unable to get %s. %s %s&#039; % (url, response.reason,&lt;br /&gt;
                    response.status)&lt;br /&gt;
            return None&lt;br /&gt;
    finally:&lt;br /&gt;
        connection.close()&lt;br /&gt;
&lt;br /&gt;
j = get_http_json(server, path)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pretty printing from the command line:&lt;br /&gt;
 echo &#039;{&amp;quot;json&amp;quot;:&amp;quot;obj&amp;quot;}&#039; | python -mjson.tool&lt;br /&gt;
 #{&lt;br /&gt;
 #   &amp;quot;json&amp;quot;: &amp;quot;obj&amp;quot;&lt;br /&gt;
 #}&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* 18.2. json — JSON encoder and decoder — Python v2.7.1 documentation - http://docs.python.org/library/json.html&lt;br /&gt;
&lt;br /&gt;
=== Sockets ===&lt;br /&gt;
&lt;br /&gt;
See [[Python/Sockets]]&lt;br /&gt;
&lt;br /&gt;
=== [http://docs.python.org/library/base64.html base64] ===&lt;br /&gt;
&lt;br /&gt;
 import base64&lt;br /&gt;
&lt;br /&gt;
Encode:&lt;br /&gt;
 encoded = base64.b64encode(&#039;data to be encoded&#039;)&lt;br /&gt;
&lt;br /&gt;
Decode:&lt;br /&gt;
 base64.b64decode(encoded)&lt;br /&gt;
&lt;br /&gt;
=== daemonize ===&lt;br /&gt;
&lt;br /&gt;
Creating a daemon the Python way « Python recipes « ActiveState Code - http://code.activestate.com/recipes/278731-creating-a-daemon-the-python-way/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import os&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
try:&lt;br /&gt;
    pid = os.fork()&lt;br /&gt;
except OSError, e:&lt;br /&gt;
    raise Exception, &amp;quot;%s [%d]&amp;quot; % (e.strerror, e.errno)&lt;br /&gt;
&lt;br /&gt;
if (pid != 0):  # parent&lt;br /&gt;
    os._exit(0)&lt;br /&gt;
&lt;br /&gt;
# create new process session&lt;br /&gt;
os.setsid()&lt;br /&gt;
&lt;br /&gt;
# redirect stdin, stdout, stderr&lt;br /&gt;
os.open(&#039;/dev/null&#039;, os.O_RDWR)&lt;br /&gt;
os.dup2(0, 1)&lt;br /&gt;
os.dup2(0, 2)&lt;br /&gt;
&lt;br /&gt;
#... tasks ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
My Solution:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import os&lt;br /&gt;
import sys&lt;br /&gt;
import signal&lt;br /&gt;
import syslog&lt;br /&gt;
&lt;br /&gt;
HUP = False&lt;br /&gt;
&lt;br /&gt;
def log(msg):&lt;br /&gt;
    syslog.syslog(str(msg))&lt;br /&gt;
syslog.openlog(&#039;[WATER]&#039;)&lt;br /&gt;
&lt;br /&gt;
def kill_signal_handler(signal, frame):&lt;br /&gt;
    log(&amp;quot;Being killed off: {0} {1}&amp;quot;.format(signal, frame))&lt;br /&gt;
    log(&amp;quot;Shutting Down!&amp;quot;)&lt;br /&gt;
    sys.exit(0)&lt;br /&gt;
signal.signal(signal.SIGTERM, kill_signal_handler)&lt;br /&gt;
signal.signal(signal.SIGALRM, kill_signal_handler)&lt;br /&gt;
&lt;br /&gt;
def hup_signal_handler(signal, frame):&lt;br /&gt;
    global HUP&lt;br /&gt;
    log(&amp;quot;Signal reload received: {0} {1}&amp;quot;.format(signal, frame))&lt;br /&gt;
    HUP=True&lt;br /&gt;
signal.signal(signal.SIGHUP, hup_signal_handler)&lt;br /&gt;
&lt;br /&gt;
def main_loop():&lt;br /&gt;
    global HUP&lt;br /&gt;
&lt;br /&gt;
    while True:&lt;br /&gt;
        #  ... handle HUP=True ...&lt;br /&gt;
&lt;br /&gt;
        # ... main code ...&lt;br /&gt;
&lt;br /&gt;
        # wait 60 seconds before we start the next loop&lt;br /&gt;
        time.sleep(60)  # signals will interrupt this&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
    log(&amp;quot;Starting Daemon...&amp;quot;)&lt;br /&gt;
    child_id = os.fork()&lt;br /&gt;
    if child_id:&lt;br /&gt;
        log(&amp;quot;Daemonized!&amp;quot;)&lt;br /&gt;
        sys.exit(0)&lt;br /&gt;
    os.setsid()&lt;br /&gt;
    # redirect stdin, stdout, stderr&lt;br /&gt;
    os.open(&#039;/dev/null&#039;, os.O_RDWR)&lt;br /&gt;
    os.dup2(0, 1)&lt;br /&gt;
    os.dup2(0, 2)&lt;br /&gt;
&lt;br /&gt;
    # write pid&lt;br /&gt;
    with open(&amp;quot;water.pid&amp;quot;, &amp;quot;w&amp;quot;) as f:&lt;br /&gt;
        f.write(str(os.getpid()))&lt;br /&gt;
&lt;br /&gt;
    while True:&lt;br /&gt;
        try:&lt;br /&gt;
            main_loop()&lt;br /&gt;
        except Exception as e:&lt;br /&gt;
            log(&amp;quot;Critical Failure Caught: %s&amp;quot; % str(e))&lt;br /&gt;
            log(&amp;quot;Critical Failure - Restarting!&amp;quot;)&lt;br /&gt;
            time.sleep(30)&lt;br /&gt;
            #raise e&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 ln -s /opt/pyton27/bin/python pyton-water&lt;br /&gt;
 ./python-water water.py&lt;br /&gt;
 killall python-water&lt;br /&gt;
&lt;br /&gt;
==== fork ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import os&lt;br /&gt;
import sys&lt;br /&gt;
import time&lt;br /&gt;
&lt;br /&gt;
child_id = os.fork()&lt;br /&gt;
if child_id:&lt;br /&gt;
  print &amp;quot;parent exiting&amp;quot;&lt;br /&gt;
  sys.exit(0)&lt;br /&gt;
&lt;br /&gt;
while True:&lt;br /&gt;
    time.sleep(3)&lt;br /&gt;
    print &amp;quot;child&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For windows, to hide the console, see [[#Hide Console]]&lt;br /&gt;
&lt;br /&gt;
=== csv ===&lt;br /&gt;
&lt;br /&gt;
13.1. csv — CSV File Reading and Writing — Python v2.7.2 documentation - http://docs.python.org/library/csv.html&lt;br /&gt;
&lt;br /&gt;
Read:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import csv&lt;br /&gt;
spamReader = csv.reader(open(&#039;eggs.csv&#039;, &#039;rb&#039;), delimiter=&#039; &#039;, quotechar=&#039;|&#039;)&lt;br /&gt;
for row in spamReader:&lt;br /&gt;
  print &#039;, &#039;.join(row)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Write:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import csv&lt;br /&gt;
spamWriter = csv.writer(open(&#039;eggs.csv&#039;, &#039;wb&#039;), delimiter=&#039; &#039;,&lt;br /&gt;
    quotechar=&#039;|&#039;, quoting=csv.QUOTE_MINIMAL)&lt;br /&gt;
spamWriter.writerow([&#039;Spam&#039;] * 5 + [&#039;Baked Beans&#039;])&lt;br /&gt;
spamWriter.writerow([&#039;Spam&#039;, &#039;Lovely Spam&#039;, &#039;Wonderful Spam&#039;])&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== SQLite ===&lt;br /&gt;
&lt;br /&gt;
11.13. sqlite3 — DB-API 2.0 interface for SQLite databases — Python v2.7.2 documentation - http://docs.python.org/library/sqlite3.html&lt;br /&gt;
&lt;br /&gt;
sqlite3 - New in version 2.5.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import sqlite3&lt;br /&gt;
&lt;br /&gt;
conn = sqlite3.connect(&#039;/tmp/example&#039;)&lt;br /&gt;
&lt;br /&gt;
c = conn.cursor()&lt;br /&gt;
&lt;br /&gt;
# Create table&lt;br /&gt;
c.execute(&#039;&#039;&#039;create table stocks&lt;br /&gt;
(date text, trans text, symbol text,&lt;br /&gt;
 qty real, price real)&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
# Insert a row of data&lt;br /&gt;
c.execute(&amp;quot;&amp;quot;&amp;quot;insert into stocks&lt;br /&gt;
          values (&#039;2006-01-05&#039;,&#039;BUY&#039;,&#039;RHAT&#039;,100,35.14)&amp;quot;&amp;quot;&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
# Show affected row count&lt;br /&gt;
print c.rowcount&lt;br /&gt;
&lt;br /&gt;
# Save (commit) the changes&lt;br /&gt;
conn.commit()&lt;br /&gt;
&lt;br /&gt;
# We can also close the cursor if we are done with it&lt;br /&gt;
c.close()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
parameter substitution:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Never do this -- insecure!&lt;br /&gt;
symbol = &#039;IBM&#039;&lt;br /&gt;
c.execute(&amp;quot;... where symbol = &#039;%s&#039;&amp;quot; % symbol)&lt;br /&gt;
&lt;br /&gt;
# Do this instead&lt;br /&gt;
t = (symbol,)&lt;br /&gt;
c.execute(&#039;select * from stocks where symbol=?&#039;, t)&lt;br /&gt;
c.execute(&#039;select * from stocks where symbol=?&#039;, (symbol,))&lt;br /&gt;
&lt;br /&gt;
# Larger example&lt;br /&gt;
for t in [(&#039;2006-03-28&#039;, &#039;BUY&#039;, &#039;IBM&#039;, 1000, 45.00),&lt;br /&gt;
          (&#039;2006-04-05&#039;, &#039;BUY&#039;, &#039;MSOFT&#039;, 1000, 72.00),&lt;br /&gt;
          (&#039;2006-04-06&#039;, &#039;SELL&#039;, &#039;IBM&#039;, 500, 53.00),&lt;br /&gt;
         ]:&lt;br /&gt;
    c.execute(&#039;insert into stocks values (?,?,?,?,?)&#039;, t)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
select results:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
c = conn.cursor()&lt;br /&gt;
c.execute(&#039;select * from stocks order by price&#039;)&lt;br /&gt;
&lt;br /&gt;
for row in c:&lt;br /&gt;
  print row  # row is a tuple&lt;br /&gt;
&lt;br /&gt;
# OR (but not both)&lt;br /&gt;
&lt;br /&gt;
rows = c.fetchall()    # rows is list of tuples&lt;br /&gt;
print len(rows)&lt;br /&gt;
for row in rows:&lt;br /&gt;
  print row&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Show which version of sqlite3: [http://zetcode.com/db/sqlitepythontutorial/]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/python&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&lt;br /&gt;
import sqlite3 as lite&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
con = None&lt;br /&gt;
&lt;br /&gt;
try:&lt;br /&gt;
    con = lite.connect(&#039;test.db&#039;)&lt;br /&gt;
&lt;br /&gt;
    cur = con.cursor()&lt;br /&gt;
    cur.execute(&#039;SELECT SQLITE_VERSION()&#039;)&lt;br /&gt;
&lt;br /&gt;
    data = cur.fetchone()&lt;br /&gt;
&lt;br /&gt;
    print &amp;quot;SQLite version: %s&amp;quot; % data&lt;br /&gt;
&lt;br /&gt;
except lite.Error, e:&lt;br /&gt;
&lt;br /&gt;
    print &amp;quot;Error %s:&amp;quot; % e.args[0]&lt;br /&gt;
    sys.exit(1)&lt;br /&gt;
&lt;br /&gt;
finally:&lt;br /&gt;
&lt;br /&gt;
    if con:&lt;br /&gt;
        con.close()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Or simply: [http://stackoverflow.com/questions/1545479/force-python-to-forego-native-sqlite3-and-use-the-installed-latest-sqlite3-ver]&lt;br /&gt;
 # echo -e &amp;quot;import sqlite3\nprint sqlite3.sqlite_version_info&amp;quot; | python&lt;br /&gt;
 (3, 3, 6)&lt;br /&gt;
&lt;br /&gt;
=== MySQL Database ===&lt;br /&gt;
&lt;br /&gt;
Ubuntu packages:&lt;br /&gt;
* python-mysqldb - Python interface to MySQL&lt;br /&gt;
* python-mysql.connector - pure Python implementation of MySQL Client/Server protocol&lt;br /&gt;
&lt;br /&gt;
 apt-get install python-mysqldb&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; import _mysql&lt;br /&gt;
&lt;br /&gt;
 apt-get install python-mysql.connector&lt;br /&gt;
 &lt;br /&gt;
PIP:&lt;br /&gt;
* https://pypi.python.org/pypi/MySQL-python&lt;br /&gt;
* https://pypi.python.org/pypi/mysqlclient&lt;br /&gt;
&lt;br /&gt;
 pip install MySQL-python&lt;br /&gt;
&lt;br /&gt;
 pip install mysqlclient&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
_mysql - http://mysql-python.sourceforge.net/MySQLdb.html&lt;br /&gt;
&lt;br /&gt;
 apt-get install python-mysqldb&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import _mysql&lt;br /&gt;
&lt;br /&gt;
db=_mysql.connect(host=&amp;quot;localhost&amp;quot;,user=&amp;quot;user&amp;quot;,&lt;br /&gt;
                  passwd=&amp;quot;pass&amp;quot;,db=&amp;quot;db&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
db.query(&amp;quot;&amp;quot;&amp;quot;SELECT spam, eggs, sausage FROM breakfast&lt;br /&gt;
         WHERE price &amp;lt; 5&amp;quot;&amp;quot;&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
r=db.store_result()&lt;br /&gt;
# ...or...&lt;br /&gt;
r=db.use_result()&lt;br /&gt;
&lt;br /&gt;
row = r.fetch_row()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== couchdb ===&lt;br /&gt;
&lt;br /&gt;
Getting started with couchdb-python — couchdb-python v0.8 documentation - http://packages.python.org/CouchDB/getting-started.html&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
couch = couchdb.Server(&#039;http://127.0.0.1:5984/&#039;)&lt;br /&gt;
&lt;br /&gt;
# database&lt;br /&gt;
db = couch.create(&#039;test&#039;) # create new&lt;br /&gt;
db = couch[&#039;mydb&#039;] # or get existing&lt;br /&gt;
&lt;br /&gt;
# print databases:&lt;br /&gt;
for db in couch:&lt;br /&gt;
  print db&lt;br /&gt;
&lt;br /&gt;
doc = {&#039;foo&#039;: &#039;bar&#039;}&lt;br /&gt;
doc_id, doc_rev = db.save(doc)&lt;br /&gt;
# (u&#039;9278f7691c3421227a9f8436540008f9&#039;, u&#039;1-4c6114c65e295552ab1019e2b046b10e&#039;)&lt;br /&gt;
# note: this also updates doc with _rev and _id&lt;br /&gt;
doc = db[&#039;9278f7691c3421227a9f8436540008f9&#039;]&lt;br /&gt;
&lt;br /&gt;
# better to create a document using an id you want, instead of the randomly generated one&lt;br /&gt;
db[doc.id] = doc  # this will write immediately to the database&lt;br /&gt;
&lt;br /&gt;
# print all docs:&lt;br /&gt;
for id in db:&lt;br /&gt;
  print id&lt;br /&gt;
&lt;br /&gt;
# delete doc&lt;br /&gt;
db.delete(doc)&lt;br /&gt;
&lt;br /&gt;
# delete database&lt;br /&gt;
couch.delete(&#039;test&#039;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Search database:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# show all records&lt;br /&gt;
map_fun = &#039;&#039;&#039;function(doc) { emit(doc.name, null); }&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
# row = &amp;lt;Row id=u&#039;12341234123412341234&#039;, key=None, value=None&amp;gt;&lt;br /&gt;
# emit(key, value) - returns the values for key and value&lt;br /&gt;
&lt;br /&gt;
map_fun = &#039;&#039;&#039;&lt;br /&gt;
function(doc) {&lt;br /&gt;
  if (doc.username == &#039;virt-01&#039;)&lt;br /&gt;
     emit(doc.username, null);&lt;br /&gt;
}&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
# row = &amp;lt;Row id=u&#039;12341234123412341234&#039;, key=None, value=None&amp;gt;&lt;br /&gt;
for row in db.query(map_fun):&lt;br /&gt;
  print row.id&lt;br /&gt;
&lt;br /&gt;
for row in db.query(map_fun, descending=True):&lt;br /&gt;
  print row.id&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
couchdb-python - CouchDB Python Library - Google Project Hosting - http://code.google.com/p/couchdb-python/&lt;br /&gt;
&lt;br /&gt;
Installation:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir -p ~/.src ; cd ~/.src&lt;br /&gt;
wget http://pypi.python.org/packages/source/C/CouchDB/CouchDB-0.8.tar.gz#md5=e32b39e459e1fa2586ea252712a11a59&lt;br /&gt;
tar -zvxf CouchDB-0.8.tar.gz&lt;br /&gt;
cd CouchDB-0.8&lt;br /&gt;
python setup.py install&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Test:&lt;br /&gt;
 echo &amp;quot;import couchdb&amp;quot; | python&lt;br /&gt;
&lt;br /&gt;
=== nose ===&lt;br /&gt;
&lt;br /&gt;
nose: nose extends unittest to make testing easier&lt;br /&gt;
&lt;br /&gt;
nose : Python Package Index - http://pypi.python.org/pypi/nose&lt;br /&gt;
&lt;br /&gt;
Install:&lt;br /&gt;
 mkdir -p ~/.src ; cd ~/.src&lt;br /&gt;
 wget http://pypi.python.org/packages/source/n/nose/nose-1.1.2.tar.gz#md5=144f237b615e23f21f6a50b2183aa817&lt;br /&gt;
 tar -zvxf nose-1.1.2.tar.gz&lt;br /&gt;
 cd nose-1.1.2&lt;br /&gt;
 sudo python setup.py install&lt;br /&gt;
&lt;br /&gt;
skeleton:&lt;br /&gt;
 mkdir skeleton&lt;br /&gt;
 cd skeleton&lt;br /&gt;
 mkdir bin NAME tests docs&lt;br /&gt;
 touch NAME/__init__.py&lt;br /&gt;
 touch tests/__init__.py&lt;br /&gt;
 touch tests/NAME_tests.py&lt;br /&gt;
&lt;br /&gt;
nose test skeleton:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# tests/NAME_tests.py&lt;br /&gt;
from nose.tools import *&lt;br /&gt;
import klib&lt;br /&gt;
&lt;br /&gt;
def setup():&lt;br /&gt;
    print &amp;quot;SETUP!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
def teardown():&lt;br /&gt;
    print &amp;quot;TEAR DOWN!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
def test_basic():&lt;br /&gt;
    print &amp;quot;I RAN!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# def test_something_else():&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
 nosetests&lt;br /&gt;
&lt;br /&gt;
See Also:&lt;br /&gt;
* [[#doctest]]&lt;br /&gt;
* [[#unittest]]&lt;br /&gt;
&lt;br /&gt;
=== pydoc ===&lt;br /&gt;
&lt;br /&gt;
25.1. pydoc — Documentation generator and online help system — Python v2.7.2 documentation - http://docs.python.org/library/pydoc.html&lt;br /&gt;
&lt;br /&gt;
pydoc - The pydoc module automatically generates documentation from Python modules.&lt;br /&gt;
&lt;br /&gt;
pydoc - same as &#039;import [library], help([library])&#039;&lt;br /&gt;
 $ pydoc [library]&lt;br /&gt;
&lt;br /&gt;
Note: lists some special &#039;module metadata variables&#039; separately (e.g. version, author).&lt;br /&gt;
&lt;br /&gt;
special pydoc recognized metadata sections:&lt;br /&gt;
 __version__&lt;br /&gt;
 __author__&lt;br /&gt;
 __credits__&lt;br /&gt;
 __date__&lt;br /&gt;
&lt;br /&gt;
==== pydoc function module ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Help on package klib:&lt;br /&gt;
&lt;br /&gt;
NAME&lt;br /&gt;
    klib - This is the name&lt;br /&gt;
&lt;br /&gt;
FILE&lt;br /&gt;
    /root/klib/klib/__init__.py&lt;br /&gt;
&lt;br /&gt;
DESCRIPTION&lt;br /&gt;
    These are module doc strings&lt;br /&gt;
        that give helpful details&lt;br /&gt;
&lt;br /&gt;
PACKAGE CONTENTS&lt;br /&gt;
    markone&lt;br /&gt;
&lt;br /&gt;
FUNCTIONS&lt;br /&gt;
    func1()&lt;br /&gt;
        This is a doc string&lt;br /&gt;
        for func1&lt;br /&gt;
&lt;br /&gt;
DATA&lt;br /&gt;
    PI = 3.141&lt;br /&gt;
    __all__ = [&#039;func1&#039;, &#039;PI&#039;]&lt;br /&gt;
    __author__ = &#039;Kenneth &amp;lt;kenneth@oeey.com&amp;gt;&#039;&lt;br /&gt;
    __copyright__ = &#039;Copyright 2007, The Project&#039;&lt;br /&gt;
    __credits__ = &#039;Credits go to me&#039;&lt;br /&gt;
    __date__ = &#039;26 February 2001&#039;&lt;br /&gt;
    __email__ = &#039;ken@oeey.com&#039;&lt;br /&gt;
    __license__ = &#039;GPL&#039;&lt;br /&gt;
    __maintainer__ = &#039;Ken&#039;&lt;br /&gt;
    __status__ = &#039;Production&#039;&lt;br /&gt;
    __version__ = &#039;$Revision: 83492 $&#039;&lt;br /&gt;
&lt;br /&gt;
VERSION&lt;br /&gt;
    83492&lt;br /&gt;
&lt;br /&gt;
DATE&lt;br /&gt;
    26 February 2001&lt;br /&gt;
&lt;br /&gt;
AUTHOR&lt;br /&gt;
    Kenneth &amp;lt;kenneth@oeey.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
CREDITS&lt;br /&gt;
    Credits go to me&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Source:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
This is the name&lt;br /&gt;
&lt;br /&gt;
These are module doc strings&lt;br /&gt;
    that give helpful details&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#__version__ = &amp;quot;1.0&amp;quot;&lt;br /&gt;
__version__ = &amp;quot;$Revision: 83492 $&amp;quot;&lt;br /&gt;
__author__ = &amp;quot;Kenneth &amp;lt;kenneth@oeey.com&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
__date__ = &amp;quot;26 February 2001&amp;quot;&lt;br /&gt;
__credits__ = &amp;quot;Credits go to me&amp;quot;&lt;br /&gt;
&lt;br /&gt;
__all__ = [&#039;func1&#039;, &#039;PI&#039;]&lt;br /&gt;
&lt;br /&gt;
PI = 3.141&lt;br /&gt;
&lt;br /&gt;
__copyright__ = &#039;hello license&#039;&lt;br /&gt;
__license__ = &amp;quot;GPL&amp;quot;&lt;br /&gt;
__copyright__ = &amp;quot;Copyright 2007, The Project&amp;quot;&lt;br /&gt;
__maintainer__ = &amp;quot;Ken&amp;quot;&lt;br /&gt;
__email__ = &amp;quot;ken@oeey.com&amp;quot;&lt;br /&gt;
__status__ = &amp;quot;Production&amp;quot;&lt;br /&gt;
&lt;br /&gt;
def func1():&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    This is a doc string&lt;br /&gt;
    for func1&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== pydoc class module ====&lt;br /&gt;
&lt;br /&gt;
Sample:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Help on module class_pydoc:&lt;br /&gt;
&lt;br /&gt;
NAME&lt;br /&gt;
    class_pydoc - This is the name&lt;br /&gt;
&lt;br /&gt;
FILE&lt;br /&gt;
    /root/class_pydoc.py&lt;br /&gt;
&lt;br /&gt;
DESCRIPTION&lt;br /&gt;
    These are module doc strings&lt;br /&gt;
        that give helpful details&lt;br /&gt;
&lt;br /&gt;
CLASSES&lt;br /&gt;
    Toad&lt;br /&gt;
&lt;br /&gt;
    class Toad&lt;br /&gt;
     |  doc string for object&lt;br /&gt;
     |&lt;br /&gt;
     |  Methods defined here:&lt;br /&gt;
     |&lt;br /&gt;
     |  __init___(self, name)&lt;br /&gt;
     |      Constructor&lt;br /&gt;
     |&lt;br /&gt;
     |  instance_function(self)&lt;br /&gt;
     |      Instance Function&lt;br /&gt;
     |&lt;br /&gt;
     |  ----------------------------------------------------------------------&lt;br /&gt;
     |  Class methods defined here:&lt;br /&gt;
     |&lt;br /&gt;
     |  class_function(cls) from __builtin__.classobj&lt;br /&gt;
     |      Class Function&lt;br /&gt;
     |&lt;br /&gt;
     |  ----------------------------------------------------------------------&lt;br /&gt;
     |  Data and other attributes defined here:&lt;br /&gt;
     |&lt;br /&gt;
     |  my_class_attribute = &#039;sample class attribute&#039;&lt;br /&gt;
&lt;br /&gt;
DATA&lt;br /&gt;
    PI = 3.141&lt;br /&gt;
    __author__ = &#039;Kenneth &amp;lt;kenneth@oeey.com&amp;gt;&#039;&lt;br /&gt;
    __copyright__ = &#039;Copyright 2007, The Project&#039;&lt;br /&gt;
    __credits__ = &#039;Credits go to me&#039;&lt;br /&gt;
    __date__ = &#039;26 February 2001&#039;&lt;br /&gt;
    __email__ = &#039;ken@oeey.com&#039;&lt;br /&gt;
    __license__ = &#039;GPL&#039;&lt;br /&gt;
    __maintainer__ = &#039;Ken&#039;&lt;br /&gt;
    __status__ = &#039;Production&#039;&lt;br /&gt;
    __version__ = &#039;1.0&#039;&lt;br /&gt;
&lt;br /&gt;
VERSION&lt;br /&gt;
    1.0&lt;br /&gt;
&lt;br /&gt;
DATE&lt;br /&gt;
    26 February 2001&lt;br /&gt;
&lt;br /&gt;
AUTHOR&lt;br /&gt;
    Kenneth &amp;lt;kenneth@oeey.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
CREDITS&lt;br /&gt;
    Credits go to me&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Code:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
This is the name&lt;br /&gt;
&lt;br /&gt;
These are module doc strings&lt;br /&gt;
    that give helpful details&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
__version__ = &amp;quot;1.0&amp;quot;&lt;br /&gt;
#__version__ = &amp;quot;$Revision: 83492 $&amp;quot;&lt;br /&gt;
__author__ = &amp;quot;Kenneth &amp;lt;kenneth@oeey.com&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
__date__ = &amp;quot;26 February 2001&amp;quot;&lt;br /&gt;
__credits__ = &amp;quot;Credits go to me&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#__all__ = [&#039;func1&#039;, &#039;PI&#039;]&lt;br /&gt;
&lt;br /&gt;
PI = 3.141&lt;br /&gt;
&lt;br /&gt;
__copyright__ = &#039;hello license&#039;&lt;br /&gt;
__license__ = &amp;quot;GPL&amp;quot;&lt;br /&gt;
__copyright__ = &amp;quot;Copyright 2007, The Project&amp;quot;&lt;br /&gt;
__maintainer__ = &amp;quot;Ken&amp;quot;&lt;br /&gt;
__email__ = &amp;quot;ken@oeey.com&amp;quot;&lt;br /&gt;
__status__ = &amp;quot;Production&amp;quot;&lt;br /&gt;
&lt;br /&gt;
class Toad:&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot; doc string for object &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    my_class_attribute = &#039;sample class attribute&#039;&lt;br /&gt;
&lt;br /&gt;
    def __init___(self, name):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot; Constructor &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    def instance_function(self):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot; Instance Function &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    @classmethod&lt;br /&gt;
    def class_function(cls):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot; Class Function &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== username ===&lt;br /&gt;
&lt;br /&gt;
User ID:&lt;br /&gt;
 os.getuid()&lt;br /&gt;
&lt;br /&gt;
User Name:&lt;br /&gt;
 # fails it stdin piped to program&lt;br /&gt;
 os.getlogin()&lt;br /&gt;
&lt;br /&gt;
User Name:&lt;br /&gt;
 import sys&lt;br /&gt;
 import pwd&lt;br /&gt;
 def get_username():&lt;br /&gt;
     return pwd.getpwuid( os.getuid() )[ 0 ]&lt;br /&gt;
&lt;br /&gt;
Environment:&lt;br /&gt;
 os.environ[&#039;USER&#039;]&lt;br /&gt;
&lt;br /&gt;
=== hostname ===&lt;br /&gt;
&lt;br /&gt;
 import socket&lt;br /&gt;
 print(socket.gethostname())&lt;br /&gt;
&lt;br /&gt;
 os.uname()[1]&lt;br /&gt;
&lt;br /&gt;
 hostname = os.system(&#039;hostname&#039;)&lt;br /&gt;
&lt;br /&gt;
=== Networking ===&lt;br /&gt;
&lt;br /&gt;
==== Get Hostname ====&lt;br /&gt;
&lt;br /&gt;
 import socket&lt;br /&gt;
 print(socket.gethostname())&lt;br /&gt;
&lt;br /&gt;
==== Convert hostname to ip address ====&lt;br /&gt;
&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; socket.gethostbyaddr(&#039;demo&#039;)&lt;br /&gt;
 (&#039;demo.oeey.com&#039;, [], [&#039;10.10.10.10&#039;])&lt;br /&gt;
&lt;br /&gt;
/usr/local/bin/whatip: (or nametoip)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
# whatip - convert hostname to ip address&lt;br /&gt;
# author: Kenneth Burgener &amp;lt;kenneth@oeey.com&amp;gt; (FEB 2012)&lt;br /&gt;
#&lt;br /&gt;
&lt;br /&gt;
import socket&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
if len(sys.argv) != 2:&lt;br /&gt;
  print &amp;quot;Convert Hostname to IP Address&amp;quot;&lt;br /&gt;
  print &amp;quot;Usage: %s HOSTNAME&amp;quot; % sys.argv[0].split(&#039;/&#039;)[-1]&lt;br /&gt;
  sys.exit(1)&lt;br /&gt;
&lt;br /&gt;
hostname = sys.argv[1]&lt;br /&gt;
try:&lt;br /&gt;
  result = socket.gethostbyaddr(hostname)&lt;br /&gt;
  print result[2][0]&lt;br /&gt;
except (socket.gaierror, socket.herror) as e:&lt;br /&gt;
  print &amp;quot;Error: Unable to resolve &#039;%s&#039;&amp;quot; % hostname&lt;br /&gt;
  sys.exit(1)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Get Public IP Address ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)&lt;br /&gt;
s.connect((&amp;quot;gmail.com&amp;quot;,80))&lt;br /&gt;
print(s.getsockname()[0])&lt;br /&gt;
s.close()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
networking - Finding local IP addresses using Python&#039;s stdlib - Stack Overflow - http://stackoverflow.com/questions/166506/finding-local-ip-addresses-using-pythons-stdlib&lt;br /&gt;
&lt;br /&gt;
==== Python Network Server ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/python           # This is server.py file&lt;br /&gt;
&lt;br /&gt;
import socket               # Import socket module&lt;br /&gt;
&lt;br /&gt;
s = socket.socket()         # Create a socket object&lt;br /&gt;
host = socket.gethostname() # Get local machine name&lt;br /&gt;
port = 12345                # Reserve a port for your service.&lt;br /&gt;
s.bind((host, port))        # Bind to the port&lt;br /&gt;
&lt;br /&gt;
s.listen(5)                 # Now wait for client connection.&lt;br /&gt;
while True:&lt;br /&gt;
   c, addr = s.accept()     # Establish connection with client.&lt;br /&gt;
   print &#039;Got connection from&#039;, addr&lt;br /&gt;
   c.send(&#039;Thank you for connecting&#039;)&lt;br /&gt;
   c.close()                # Close the connection&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Source: http://www.tutorialspoint.com/python/python_networking.htm&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* 17.2. socket — Low-level networking interface — Python v2.7.5 documentation - http://docs.python.org/2/library/socket.html&lt;br /&gt;
&lt;br /&gt;
==== Python Network Client ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/python           # This is client.py file&lt;br /&gt;
&lt;br /&gt;
import socket               # Import socket module&lt;br /&gt;
&lt;br /&gt;
s = socket.socket()         # Create a socket object&lt;br /&gt;
host = socket.gethostname() # Get local machine name&lt;br /&gt;
port = 12345                # Reserve a port for your service.&lt;br /&gt;
&lt;br /&gt;
s.connect((host, port))&lt;br /&gt;
print s.recv(1024)&lt;br /&gt;
s.close                     # Close the socket when done&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Source: http://www.tutorialspoint.com/python/python_networking.htm&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* 17.2. socket — Low-level networking interface — Python v2.7.5 documentation - http://docs.python.org/2/library/socket.html&lt;br /&gt;
&lt;br /&gt;
=== Run Library Module as Script ===&lt;br /&gt;
&lt;br /&gt;
Run python with -m option:&lt;br /&gt;
 -m mod : run library module as a script (terminates option list)&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
 cat [json_file] | python -m json.tool&lt;br /&gt;
 # same as:&lt;br /&gt;
 cat [json_file] | python /opt/python26/lib/python2.6/json/tool.py&lt;br /&gt;
&lt;br /&gt;
Good for when library is buried deep in the library directories&lt;br /&gt;
&lt;br /&gt;
=== Hex ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hex(10)  # print integer as hex string&lt;br /&gt;
&#039;0xa&#039;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; sys.hexversion  # python version as integer&lt;br /&gt;
33817584&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; hex(sys.hexversion)  # python version as hex&lt;br /&gt;
&#039;0x20403f0&#039;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; print &amp;quot;0x%08x&amp;quot; % sys.hexversion  # python version as hex&lt;br /&gt;
&#039;0x20403f0&#039;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; int(&#039;0xa&#039;, 16)  # hex string to integer&lt;br /&gt;
10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; int(&#039;0a&#039;, 16)  # hex string to integer&lt;br /&gt;
10&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; int(&#039;0xa&#039;, 0)  # hex string to integer auto detected du to &#039;0x&#039;&lt;br /&gt;
10&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Binary ===&lt;br /&gt;
&lt;br /&gt;
Integer to Binary String with Negative Number Support: (2&#039;s complement)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# source: http://www.gossamer-threads.com/lists/python/python/645216&lt;br /&gt;
def bin(x):&lt;br /&gt;
    if x &amp;lt; -32768 or x &amp;gt; 65535:&lt;br /&gt;
        raise Exception(&amp;quot;Out of Range Error: %d&amp;quot; % x)&lt;br /&gt;
    if x &amp;lt; 0:&lt;br /&gt;
        x = 65535 + x + 1&lt;br /&gt;
    bin_str = &#039;&#039;&lt;br /&gt;
    bin_str += &#039;&#039;.join(x &amp;amp; (1 &amp;lt;&amp;lt; i) and &#039;1&#039; or &#039;0&#039; for i in range(15, 11, -1))&lt;br /&gt;
    bin_str += &#039; &#039;&lt;br /&gt;
    bin_str += &#039;&#039;.join(x &amp;amp; (1 &amp;lt;&amp;lt; i) and &#039;1&#039; or &#039;0&#039; for i in range(11, 7, -1))&lt;br /&gt;
    bin_str += &#039; &#039;&lt;br /&gt;
    bin_str += &#039;&#039;.join(x &amp;amp; (1 &amp;lt;&amp;lt; i) and &#039;1&#039; or &#039;0&#039; for i in range(7, 3, -1))&lt;br /&gt;
    bin_str += &#039; &#039;&lt;br /&gt;
    bin_str += &#039;&#039;.join(x &amp;amp; (1 &amp;lt;&amp;lt; i) and &#039;1&#039; or &#039;0&#039; for i in range(3, -1, -1))&lt;br /&gt;
    return bin_str&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Integer to Binary String:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# source: http://www.gossamer-threads.com/lists/python/python/645216&lt;br /&gt;
def bin(x):&lt;br /&gt;
    if x &amp;lt; 0 or x &amp;gt; 65535:&lt;br /&gt;
        raise Exception(&amp;quot;Out of Range Error: %d&amp;quot; % x)&lt;br /&gt;
    bin_str = &#039;&#039;&lt;br /&gt;
    bin_str = &#039;&#039;.join(x &amp;amp; (1 &amp;lt;&amp;lt; i) and &#039;1&#039; or &#039;0&#039; for i in range(15, 7, -1))&lt;br /&gt;
    bin_str = bin_str + &#039; &#039;&lt;br /&gt;
    bin_str = bin_str + &#039;&#039;.join(x &amp;amp; (1 &amp;lt;&amp;lt; i) and &#039;1&#039; or &#039;0&#039; for i in range(7, -1, -1))&lt;br /&gt;
    return bin_str&lt;br /&gt;
&lt;br /&gt;
print bin(0)      # &#039;00000000 00000000&#039;&lt;br /&gt;
print bin(1)      # &#039;00000000 00000001&#039;&lt;br /&gt;
print bin(255)    # &#039;00000000 11111111&#039;&lt;br /&gt;
print bin(256)    # &#039;00000001 00000000&#039;&lt;br /&gt;
print bin(43690)  # &#039;10101010 10101010&#039;&lt;br /&gt;
print bin(65535)  # &#039;11111111 11111111&#039;&lt;br /&gt;
print bin(65536)  # &#039;00000000 00000000&#039; - rolled over to next set!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Integer to Binary:&lt;br /&gt;
 bin(170)  # &#039;0b10101010&#039;&lt;br /&gt;
&lt;br /&gt;
Binary to Integer:&lt;br /&gt;
 int(&#039;10101010&#039;, 2)  # 170&lt;br /&gt;
&lt;br /&gt;
=== bitwise ===&lt;br /&gt;
&lt;br /&gt;
See [[#Binary]]&lt;br /&gt;
&lt;br /&gt;
BitwiseOperators - Python Wiki - http://wiki.python.org/moin/BitwiseOperators&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
The Operators:&lt;br /&gt;
&lt;br /&gt;
x &amp;lt;&amp;lt; y&lt;br /&gt;
    Returns x with the bits shifted to the left by y places (and new bits on the right-hand-side are zeros). This is the same as multiplying x by 2**y. &lt;br /&gt;
x &amp;gt;&amp;gt; y&lt;br /&gt;
    Returns x with the bits shifted to the right by y places. This is the same as //&#039;ing x by 2**y. &lt;br /&gt;
x &amp;amp; y&lt;br /&gt;
    AND - Does a &amp;quot;bitwise and&amp;quot;. Each bit of the output is 1 if the corresponding bit of x AND of y is 1, otherwise it&#039;s 0. &lt;br /&gt;
x | y&lt;br /&gt;
    OR - Does a &amp;quot;bitwise or&amp;quot;. Each bit of the output is 0 if the corresponding bit of x AND of y is 0, otherwise it&#039;s 1. &lt;br /&gt;
~ x&lt;br /&gt;
    Returns the complement of x - the number you get by switching each 1 for a 0 and each 0 for a 1. This is the same as -x - 1. &lt;br /&gt;
x ^ y&lt;br /&gt;
    XOR - Does a &amp;quot;bitwise exclusive or&amp;quot;. Each bit of the output is the same as the corresponding bit in x if that bit in y is 0, and it&#039;s the complement of the bit in x if that bit in y is 1. &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Script Path ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
    # Change directory to where this script lives so we can find relative&lt;br /&gt;
    # paths from here regardless of where the working directory was when we&lt;br /&gt;
    # ran the script.&lt;br /&gt;
    # APP_DIR = os.path.dirname(sys.argv[0])&lt;br /&gt;
    APP_DIR = os.path.dirname(os.path.abspath(sys.argv[0))&lt;br /&gt;
    if APP_DIR:&lt;br /&gt;
        os.chdir(APP_DIR)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 normpath(path)  # Normalize path, eliminating double slashes, etc.&lt;br /&gt;
 abspath(path)   # Return an absolute path&lt;br /&gt;
&lt;br /&gt;
Path to a module: [http://stackoverflow.com/questions/247770/retrieving-python-module-path] (couldn&#039;t fine a_module)&lt;br /&gt;
 import a_module&lt;br /&gt;
 import os&lt;br /&gt;
 path = os.path.dirname(a_module.__file__)&lt;br /&gt;
&lt;br /&gt;
Path to module: [http://stackoverflow.com/questions/50499/in-python-how-do-i-get-the-path-and-name-of-the-file-that-is-currently-executin]&lt;br /&gt;
 import inspect, os&lt;br /&gt;
 print inspect.getfile(inspect.currentframe()) # script filename (usually with path)&lt;br /&gt;
 print os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) # script directory&lt;br /&gt;
&lt;br /&gt;
Even better:&lt;br /&gt;
 print os.path.realpath(__file__)&lt;br /&gt;
 print os.path.dirname(__file__)&lt;br /&gt;
 print os.path.basename(__file__)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
references:&lt;br /&gt;
* http://stackoverflow.com/questions/595305/python-path-of-script&lt;br /&gt;
&lt;br /&gt;
keywords: scriptpath script path program path pathname&lt;br /&gt;
&lt;br /&gt;
=== Singleton ===&lt;br /&gt;
&lt;br /&gt;
GLOBAL OBJECT!&lt;br /&gt;
&lt;br /&gt;
None is a singleton (Python only has one copy of None in the interpreter).&lt;br /&gt;
&lt;br /&gt;
Make your own singleton:&lt;br /&gt;
&lt;br /&gt;
override the new method like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Singleton(object):&lt;br /&gt;
    _instance = None&lt;br /&gt;
    def __new__(cls, *args, **kwargs):&lt;br /&gt;
        if not cls._instance:&lt;br /&gt;
            cls._instance = super(Singleton, cls).__new__(&lt;br /&gt;
                                cls, *args, **kwargs)&lt;br /&gt;
        return cls._instance&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
if __name__ == &#039;__main__&#039;:&lt;br /&gt;
    s1=Singleton()&lt;br /&gt;
    s2=Singleton()&lt;br /&gt;
    if(id(s1)==id(s2)):&lt;br /&gt;
        print &amp;quot;Same&amp;quot;&lt;br /&gt;
    else:&lt;br /&gt;
        print &amp;quot;Different&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Using decorator -implementation from PEP318? Implementing the singleton pattern with a decorator:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def singleton(cls):&lt;br /&gt;
    instances = {}&lt;br /&gt;
    def getinstance():&lt;br /&gt;
        if cls not in instances:&lt;br /&gt;
            instances[cls] = cls()&lt;br /&gt;
        return instances[cls]&lt;br /&gt;
    return getinstance&lt;br /&gt;
&lt;br /&gt;
@singleton&lt;br /&gt;
class MyClass:&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Python and the Singleton Pattern - Stack Overflow - http://stackoverflow.com/questions/42558/python-and-the-singleton-pattern&lt;br /&gt;
&lt;br /&gt;
=== XML ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from xml.dom.minidom import parse, parseString&lt;br /&gt;
&lt;br /&gt;
dom1 = parse(&#039;c:\\temp\\mydata.xml&#039;) # parse an XML file by name&lt;br /&gt;
&lt;br /&gt;
datasource = open(&#039;c:\\temp\\mydata.xml&#039;)&lt;br /&gt;
dom2 = parse(datasource)   # parse an open file&lt;br /&gt;
&lt;br /&gt;
dom3 = parseString(&#039;&amp;lt;myxml&amp;gt;Some data&amp;lt;empty/&amp;gt; some more data&amp;lt;/myxml&amp;gt;&#039;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pretty Print: [http://stackoverflow.com/questions/749796/pretty-printing-xml-in-python]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import xml.dom.minidom&lt;br /&gt;
&lt;br /&gt;
xml = xml.dom.minidom.parse(xml_fname) # or xml.dom.minidom.parseString(xml_string)&lt;br /&gt;
pretty_xml_as_string = xml.toprettyxml()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pretty Print with etree [http://stackoverflow.com/questions/749796/pretty-printing-xml-in-python]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import lxml.etree as etree&lt;br /&gt;
&lt;br /&gt;
x = etree.parse(&amp;quot;filename&amp;quot;)&lt;br /&gt;
print etree.tostring(x, pretty_print = True)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* 19.7. xml.dom.minidom — Lightweight DOM implementation — Python v2.7.3 documentation - http://docs.python.org/library/xml.dom.minidom.html&lt;br /&gt;
* Pretty printing XML in python - Stack Overflow - http://stackoverflow.com/questions/749796/pretty-printing-xml-in-python&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
Simply don&#039;t include self.output.startElement and self.output.endElement for elements you don&#039;t want:&lt;br /&gt;
&lt;br /&gt;
simple_filter_parser.py: (my version of [http://freegeographytools.com/2010/removin-time-data-out-of-a-gpx-or-kml-file-to-make-it-work-right-in-google-earth])&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# this parses out the time element of a gpx for Google Earth&lt;br /&gt;
import os&lt;br /&gt;
import sys&lt;br /&gt;
import optparse&lt;br /&gt;
import fnmatch&lt;br /&gt;
from sys import argv&lt;br /&gt;
import xml.sax, xml.sax.saxutils&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
class my_filter_xml(xml.sax.ContentHandler):&lt;br /&gt;
    def __init__(self, outfile, verbose=False):&lt;br /&gt;
        self.output = xml.sax.saxutils.XMLGenerator(outfile, &#039;utf-8&#039;)&lt;br /&gt;
        self.indent = 0&lt;br /&gt;
        self.ignore = False&lt;br /&gt;
        self.output.startDocument()&lt;br /&gt;
&lt;br /&gt;
    def startElement(self, name, attrs):&lt;br /&gt;
        print &amp;quot; &amp;quot; * self.indent + &amp;quot;start: &amp;quot; + name&lt;br /&gt;
        if attrs.keys():&lt;br /&gt;
            keys = &amp;quot; &amp;quot; * (self.indent + 2) + &amp;quot;attrs:&amp;quot;&lt;br /&gt;
            for key in attrs.keys():&lt;br /&gt;
                keys = keys + &amp;quot; &amp;quot; + key + &amp;quot;=&amp;quot; + attrs[key]&lt;br /&gt;
            print keys&lt;br /&gt;
        self.indent = self.indent + 2&lt;br /&gt;
        #self.output.startElement(name, {})&lt;br /&gt;
        if name == &amp;quot;time&amp;quot;:&lt;br /&gt;
            self.ignore = True&lt;br /&gt;
        #if not self.ignore:&lt;br /&gt;
        self.output.startElement(name, attrs)&lt;br /&gt;
&lt;br /&gt;
    def characters(self, ch):&lt;br /&gt;
        if ch.strip():&lt;br /&gt;
            print &amp;quot; &amp;quot; * self.indent + &amp;quot;ch: &amp;quot; + ch.strip()&lt;br /&gt;
            if not self.ignore:&lt;br /&gt;
                self.output.characters(ch)&lt;br /&gt;
        else:&lt;br /&gt;
            if not self.ignore:&lt;br /&gt;
                self.output.characters(&amp;quot;\n&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    def endElement(self, name):&lt;br /&gt;
        self.indent = self.indent - 2&lt;br /&gt;
        print &amp;quot; &amp;quot; * self.indent + &amp;quot;/end: &amp;quot; + name&lt;br /&gt;
        #if not self.ignore:&lt;br /&gt;
        self.output.endElement(name)&lt;br /&gt;
        if name == &amp;quot;time&amp;quot;:&lt;br /&gt;
            self.ignore = False&lt;br /&gt;
&lt;br /&gt;
if __name__ == &#039;__main__&#039;:&lt;br /&gt;
    source = open(&amp;quot;tracks.gpx&amp;quot;)&lt;br /&gt;
    dest = open(&amp;quot;tracks_out.gpx&amp;quot;, &#039;w+&#039;)&lt;br /&gt;
    xml.sax.parse(source, my_filter_xml(dest, True))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
fixdescriptor.py:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import os&lt;br /&gt;
import sys&lt;br /&gt;
import optparse&lt;br /&gt;
import fnmatch&lt;br /&gt;
from sys import argv&lt;br /&gt;
import xml.sax, xml.sax.saxutils&lt;br /&gt;
&lt;br /&gt;
class fix_descriptor(xml.sax.ContentHandler):&lt;br /&gt;
    def __init__(self, outfile, verbose=False):&lt;br /&gt;
        self._outfile = outfile&lt;br /&gt;
        self._verbose = verbose&lt;br /&gt;
        self.output = xml.sax.saxutils.XMLGenerator(outfile, &#039;utf-8&#039;)&lt;br /&gt;
        self._filter = [ &#039;payload&#039;,&lt;br /&gt;
                         &#039;payloads&#039;,&lt;br /&gt;
                         &#039;file-list&#039;,&lt;br /&gt;
                         &#039;file&#039;,&lt;br /&gt;
                         &#039;checksum&#039; ]&lt;br /&gt;
        self._keep = [ &#039;vib&#039;,&lt;br /&gt;
                       &#039;maintenance-mode&#039; ]&lt;br /&gt;
        self._inside = None&lt;br /&gt;
&lt;br /&gt;
    def startElement(self, name, attrs):&lt;br /&gt;
        # Certain elements are kept unchanged&lt;br /&gt;
        if name in self._keep:&lt;br /&gt;
            if self._verbose:&lt;br /&gt;
                print &#039;%s element start found&#039; % (name)&lt;br /&gt;
            self.output.startElement(name, {})&lt;br /&gt;
            if name == &#039;maintenance-mode&#039;:&lt;br /&gt;
                if self._verbose:&lt;br /&gt;
                    print &#039;inside maintenance-mode&#039;&lt;br /&gt;
                self._inside = name&lt;br /&gt;
            return&lt;br /&gt;
        # Other elements are filtered (removed)&lt;br /&gt;
        elif name in self._filter:&lt;br /&gt;
            if self._verbose:&lt;br /&gt;
                print &#039;%s element start found&#039; % (name)&lt;br /&gt;
            self._inside = name&lt;br /&gt;
            return&lt;br /&gt;
        self.output.startElement(name, attrs)&lt;br /&gt;
&lt;br /&gt;
    def characters(self, ch):&lt;br /&gt;
        if self._inside == &#039;maintenance-mode&#039;:&lt;br /&gt;
            if self._verbose:&lt;br /&gt;
                print &#039;new content for maintenance-mode&#039;&lt;br /&gt;
            self.output.characters(&#039;false&#039;)&lt;br /&gt;
        elif self._inside not in self._filter:&lt;br /&gt;
            self.output.characters(ch)&lt;br /&gt;
&lt;br /&gt;
    def endElement(self, name):&lt;br /&gt;
        # If it&#039;s not a checksum element, only print it&lt;br /&gt;
        if name in self._filter + self._keep:&lt;br /&gt;
            self._inside = None&lt;br /&gt;
            if self._verbose:&lt;br /&gt;
                print &#039;%s element end found&#039; % (name)&lt;br /&gt;
            if name in self._filter:&lt;br /&gt;
                return&lt;br /&gt;
        self.output.endElement(name)&lt;br /&gt;
&lt;br /&gt;
if __name__ == &#039;__main__&#039;:&lt;br /&gt;
    #&lt;br /&gt;
    parser = optparse.OptionParser(usage=&#039;%prog ...&#039;)&lt;br /&gt;
    parser.add_option(&#039;-v&#039;, &#039;--verbose&#039;,&lt;br /&gt;
                       action=&#039;store_true&#039;, default=False,&lt;br /&gt;
                       help=&#039;Print more information.&#039;)&lt;br /&gt;
    parser.add_option(&#039;--input-xml&#039;,&lt;br /&gt;
                       type=&#039;str&#039;, default=&#039;descriptor.xml&#039;,&lt;br /&gt;
                       help=&#039;Name of input XML [default: %default]&#039;)&lt;br /&gt;
    parser.add_option(&#039;--output-xml&#039;,&lt;br /&gt;
                       type=&#039;str&#039;, default=&#039;fixed_descriptor.xml&#039;,&lt;br /&gt;
                       help=&#039;Name of output XML [default: %default]&#039;)&lt;br /&gt;
    opts, args = parser.parse_args(argv[1:])&lt;br /&gt;
    source = open(opts.input_xml)&lt;br /&gt;
    dest = open(opts.output_xml, &#039;w+&#039;)&lt;br /&gt;
    xml.sax.parse(source, fix_descriptor(dest, opts.verbose))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--&lt;br /&gt;
&lt;br /&gt;
Simple read and output parsing:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import os&lt;br /&gt;
import sys&lt;br /&gt;
import optparse&lt;br /&gt;
import fnmatch&lt;br /&gt;
from sys import argv&lt;br /&gt;
import xml.sax, xml.sax.saxutils&lt;br /&gt;
&lt;br /&gt;
class fix_descriptor(xml.sax.ContentHandler):&lt;br /&gt;
    def __init__(self, outfile, verbose=False):&lt;br /&gt;
        self._outfile = outfile&lt;br /&gt;
        self._verbose = verbose&lt;br /&gt;
        self.output = xml.sax.saxutils.XMLGenerator(outfile, &#039;utf-8&#039;)&lt;br /&gt;
        self._inside = None&lt;br /&gt;
&lt;br /&gt;
    def startElement(self, name, attrs):&lt;br /&gt;
        # attrs.items() is a list of tuples (name, value)&lt;br /&gt;
        print &amp;quot;start:&amp;quot;, name, &amp;quot;/&amp;quot;, attrs.items()&lt;br /&gt;
        self.output.startElement(name, attrs)&lt;br /&gt;
&lt;br /&gt;
    def characters(self, ch):&lt;br /&gt;
        print &amp;quot;char:&amp;quot;, self._inside, &amp;quot;/&amp;quot;, ch&lt;br /&gt;
        self.output.characters(ch)&lt;br /&gt;
&lt;br /&gt;
    def endElement(self, name):&lt;br /&gt;
        print &amp;quot;end:&amp;quot;, name&lt;br /&gt;
        self.output.endElement(name)&lt;br /&gt;
&lt;br /&gt;
if __name__ == &#039;__main__&#039;:&lt;br /&gt;
    parser = optparse.OptionParser(usage=&#039;%prog ...&#039;)&lt;br /&gt;
    parser.add_option(&#039;-v&#039;, &#039;--verbose&#039;,&lt;br /&gt;
                       action=&#039;store_true&#039;, default=False,&lt;br /&gt;
                       help=&#039;Print more information.&#039;)&lt;br /&gt;
    parser.add_option(&#039;--input-xml&#039;,&lt;br /&gt;
                       type=&#039;str&#039;, default=&#039;descriptor.xml&#039;,&lt;br /&gt;
                       help=&#039;Name of input XML [default: %default]&#039;)&lt;br /&gt;
    parser.add_option(&#039;--output-xml&#039;,&lt;br /&gt;
                       type=&#039;str&#039;, default=&#039;fixed_descriptor.xml&#039;,&lt;br /&gt;
                       help=&#039;Name of output XML [default: %default]&#039;)&lt;br /&gt;
    opts, args = parser.parse_args(argv[1:])&lt;br /&gt;
    source = open(opts.input_xml)&lt;br /&gt;
    dest = open(opts.output_xml, &#039;w+&#039;)&lt;br /&gt;
    xml.sax.parse(source, fix_descriptor(dest, opts.verbose))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Unicode ===&lt;br /&gt;
&lt;br /&gt;
Unicode string:&lt;br /&gt;
 u&#039;Hello World !&#039;&lt;br /&gt;
&lt;br /&gt;
Raw Unicode string:&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; ur&#039;Hello\u0020World !&#039;&lt;br /&gt;
 u&#039;Hello World !&#039;&lt;br /&gt;
&lt;br /&gt;
Convert:&lt;br /&gt;
 u = u&#039;hello\xe4&#039;&lt;br /&gt;
 str(u)  # UnicodeEncodeError: &#039;ascii&#039; codec can&#039;t encode character u&#039;\xe4&#039; in position 5: ordinal not in range(128)&lt;br /&gt;
 s = u.encode(&#039;utf8&#039;)  # &#039;s&#039; is now type str&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* Introduction to Unicode Strings - http://docs.python.org/tutorial/introduction.html#unicode-strings&lt;br /&gt;
&lt;br /&gt;
=== Zip ===&lt;br /&gt;
&lt;br /&gt;
See [[Python/Zip]]&lt;br /&gt;
&lt;br /&gt;
=== signals ===&lt;br /&gt;
&lt;br /&gt;
 signal.SIGTERM  : kill  [pid]&lt;br /&gt;
 signal.SIGALRM  : kill -ALRM  [pid]&lt;br /&gt;
 signal.SIGHUP   : kill -HUP  [pid]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import signal, os&lt;br /&gt;
&lt;br /&gt;
def handler(signum, frame):&lt;br /&gt;
    print &#039;Signal handler called with signal&#039;, signum&lt;br /&gt;
    raise IOError(&amp;quot;Couldn&#039;t open device!&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
# Set the signal handler and a 5-second alarm&lt;br /&gt;
signal.signal(signal.SIGALRM, handler)&lt;br /&gt;
signal.alarm(5)&lt;br /&gt;
&lt;br /&gt;
# This open() may hang indefinitely&lt;br /&gt;
fd = os.open(&#039;/dev/ttyS0&#039;, os.O_RDWR)&lt;br /&gt;
&lt;br /&gt;
signal.alarm(0)          # Disable the alarm&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: use signal.SIGTERM to handle &amp;quot;kill&amp;quot; command&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* 17.4. signal — Set handlers for asynchronous events — Python v2.7.5 documentation - http://docs.python.org/2/library/signal.html&lt;br /&gt;
&lt;br /&gt;
==== Ctrl+C ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
import signal&lt;br /&gt;
import sys&lt;br /&gt;
def signal_handler(signal, frame):&lt;br /&gt;
        print &#039;You pressed Ctrl+C!&#039;&lt;br /&gt;
        sys.exit(0)&lt;br /&gt;
signal.signal(signal.SIGINT, signal_handler)&lt;br /&gt;
print &#039;Press Ctrl+C&#039;&lt;br /&gt;
&lt;br /&gt;
# linux only:&lt;br /&gt;
signal.pause()&lt;br /&gt;
&lt;br /&gt;
# windows alternative:&lt;br /&gt;
#import time&lt;br /&gt;
#time.sleep(60)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* control - How do I capture SIGINT in Python? - Stack Overflow - http://stackoverflow.com/questions/1112343/how-do-i-capture-sigint-in-python&lt;br /&gt;
&lt;br /&gt;
==== Non-blocking raw_input for Python ====&lt;br /&gt;
&lt;br /&gt;
Non-blocking raw_input for Python:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# source: http://www.garyrobinson.net/2009/10/non-blocking-raw_input-for-python.html&lt;br /&gt;
&lt;br /&gt;
import signal&lt;br /&gt;
&lt;br /&gt;
class AlarmException(Exception):&lt;br /&gt;
    pass&lt;br /&gt;
&lt;br /&gt;
def alarmHandler(signum, frame):&lt;br /&gt;
    raise AlarmException&lt;br /&gt;
&lt;br /&gt;
def nonBlockingRawInput(prompt=&#039;&#039;, timeout=20):&lt;br /&gt;
    signal.signal(signal.SIGALRM, alarmHandler)&lt;br /&gt;
    signal.alarm(timeout)&lt;br /&gt;
    try:&lt;br /&gt;
        text = raw_input(prompt)&lt;br /&gt;
        signal.alarm(0)&lt;br /&gt;
        return text&lt;br /&gt;
    except AlarmException:&lt;br /&gt;
        print &#039;\nPrompt timeout. Continuing...&#039;&lt;br /&gt;
    signal.signal(signal.SIGALRM, signal.SIG_IGN)&lt;br /&gt;
    return &#039;&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== email ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import smtplib&lt;br /&gt;
import email.mime.text&lt;br /&gt;
&lt;br /&gt;
msg_text = &amp;quot;Hello World&amp;quot;&lt;br /&gt;
msg = email.mime.text.MIMEText(msg_text)&lt;br /&gt;
&lt;br /&gt;
# me == the sender&#039;s email address&lt;br /&gt;
# you == the recipient&#039;s email address&lt;br /&gt;
msg[&#039;Subject&#039;] = &#039;The contents of %s&#039; % textfile&lt;br /&gt;
msg[&#039;From&#039;] = me&lt;br /&gt;
msg[&#039;To&#039;] = you&lt;br /&gt;
&lt;br /&gt;
# Send the message via our own SMTP server, but don&#039;t include the&lt;br /&gt;
# envelope header.&lt;br /&gt;
s = smtplib.SMTP(&#039;localhost&#039;)&lt;br /&gt;
s.sendmail(me, [you], msg.as_string())&lt;br /&gt;
s.quit()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
my nagios fake /bin/mail:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
&lt;br /&gt;
import smtplib&lt;br /&gt;
import email.mime.text&lt;br /&gt;
import optparse&lt;br /&gt;
import os&lt;br /&gt;
import sys&lt;br /&gt;
import pwd&lt;br /&gt;
&lt;br /&gt;
os.system(&#039;logger mail called&#039;)&lt;br /&gt;
&lt;br /&gt;
parser = optparse.OptionParser()&lt;br /&gt;
parser.add_option(&lt;br /&gt;
    &#039;-s&#039;, &#039;--subject&#039;,&lt;br /&gt;
    help=&#039;Subject&#039;,&lt;br /&gt;
    default=&amp;quot;&amp;quot;)&lt;br /&gt;
parser.add_option(&lt;br /&gt;
    &#039;-t&#039;, &#039;--to&#039;,&lt;br /&gt;
    help=&#039;To&#039;,&lt;br /&gt;
    dest=&amp;quot;send_to&amp;quot;,&lt;br /&gt;
    default=None)&lt;br /&gt;
parser.add_option(&lt;br /&gt;
    &#039;-f&#039;, &#039;--from&#039;,&lt;br /&gt;
    help=&#039;From&#039;,&lt;br /&gt;
    dest=&amp;quot;send_from&amp;quot;,&lt;br /&gt;
    default=None)&lt;br /&gt;
parser.add_option(&lt;br /&gt;
    &#039;-S&#039;, &#039;--server&#039;,&lt;br /&gt;
    help=&#039;server&#039;,&lt;br /&gt;
    default=&amp;quot;prime&amp;quot;)&lt;br /&gt;
(options, args) = parser.parse_args()&lt;br /&gt;
&lt;br /&gt;
def get_username():&lt;br /&gt;
    return pwd.getpwuid( os.getuid() )[ 0 ]&lt;br /&gt;
&lt;br /&gt;
if options.send_to:&lt;br /&gt;
    send_to = options.send_to&lt;br /&gt;
else:&lt;br /&gt;
    if len(args) == 1:&lt;br /&gt;
        send_to = args[0]&lt;br /&gt;
    else:&lt;br /&gt;
        parser.print_help()&lt;br /&gt;
        sys.exit(1)&lt;br /&gt;
&lt;br /&gt;
if options.send_from:&lt;br /&gt;
    send_from = options.send_from&lt;br /&gt;
else:&lt;br /&gt;
    username = get_username()&lt;br /&gt;
    hostname = os.uname()[1]&lt;br /&gt;
    send_from = username + &amp;quot;@&amp;quot; + hostname&lt;br /&gt;
&lt;br /&gt;
msg_text = sys.stdin.read()&lt;br /&gt;
msg = email.mime.text.MIMEText(msg_text)&lt;br /&gt;
&lt;br /&gt;
msg[&#039;Subject&#039;] = options.subject&lt;br /&gt;
msg[&#039;From&#039;] = send_from&lt;br /&gt;
msg[&#039;To&#039;] = send_to&lt;br /&gt;
&lt;br /&gt;
s = smtplib.SMTP(options.server)&lt;br /&gt;
s.sendmail(send_from, [send_to], msg.as_string())&lt;br /&gt;
s.quit()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Authenticated (with gmail):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import smtplib&lt;br /&gt;
import email.mime.text&lt;br /&gt;
&lt;br /&gt;
# from_email = &amp;quot;kenneth@demo.oeey.com&amp;quot;&lt;br /&gt;
# to_email = &amp;quot;kenneth@demo.oeey.com&amp;quot;&lt;br /&gt;
from_email = &amp;quot;Kenneth Burgener &amp;lt;kenneth@demo.oeey.com&amp;gt;&amp;quot;&lt;br /&gt;
to_emails = [&amp;quot;Kenneth Burgener &amp;lt;kenneth@demo.oeey.com&amp;gt;&amp;quot;, &amp;quot;Kenneth Cell &amp;lt;xxx@xxx.com&amp;gt;&amp;quot;]&lt;br /&gt;
&lt;br /&gt;
msg_text = &amp;quot;hello world&amp;quot;&lt;br /&gt;
msg = email.mime.text.MIMEText(msg_text)&lt;br /&gt;
msg[&#039;Subject&#039;] = &#039;Test text&#039;&lt;br /&gt;
msg[&#039;From&#039;] = from_email&lt;br /&gt;
# msg[&#039;To&#039;] = to_email&lt;br /&gt;
msg[&#039;To&#039;] = &amp;quot;, &amp;quot;.join(to_emails)&lt;br /&gt;
# s = smtplib.SMTP(&#039;localhost&#039;)&lt;br /&gt;
print &amp;quot;sending...&amp;quot;&lt;br /&gt;
s = smtplib.SMTP_SSL(&#039;smtp.gmail.com&#039;, &#039;465&#039;)&lt;br /&gt;
s.login(&#039;xxx&#039;, &#039;xxx&#039;)&lt;br /&gt;
# s.sendmail(from_email, [to_email], msg.as_string())&lt;br /&gt;
s.sendmail(from_email, to_emails, msg.as_string())&lt;br /&gt;
s.quit()&lt;br /&gt;
print &amp;quot;sent!&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Source: &lt;br /&gt;
* 20.12. smtplib — SMTP protocol client — Python v2.7.5 documentation - http://docs.python.org/2/library/smtplib.html&lt;br /&gt;
* 18.1.11. email: Examples — Python v2.7.5 documentation - http://docs.python.org/2/library/email-examples.html&lt;br /&gt;
&lt;br /&gt;
=== pprint ===&lt;br /&gt;
&lt;br /&gt;
8.18. pprint — Data pretty printer — Python v2.7.5 documentation - http://docs.python.org/2/library/pprint.html&lt;br /&gt;
&lt;br /&gt;
 import pprint&lt;br /&gt;
 pprint.pprint(myVar)&lt;br /&gt;
&lt;br /&gt;
 import pprint&lt;br /&gt;
 pp = pprint.PrettyPrinter(indent=4)&lt;br /&gt;
 pp.pprint(myVar)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Note: Useless on objects!&lt;br /&gt;
&lt;br /&gt;
Dump object:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def dumpobject(obj):&lt;br /&gt;
    print &amp;quot;&amp;lt;&amp;lt;&amp;lt;---&amp;quot;&lt;br /&gt;
    print type(obj), obj.__class__.__name__&lt;br /&gt;
    for attr in dir(obj):&lt;br /&gt;
        if attr[0] == &amp;quot;_&amp;quot;: continue  # ignore under/dunder properties&lt;br /&gt;
        if str(type(getattr(obj, attr))) == &amp;quot;&amp;lt;type &#039;instancemethod&#039;&amp;gt;&amp;quot;:&lt;br /&gt;
            print attr, &amp;quot;: METHOD&amp;quot;&lt;br /&gt;
        else:&lt;br /&gt;
            print attr, &amp;quot;:&amp;quot;, type(getattr(obj, attr)), &amp;quot;:&amp;quot;, getattr(obj, attr)&lt;br /&gt;
    print &amp;quot;END ---&amp;gt;&amp;gt;&amp;gt;&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Curses ===&lt;br /&gt;
&lt;br /&gt;
Curses Programming with Python — Python v3.3.2 documentation - http://docs.python.org/3/howto/curses.html&lt;br /&gt;
&lt;br /&gt;
&amp;quot;The curses library supplies a terminal-independent screen-painting and keyboard-handling facility for text-based terminals; such terminals include VT100s, the Linux console, and the simulated terminal provided by various programs. Display terminals support various control codes to perform common operations such as moving the cursor, scrolling the screen, and erasing areas. Different terminals use widely differing codes, and often have their own minor quirks.&lt;br /&gt;
&lt;br /&gt;
In a world of graphical displays, one might ask “why bother”? It’s true that character-cell display terminals are an obsolete technology, but there are niches in which being able to do fancy things with them are still valuable. One niche is on small-footprint or embedded Unixes that don’t run an X server. Another is tools such as OS installers and kernel configurators that may have to run before any graphical support is available.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
Thread from Utah Python User&#039;s Group mailing list:&lt;br /&gt;
&lt;br /&gt;
-&lt;br /&gt;
&lt;br /&gt;
Hello, I am trying to learn more about curses in python for a desktop application. Does anybody have any recommendations on tutorials or documentation? &lt;br /&gt;
&lt;br /&gt;
-Corban&lt;br /&gt;
&lt;br /&gt;
-&lt;br /&gt;
&lt;br /&gt;
We&#039;ve use urwid at work. Seems to be a good approach if you aren&#039;t already tied to something. Learning curve can be a bit steep (well, compared to what you&#039;d think it should be). Good luck!&lt;br /&gt;
&lt;br /&gt;
 http://excess.org/urwid/&lt;br /&gt;
&lt;br /&gt;
Gabriel Gunderson&lt;br /&gt;
&lt;br /&gt;
-&lt;br /&gt;
&lt;br /&gt;
This video series looks pretty good:&lt;br /&gt;
&lt;br /&gt;
http://www.youtube.com/user/pythoncursestutorial?feature=watch&lt;br /&gt;
&lt;br /&gt;
Official HOWTOs from the python.org site:&lt;br /&gt;
&lt;br /&gt;
http://docs.python.org/2/howto/curses.html&lt;br /&gt;
http://docs.python.org/3/howto/curses.html&lt;br /&gt;
&lt;br /&gt;
As Gabe mentioned, there are other libraries that provide similar or&lt;br /&gt;
greater functionality, so if you aren&#039;t doing this specifically to&lt;br /&gt;
learn curses, it&#039;s worth at least looking at a few of them to compare.&lt;br /&gt;
&lt;br /&gt;
There&#039;s a brief comparison of three possibilities here:&lt;br /&gt;
&lt;br /&gt;
http://stackoverflow.com/questions/8349085/python-ncurses-cdk-urwid-difference&lt;br /&gt;
&lt;br /&gt;
Daniel Fackrell&lt;br /&gt;
&lt;br /&gt;
-&lt;br /&gt;
&lt;br /&gt;
Here&#039;s another option that looks promising:&lt;br /&gt;
&lt;br /&gt;
https://pypi.python.org/pypi/blessings/&lt;br /&gt;
&lt;br /&gt;
Daniel Fackrell&lt;br /&gt;
&lt;br /&gt;
=== dialog ===&lt;br /&gt;
&lt;br /&gt;
pythondialog - http://pythondialog.sourceforge.net/&lt;br /&gt;
: &amp;quot;pythondialog is a Python wrapper for the dialog utility originally written by Savio Lam, and later rewritten by Thomas E. Dickey. Its purpose is to provide an easy to use, pythonic and comprehensive Python interface to dialog. This allows one to make simple text-mode user interfaces on Unix-like systems (including Linux). &amp;quot;&lt;br /&gt;
&lt;br /&gt;
Note: The latest versions (2.12 and later) only support Python 3; users who really want to stick to Python 2 should use version 2.11 for now.&lt;br /&gt;
&lt;br /&gt;
Install:&lt;br /&gt;
 # latest:&lt;br /&gt;
 # wget http://sourceforge.net/projects/pythondialog/files/latest/download?source=dlp&lt;br /&gt;
&lt;br /&gt;
 wget http://sourceforge.net/projects/pythondialog/files/pythondialog/2.11/python2-pythondialog-2.11.tar.gz/download&lt;br /&gt;
 tar -zvxf python2-pythondialog-2.11.tar.gz&lt;br /&gt;
 cd pythondialog-2.11&lt;br /&gt;
&lt;br /&gt;
 import dialog&lt;br /&gt;
 d = dialog.Dialog()&lt;br /&gt;
 if d.yesno(&amp;quot;Continue?&amp;quot;) == d.DIALOG_OK:&lt;br /&gt;
  print &amp;quot;Continuing...&amp;quot;&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
My solution&lt;br /&gt;
&lt;br /&gt;
kiloforce / dialog / source / — Bitbucket - https://bitbucket.org/kiloforce/dialog&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot; Wrapper for Linux &#039;dialog&#039; command &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
__author__ = &amp;quot;Kenneth Burgener &amp;lt;kenneth@k.ttak.org&amp;gt;&amp;quot;&lt;br /&gt;
__copyright__ = &amp;quot;(c) 2013&amp;quot;&lt;br /&gt;
__date__ = &amp;quot;$Sep 27, 2013$&amp;quot;&lt;br /&gt;
__version__ = &amp;quot;1.0&amp;quot;&lt;br /&gt;
__credits__ = r&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
XXXXXXXXXXXXXXXXXX&lt;br /&gt;
X Dialog Wrapper #&lt;br /&gt;
##################&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
import subprocess&lt;br /&gt;
import time&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
class Dialog():&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot; Python wrapper for Linux &#039;dialog&#039; command&lt;br /&gt;
&lt;br /&gt;
    dialog - display dialog boxes from shell scripts&lt;br /&gt;
&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import dialog&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; dlg = dialog.Dialog()&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; rc = dlg.msgbox(&#039;hello world&#039;)&lt;br /&gt;
&lt;br /&gt;
    Return codes:&lt;br /&gt;
        YES = 0&lt;br /&gt;
        OK = 0&lt;br /&gt;
        EXIT = 0&lt;br /&gt;
        NO = 1&lt;br /&gt;
        CANCEL = 1&lt;br /&gt;
        ESC = 255&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    YES = 0&lt;br /&gt;
    OK = 0&lt;br /&gt;
    EXIT = 0&lt;br /&gt;
    NO = 1&lt;br /&gt;
    CANCEL = 1&lt;br /&gt;
    ESC = 255&lt;br /&gt;
&lt;br /&gt;
    def __init__(self):&lt;br /&gt;
        rc = self._exe(&#039;which dialog &amp;gt; /dev/null&#039;)[0]&lt;br /&gt;
        if rc != 0:&lt;br /&gt;
            print &amp;quot;Error: failed to find Linux dialog command&amp;quot;&lt;br /&gt;
            sys.exit(1)&lt;br /&gt;
&lt;br /&gt;
    def _exe(self, cmd, strip=True):&lt;br /&gt;
        p = subprocess.Popen(cmd, shell=True, stderr=subprocess.PIPE)&lt;br /&gt;
        output = &amp;quot;\n&amp;quot;.join(p.stderr.readlines())&lt;br /&gt;
        if strip:&lt;br /&gt;
            output = output.strip()&lt;br /&gt;
        rc = p.wait()&lt;br /&gt;
        return (rc, output)&lt;br /&gt;
&lt;br /&gt;
    def rc_to_str(self, rc):&lt;br /&gt;
        if rc == 0:&lt;br /&gt;
            return &amp;quot;YES&amp;quot;&lt;br /&gt;
        elif rc == 1:&lt;br /&gt;
            return &amp;quot;NO&amp;quot;&lt;br /&gt;
        elif rc == 255:&lt;br /&gt;
            return &amp;quot;ESX&amp;quot;&lt;br /&gt;
        else:&lt;br /&gt;
            raise Exception(&amp;quot;Unknown return code: %s&amp;quot; % rc)&lt;br /&gt;
&lt;br /&gt;
    def clear(self):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Clear screen&lt;br /&gt;
&lt;br /&gt;
        Example:&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt; dialog.clear()&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        rc, output = self._exe(&#039;clear&#039;)&lt;br /&gt;
        assert rc in (0,), &amp;quot;clear rc&amp;quot;&lt;br /&gt;
        return rc&lt;br /&gt;
&lt;br /&gt;
    def msgbox(self, msg):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Simple message box&lt;br /&gt;
&lt;br /&gt;
        @param msg (str) = display message&lt;br /&gt;
        @return: rc (int)&lt;br /&gt;
&lt;br /&gt;
        Example:&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt; rc = dialog.msgbox(&#039;hello world&#039;)&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        rc, output = self._exe(&#039;dialog --msgbox &amp;quot;{msg}&amp;quot; 0 0&#039;.format(msg=msg))&lt;br /&gt;
        assert rc in (self.YES, self.ESC), &amp;quot;msgbox rc&amp;quot;&lt;br /&gt;
        return rc&lt;br /&gt;
&lt;br /&gt;
    def yesno(self, msg):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Yes/No dialog&lt;br /&gt;
&lt;br /&gt;
        @param msg (str) = display message&lt;br /&gt;
        @return: rc (int)&lt;br /&gt;
&lt;br /&gt;
        Example:&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt; rc = dialog.yesno(&#039;continue&#039;)&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        rc, output = self._exe(&#039;dialog --yesno &amp;quot;{msg}&amp;quot; 0 0&#039;.format(msg=msg))&lt;br /&gt;
        assert rc in (self.YES, self.NO, self.ESC), &amp;quot;yesno rc&amp;quot;&lt;br /&gt;
        return rc&lt;br /&gt;
&lt;br /&gt;
    def infobox(self, msg):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Dialog that does not wait for user&#039;s response&lt;br /&gt;
        (do your own pause)&lt;br /&gt;
&lt;br /&gt;
        @param msg (str) = display message&lt;br /&gt;
        @return: rc (int) always zero&lt;br /&gt;
&lt;br /&gt;
        Example:&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt; for i in range(10):&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt;   dialog.infobox(&#039;counting: &#039; + str(i))&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt;   time.sleep(3)&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        rc, output = self._exe(&#039;dialog --infobox &amp;quot;{msg}&amp;quot; 0 0&#039;.format(msg=msg))&lt;br /&gt;
        assert rc in (self.YES,), &amp;quot;infobox rc&amp;quot;&lt;br /&gt;
        return rc&lt;br /&gt;
&lt;br /&gt;
    def inputbox(self, msg):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Get user input&lt;br /&gt;
&lt;br /&gt;
        @param msg (str) = display message&lt;br /&gt;
        @return: rc (int), output (str/None)&lt;br /&gt;
&lt;br /&gt;
        Example:&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt; rc, output = dialog.inputbox(&#039;name:&#039;)&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        rc, output = self._exe(&#039;dialog --inputbox &amp;quot;{msg}&amp;quot; 0 0&#039;.format(msg=msg))&lt;br /&gt;
        assert rc in (self.YES, self.NO, self.ESC), &amp;quot;inputbox rc&amp;quot;&lt;br /&gt;
        if not output:&lt;br /&gt;
            output = None&lt;br /&gt;
        return rc, output&lt;br /&gt;
&lt;br /&gt;
    def textbox(self, filename):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Display a file&lt;br /&gt;
&lt;br /&gt;
        @param filename (str) = file to display&lt;br /&gt;
        @return: rc (int)&lt;br /&gt;
&lt;br /&gt;
        Example:&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt; dialog.textbox(&#039;/etc/passwd&#039;)&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        rc, output = self._exe(&#039;dialog --textbox {filename} 0 0&#039;.format(filename=filename))&lt;br /&gt;
        assert rc in (self.YES, self.ESC), &amp;quot;textbox rc&amp;quot;&lt;br /&gt;
        return rc&lt;br /&gt;
&lt;br /&gt;
    def menu(self, msg, item_list):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Single selection checkbox menu&lt;br /&gt;
&lt;br /&gt;
        @param msg (str) = display message&lt;br /&gt;
        @param item_list (str list) = list of items to display&lt;br /&gt;
        @return: rc (int), selection (int/None)&lt;br /&gt;
&lt;br /&gt;
        Example:&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt; rc, selection = dialog.menu(&#039;Select multiple options:&#039;,&lt;br /&gt;
        ...     (&#039;option 1&#039;, &#039;option 2&#039;))&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        item_str = &amp;quot;&amp;quot;&lt;br /&gt;
        for i in range(len(item_list)):&lt;br /&gt;
            item_str += &amp;quot; &amp;quot; + str(i+1) + &amp;quot; \&amp;quot;&amp;quot; + item_list[i] + &amp;quot;\&amp;quot;&amp;quot;&lt;br /&gt;
        rc, output = self._exe(&#039;dialog --menu &amp;quot;{msg}&amp;quot; 0 0 0 {item_str}&#039;.format(msg=msg, item_str=item_str))&lt;br /&gt;
        if output:&lt;br /&gt;
            selection = int(output)&lt;br /&gt;
        else:&lt;br /&gt;
            selection = None&lt;br /&gt;
        assert rc in (self.YES, self.NO, self.ESC), &amp;quot;menu rc&amp;quot;&lt;br /&gt;
        return rc, selection&lt;br /&gt;
&lt;br /&gt;
    def checklist(self, msg, item_list, checked_list=None):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Multiple selection checkbox menu&lt;br /&gt;
&lt;br /&gt;
        @param msg (str) = display message&lt;br /&gt;
        @param item_list (str list) = list of items&lt;br /&gt;
        @param checked_list (int list) = default items to check&lt;br /&gt;
        @return: rc (int), selections (int list/None)&lt;br /&gt;
&lt;br /&gt;
        Example:&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt; rc, selections = dialog.checklist(&#039;Select multiple options:&#039;,&lt;br /&gt;
        ...     (&#039;option 1&#039;, &#039;option 2&#039;)&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        item_str = &amp;quot;&amp;quot;&lt;br /&gt;
        assert type(item_list) in (type(None), type(()), type([])), &amp;quot;checklist: item_list must be a list&amp;quot;&lt;br /&gt;
        assert type(checked_list) in (type(None), type(()), type([])), &amp;quot;checklist: checked_list must be a list&amp;quot;&lt;br /&gt;
        for i in range(len(item_list)):&lt;br /&gt;
            item_str += &amp;quot; &amp;quot; + str(i+1) + &amp;quot; \&amp;quot;&amp;quot; + item_list[i] + &amp;quot;\&amp;quot;&amp;quot;&lt;br /&gt;
            if checked_list and i+1 in checked_list:&lt;br /&gt;
                item_str += &amp;quot; on&amp;quot;&lt;br /&gt;
            else:&lt;br /&gt;
                item_str += &amp;quot; off&amp;quot;&lt;br /&gt;
        rc, output = self._exe(&#039;dialog --checklist &amp;quot;{msg}&amp;quot; 0 0 0 {item_str}&#039;.format(msg=msg, item_str=item_str))&lt;br /&gt;
        print item_str&lt;br /&gt;
        selections = []&lt;br /&gt;
        for choice in output.split(&#039;&amp;quot;&#039;):&lt;br /&gt;
            if choice.strip():&lt;br /&gt;
                selections.append(int(choice))&lt;br /&gt;
        if selections:&lt;br /&gt;
            selections = tuple(selections)&lt;br /&gt;
        else:&lt;br /&gt;
            selections = None&lt;br /&gt;
        assert rc in (self.YES, self.NO, self.ESC), &amp;quot;checklist rc&amp;quot;&lt;br /&gt;
        return rc, selections&lt;br /&gt;
&lt;br /&gt;
    def radiolist(self, msg, item_list, checked_item=None):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Single selection radio menu, with default&lt;br /&gt;
&lt;br /&gt;
        @param msg (str) = display message&lt;br /&gt;
        @param item_list (str list) = list of items&lt;br /&gt;
        @param checked_item (int) = default item to select&lt;br /&gt;
        @return: rc (int), selection (int)&lt;br /&gt;
&lt;br /&gt;
        Example:&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt; rc, selection = dialog.radiolist(&#039;Select one option:&#039;,&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt;     (&#039;option 1&#039;, &#039;option 2&#039;), 2)&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        item_str = &amp;quot;&amp;quot;&lt;br /&gt;
        for i in range(len(item_list)):&lt;br /&gt;
            item_str += &amp;quot; &amp;quot; + str(i+1) + &amp;quot; \&amp;quot;&amp;quot; + item_list[i] + &amp;quot;\&amp;quot;&amp;quot;&lt;br /&gt;
            if checked_item and i+1 == int(checked_item):&lt;br /&gt;
                item_str += &amp;quot; on&amp;quot;&lt;br /&gt;
            else:&lt;br /&gt;
                item_str += &amp;quot; off&amp;quot;&lt;br /&gt;
        rc, selection = self._exe(&#039;dialog --radiolist &amp;quot;{msg}&amp;quot; 0 0 0 {item_str}&#039;.format(msg=msg, item_str=item_str))&lt;br /&gt;
        if not selection:&lt;br /&gt;
            selection = None&lt;br /&gt;
        assert rc in (self.YES, self.NO, self.ESC), &amp;quot;radiolist rc&amp;quot;&lt;br /&gt;
        return rc, selection&lt;br /&gt;
&lt;br /&gt;
    def gauge(self, msg, percent):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Progress bar (does not wait for user&#039;s input)&lt;br /&gt;
&lt;br /&gt;
        @param msg (str) = display message&lt;br /&gt;
        @param percent (int) = progress&lt;br /&gt;
        @return: rc (int) always zero&lt;br /&gt;
&lt;br /&gt;
        Example:&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt; for i in range(0, 100+1, 2):&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt;   dialog.gauge(&#039;Progress:&#039;, i)&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt;   time.sleep(.1)&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        rc, output = self._exe(&#039;echo {percent} | dialog --gauge &amp;quot;{msg}&amp;quot; 0 0&#039;.format(percent=percent, msg=msg))&lt;br /&gt;
        assert rc in (self.YES,), &amp;quot;guage rc&amp;quot;&lt;br /&gt;
        return rc&lt;br /&gt;
&lt;br /&gt;
    def progress(self, msg, percent):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Alias for self.guage()&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        return self.gauge(msg=msg, percent=percent)&lt;br /&gt;
&lt;br /&gt;
    def form(self, msg, item_list):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Multiple item entry form&lt;br /&gt;
&lt;br /&gt;
        @param msg (str) = display message&lt;br /&gt;
        @param item_list (str list) = list of items&lt;br /&gt;
        @return: rc (int), answers (str list)&lt;br /&gt;
&lt;br /&gt;
        Example:&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt; rc, answers = dialog.form(&#039;Enter details&#039;,&lt;br /&gt;
        ...     (&#039;first name&#039;, &#039;last name&#039;))&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        item_str = &amp;quot;&amp;quot;&lt;br /&gt;
        name_len = 1&lt;br /&gt;
        for i in range(len(item_list)):&lt;br /&gt;
            if len(item_list[i])+3 &amp;gt; name_len:&lt;br /&gt;
                name_len = len(item_list[i])+3&lt;br /&gt;
        for i in range(len(item_list)):&lt;br /&gt;
            item_str += &amp;quot; \&amp;quot;&amp;quot; + item_list[i] + &amp;quot;:\&amp;quot; &amp;quot; + str(i+1) + &amp;quot; 1 \&amp;quot;\&amp;quot; &amp;quot; + str(i+1) +\&lt;br /&gt;
                &amp;quot; &amp;quot; + str(name_len) + &amp;quot; 40 0&amp;quot;&lt;br /&gt;
        rc, answers = self._exe(&#039;dialog --form &amp;quot;{msg}&amp;quot; 0 0 0 {item_str}&#039;.format(msg=msg, item_str=item_str),&lt;br /&gt;
                                strip=False)&lt;br /&gt;
        answers = answers.split(&#039;\n\n&#039;)&lt;br /&gt;
        if not answers:&lt;br /&gt;
            answers = None&lt;br /&gt;
        assert rc in (self.YES, self.NO, self.ESC), &amp;quot;form rc&amp;quot;&lt;br /&gt;
        return rc, answers&lt;br /&gt;
&lt;br /&gt;
    def test(self):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Test features&lt;br /&gt;
&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt; import dialog&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt; dlg = dialog.Dialog()&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt; dlg.test()&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
        def wait_user(msg):&lt;br /&gt;
            self.msgbox(&amp;quot;%s&amp;quot; % msg)&lt;br /&gt;
&lt;br /&gt;
        # rc_to_str&lt;br /&gt;
        wait_user(&amp;quot;Testing return code...&amp;quot;)&lt;br /&gt;
        print self.rc_to_str(self.YES)  # YES&lt;br /&gt;
        print self.rc_to_str(self.NO)  # NO&lt;br /&gt;
        print self.rc_to_str(self.ESC)  # ESX&lt;br /&gt;
        try:&lt;br /&gt;
            print self.rc_to_str(111)  # exception&lt;br /&gt;
            raise Exception(&amp;quot;Did not throw exception&amp;quot;)&lt;br /&gt;
        except Exception as rc:&lt;br /&gt;
            pass&lt;br /&gt;
&lt;br /&gt;
        # msgbox&lt;br /&gt;
        wait_user(&amp;quot;Testing msgbox...&amp;quot;)&lt;br /&gt;
        rc = self.msgbox(&amp;quot;msgbox&amp;quot;)&lt;br /&gt;
        if rc not in (self.YES, self.ESC):&lt;br /&gt;
            raise Exception(&amp;quot;Unknown return code for msgbox: %s&amp;quot; % rc)&lt;br /&gt;
&lt;br /&gt;
        # yesno&lt;br /&gt;
        wait_user(&amp;quot;Testing yesno...&amp;quot;)&lt;br /&gt;
        rc = self.yesno(&amp;quot;yesno&amp;quot;)&lt;br /&gt;
        if rc not in (self.YES, self.NO, self.ESC):&lt;br /&gt;
            raise Exception(&amp;quot;Unknown return code for yesno: %s&amp;quot; % rc)&lt;br /&gt;
&lt;br /&gt;
        # infobox&lt;br /&gt;
        wait_user(&amp;quot;Testing infobox...&amp;quot;)&lt;br /&gt;
        rc = self.infobox(&amp;quot;infobox sleep 1 sec&amp;quot;)&lt;br /&gt;
        if rc not in (self.YES,):&lt;br /&gt;
            raise Exception(&amp;quot;Unknown return code for infobox %s&amp;quot; % rc)&lt;br /&gt;
        time.sleep(1)&lt;br /&gt;
&lt;br /&gt;
        # inputbox&lt;br /&gt;
        wait_user(&amp;quot;Testing inputbox...&amp;quot;)&lt;br /&gt;
        rc, output = self.inputbox(&amp;quot;inputbox&amp;quot;)&lt;br /&gt;
        if rc not in (self.YES, self.NO, self.ESC):&lt;br /&gt;
            raise Exception(&amp;quot;Unknown return code for inputbox: %s&amp;quot; % rc)&lt;br /&gt;
        wait_user(&amp;quot;Result: %s&amp;quot; % output)&lt;br /&gt;
&lt;br /&gt;
        # textbox&lt;br /&gt;
        wait_user(&amp;quot;Testing textbox...&amp;quot;)&lt;br /&gt;
        rc = self.textbox(&amp;quot;/etc/passwd&amp;quot;)&lt;br /&gt;
        if rc not in (self.YES, self.ESC):&lt;br /&gt;
            raise Exception(&amp;quot;Unknown return code for textbox: %s&amp;quot; % rc)&lt;br /&gt;
&lt;br /&gt;
        # menu&lt;br /&gt;
        wait_user(&amp;quot;Testing menu...&amp;quot;)&lt;br /&gt;
        rc, selection = self.menu(&amp;quot;menu&amp;quot;, (&amp;quot;option 1&amp;quot;, &amp;quot;option 2&amp;quot;))&lt;br /&gt;
        if rc not in (self.YES, self.NO, self.ESC):&lt;br /&gt;
            raise Exception(&amp;quot;Unknown return code for menu: %s&amp;quot; % rc)&lt;br /&gt;
        wait_user(&amp;quot;Result: %s&amp;quot; % selection)&lt;br /&gt;
&lt;br /&gt;
        # checklist&lt;br /&gt;
        wait_user(&amp;quot;Testing checklist...&amp;quot;)&lt;br /&gt;
        rc, selection = self.checklist(&amp;quot;menu&amp;quot;, [&amp;quot;option 1&amp;quot;, &amp;quot;option 2&amp;quot;])&lt;br /&gt;
        if rc not in (self.YES, self.NO, self.ESC):&lt;br /&gt;
            raise Exception(&amp;quot;Unknown return code for checklist: %s&amp;quot; % rc)&lt;br /&gt;
        wait_user(&amp;quot;Result: %s&amp;quot; % str(selection))&lt;br /&gt;
        wait_user(&amp;quot;Testing checklist with default selection...&amp;quot;)&lt;br /&gt;
        rc, selection = self.checklist(&amp;quot;menu&amp;quot;, [&amp;quot;option 1&amp;quot;, &amp;quot;option 2&amp;quot;], [1, 2])&lt;br /&gt;
        if rc not in (self.YES, self.NO, self.ESC):&lt;br /&gt;
            raise Exception(&amp;quot;Unknown return code for checklist: %s&amp;quot; % rc)&lt;br /&gt;
        wait_user(&amp;quot;Result: %s&amp;quot; % str(selection))&lt;br /&gt;
&lt;br /&gt;
        # radiolist&lt;br /&gt;
        wait_user(&amp;quot;Testing radiolist...&amp;quot;)&lt;br /&gt;
        rc, selection = self.radiolist(&amp;quot;menu&amp;quot;, [&amp;quot;option 1&amp;quot;, &amp;quot;option 2&amp;quot;])&lt;br /&gt;
        if rc not in (self.YES, self.NO, self.ESC):&lt;br /&gt;
            raise Exception(&amp;quot;Unknown return code for radiolist: %s&amp;quot; % rc)&lt;br /&gt;
        wait_user(&amp;quot;Result: %s&amp;quot; % str(selection))&lt;br /&gt;
        wait_user(&amp;quot;Testing radiolist with default selection...&amp;quot;)&lt;br /&gt;
        rc, selection = self.radiolist(&amp;quot;menu&amp;quot;, [&amp;quot;option 1&amp;quot;, &amp;quot;option 2&amp;quot;], 2)&lt;br /&gt;
        if rc not in (self.YES, self.NO, self.ESC):&lt;br /&gt;
            raise Exception(&amp;quot;Unknown return code for radiolist: %s&amp;quot; % rc)&lt;br /&gt;
        wait_user(&amp;quot;Result: %s&amp;quot; % str(selection))&lt;br /&gt;
&lt;br /&gt;
        # guage&lt;br /&gt;
        wait_user(&amp;quot;Testing guage...&amp;quot;)&lt;br /&gt;
        for i in range(4+1):&lt;br /&gt;
            rc = self.gauge(&amp;quot;test guage&amp;quot;, i*25)&lt;br /&gt;
            # rc = self.progress(&amp;quot;test progress&amp;quot;, i*25)&lt;br /&gt;
            if rc not in (self.YES,):&lt;br /&gt;
                raise Exception(&amp;quot;Unknown return code for guage: %s&amp;quot; % rc)&lt;br /&gt;
            time.sleep(1)&lt;br /&gt;
&lt;br /&gt;
        # form&lt;br /&gt;
        wait_user(&amp;quot;Testing form...&amp;quot;)&lt;br /&gt;
        rc, answers = self.form(&amp;quot;form&amp;quot;, [&amp;quot;option 1&amp;quot;, &amp;quot;option 2&amp;quot;])&lt;br /&gt;
        if rc not in (self.YES, self.NO, self.ESC):&lt;br /&gt;
            raise Exception(&amp;quot;Unknown return code for form: %s&amp;quot; % rc)&lt;br /&gt;
        wait_user(&amp;quot;Result: %s&amp;quot; % str(answers))&lt;br /&gt;
&lt;br /&gt;
        # done with test, cleanup&lt;br /&gt;
        wait_user(&amp;quot;Done with tests...&amp;quot;)&lt;br /&gt;
        self.clear()&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
    # dialog = Dialog()&lt;br /&gt;
    # dialog.test()&lt;br /&gt;
    pass&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Busy Loop and Thread.yield() ===&lt;br /&gt;
&lt;br /&gt;
&amp;quot;I want to tell my Python threads to yield, and so avoid hogging the CPU unnecessarily. In Java, you could do that using the Thread.yield() function&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Solution:&lt;br /&gt;
 time.sleep(0)&lt;br /&gt;
 time.sleep(0.00001)&lt;br /&gt;
 time.sleep(epsilon)&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* multithreading - In there something similar to Java&#039;s Thread.yield() in Python? Does that even make sense? - Stack Overflow - http://stackoverflow.com/questions/1908206/in-there-something-similar-to-javas-thread-yield-in-python-does-that-even-ma&lt;br /&gt;
* multithreading - How does a threading.Thread yield the rest of its quantum in Python? - Stack Overflow - http://stackoverflow.com/questions/787803/how-does-a-threading-thread-yield-the-rest-of-its-quantum-in-python&lt;br /&gt;
&lt;br /&gt;
=== USB ===&lt;br /&gt;
&lt;br /&gt;
Programming with PyUSB 1.0 - http://pyusb.sourceforge.net/docs/1.0/tutorial.html&lt;br /&gt;
&lt;br /&gt;
PyUSB - http://pyusb.sourceforge.net/&lt;br /&gt;
&lt;br /&gt;
 git clone https://github.com/walac/pyusb&lt;br /&gt;
&lt;br /&gt;
 import usb.core&lt;br /&gt;
 dev = usb.core.find()&lt;br /&gt;
&lt;br /&gt;
 # find our device&lt;br /&gt;
 dev = usb.core.find(idVendor=0xfffe, idProduct=0x0001)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&#039;&#039;&#039;Dealing with multiple identical devices&#039;&#039;&#039; - Sometimes you may have two identical devices connected to the computer. How can you differentiate them? Device objects come with two additional attributes which are not part of the USB Spec, but are very useful: bus and address attributes. First of all, it is worth to say that these attributes come from the backend and a backend is free to not support them, in which case they are set to None. That said, these attributes represent the bus number and bus address of the device and, as you might already have imagined, can be used to differentiate two devices with the same idVendor and idProduct attributes.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Tkinter ===&lt;br /&gt;
&lt;br /&gt;
Python GUI Bitcoin: [http://bitcoin.stackexchange.com/questions/10594/simplest-way-of-obtaining-mtgox-exchange-rate-via-an-api]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import json&lt;br /&gt;
import urllib2&lt;br /&gt;
from Tkinter import *&lt;br /&gt;
&lt;br /&gt;
url=&#039;http://api.bitcoincharts.com/v1/markets.json&#039;&lt;br /&gt;
req=urllib2.Request(url)&lt;br /&gt;
response=urllib2.urlopen(req).read()&lt;br /&gt;
output=json.loads(response)&lt;br /&gt;
&lt;br /&gt;
mtusd_price = output[-10][&#039;avg&#039;]&lt;br /&gt;
mteur_price = output[31][&#039;avg&#039;]&lt;br /&gt;
mtgbp_price = output[44][&#039;avg&#039;]&lt;br /&gt;
&lt;br /&gt;
MTUSD= &#039;USD&#039; + &#039; &#039; + str(mtusd_price)&lt;br /&gt;
MTEUR= &#039;EUR&#039; + &#039; &#039; + str(mteur_price)&lt;br /&gt;
MTGBP = &#039;GBP&#039; + &#039; &#039; + str(mtgbp_price)&lt;br /&gt;
&lt;br /&gt;
root= Tk()&lt;br /&gt;
root.title(&amp;quot;Bitcoin Price&amp;quot;)&lt;br /&gt;
root.geometry(&amp;quot;250x100&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
USD = Label(root, text=MTUSD)&lt;br /&gt;
EUR = Label(root, text=MTEUR)&lt;br /&gt;
GBP = Label(root, text=MTGBP)&lt;br /&gt;
USD.pack()&lt;br /&gt;
EUR.pack()&lt;br /&gt;
GBP.pack()&lt;br /&gt;
mainloop()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== ctypes ===&lt;br /&gt;
&lt;br /&gt;
&amp;quot;ctypes is a foreign function library for Python. It provides C compatible data types, and allows calling functions in DLLs or shared libraries. It can be used to wrap these libraries in pure Python.&amp;quot;&lt;br /&gt;
:-- 15.17. ctypes — A foreign function library for Python — Python v2.7.7 documentation - https://docs.python.org/2/library/ctypes.html&lt;br /&gt;
&lt;br /&gt;
Use &amp;quot;c scope&amp;quot; to build a database of symbols to see what options are available.&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
testlib.c&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void myprint(void);&lt;br /&gt;
&lt;br /&gt;
void myprint()&lt;br /&gt;
{&lt;br /&gt;
    printf(&amp;quot;hello world\n&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Compile:&lt;br /&gt;
 gcc -shared -Wl,-soname,testlib -o testlib.so -fPIC testlib.c&lt;br /&gt;
&lt;br /&gt;
testlibwrapper.py&lt;br /&gt;
&lt;br /&gt;
Python:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import ctypes&lt;br /&gt;
&lt;br /&gt;
testlib = ctypes.CDLL(&#039;/full/path/to/testlib.so&#039;)&lt;br /&gt;
testlib.myprint()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Source: python - ctypes - Beginner - Stack Overflow - http://stackoverflow.com/questions/5081875/ctypes-beginner&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
nzjrs&#039;s Gists - https://gist.github.com/nzjrs&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int sum(double *x,int n)&lt;br /&gt;
{&lt;br /&gt;
  int i;&lt;br /&gt;
  double counter;&lt;br /&gt;
  counter = 0;&lt;br /&gt;
  for(i=0;i&amp;lt;n;i++)&lt;br /&gt;
    {&lt;br /&gt;
      counter=counter+x[i];&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
  return counter;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -c sum.c&lt;br /&gt;
gcc -shared -o sum.so sum.o&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from ctypes import *&lt;br /&gt;
my_sum=CDLL(&#039;sum.so&#039;)&lt;br /&gt;
a=numpy.array(range(10),dtype=float)&lt;br /&gt;
my_sum.sum(a.ctypes.data_as(c_void_p),int(10))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
a=(c_double*10)()&lt;br /&gt;
for i in range(10):&lt;br /&gt;
   a[i]=i&lt;br /&gt;
my_sum.sum(a,int(10))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Source: Ctypes — Numerical Computing with Sage v6.2 - http://www.sagemath.org/doc/numerical_sage/ctypes.html&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
=== Warnings ===&lt;br /&gt;
&lt;br /&gt;
 if sys.version_info &amp;gt;= (1, 0, 0):&lt;br /&gt;
   warnings.warn(&amp;quot;Danger Will Robinson: trying Phi on untested Python 3.0!&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
=== enum ===&lt;br /&gt;
&lt;br /&gt;
Python 3: https://docs.python.org/3/library/enum.html&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from enum import Enum&lt;br /&gt;
&lt;br /&gt;
# class syntax&lt;br /&gt;
class Color(Enum):&lt;br /&gt;
    RED = 1&lt;br /&gt;
    GREEN = 2&lt;br /&gt;
    BLUE = 3&lt;br /&gt;
&lt;br /&gt;
# functional syntax&lt;br /&gt;
Color = Enum(&#039;Color&#039;, [&#039;RED&#039;, &#039;GREEN&#039;, &#039;BLUE&#039;])&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
Python 2: [http://stackoverflow.com/questions/36932/how-can-i-represent-an-enum-in-python]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Enum(set):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot; Basic enumerated type&lt;br /&gt;
    &lt;br /&gt;
    Example&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt; Animals = phi.Enum([&amp;quot;DOG&amp;quot;, &amp;quot;CAT&amp;quot;, &amp;quot;HORSE&amp;quot;])&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt; Animals.DOG&lt;br /&gt;
        &#039;DOG&#039;&lt;br /&gt;
        &amp;gt;&amp;gt;&amp;gt; &#039;HORSE&#039; in Animals&lt;br /&gt;
        True&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    def __getattr__(self, name):&lt;br /&gt;
        if name in self:&lt;br /&gt;
            return name&lt;br /&gt;
        raise AttributeError(&amp;quot;Missing Enum property: %s&amp;quot; % name)&lt;br /&gt;
    def __setattr__(self, name, value):  # this makes it read-only&lt;br /&gt;
        raise AttributeError(&amp;quot;Unable to modify Enum property: %s (%s)&amp;quot; % (name, value))&lt;br /&gt;
&lt;br /&gt;
Animals = Enum([&amp;quot;DOG&amp;quot;, &amp;quot;CAT&amp;quot;, &amp;quot;HORSE&amp;quot;])&lt;br /&gt;
&lt;br /&gt;
print(Animals.DOG)  # &#039;DOG&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----------&lt;br /&gt;
&lt;br /&gt;
Alternative:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Stationery:&lt;br /&gt;
    Pen, Pencil, Eraser = range(0, 3)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
One liner:&lt;br /&gt;
 class Enum(tuple): __getattr__ = tuple.index&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; State = Enum([&#039;Unclaimed&#039;, &#039;Claimed&#039;])&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; State.Claimed&lt;br /&gt;
1&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; State[1]&lt;br /&gt;
&#039;Claimed&#039;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; State&lt;br /&gt;
(&#039;Unclaimed&#039;, &#039;Claimed&#039;)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; range(len(State))&lt;br /&gt;
[0, 1]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; [(k, State[k]) for k in range(len(State))]&lt;br /&gt;
[(0, &#039;Unclaimed&#039;), (1, &#039;Claimed&#039;)]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; [(k, getattr(State, k)) for k in State]&lt;br /&gt;
[(&#039;Unclaimed&#039;, 0), (&#039;Claimed&#039;, 1)]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Python 3 supports enum natively with the enum.Enum library:&lt;br /&gt;
&lt;br /&gt;
=== pySerial ===&lt;br /&gt;
&lt;br /&gt;
https://pythonhosted.org/pyserial/&lt;br /&gt;
&lt;br /&gt;
&amp;quot;This module encapsulates the access for the serial port. It provides backends for Python running on Windows, OSX, Linux, BSD (possibly any POSIX compliant system) and IronPython. The module named “serial” automatically selects the appropriate backend.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
https://github.com/pyserial/&lt;br /&gt;
&lt;br /&gt;
Intro - https://pythonhosted.org/pyserial/shortintro.html&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import serial&lt;br /&gt;
import time&lt;br /&gt;
&lt;br /&gt;
ser = serial.Serial(&lt;br /&gt;
    port=&#039;COM4&#039;,\&lt;br /&gt;
    baudrate=9600,\&lt;br /&gt;
    parity=serial.PARITY_NONE,\&lt;br /&gt;
    stopbits=serial.STOPBITS_ONE,\&lt;br /&gt;
    bytesize=serial.EIGHTBITS,\&lt;br /&gt;
        timeout=0)&lt;br /&gt;
&lt;br /&gt;
print(&amp;quot;connected to: &amp;quot; + ser.portstr)&lt;br /&gt;
&lt;br /&gt;
#this will store the line&lt;br /&gt;
seq = []&lt;br /&gt;
count = 1&lt;br /&gt;
&lt;br /&gt;
while True:&lt;br /&gt;
    for c in ser.read():&lt;br /&gt;
        seq.append(chr(c)) #convert from ANSII&lt;br /&gt;
        joined_seq = &#039;&#039;.join(str(v) for v in seq) #Make a string from array&lt;br /&gt;
&lt;br /&gt;
        if chr(c) == &#039;\n&#039;:&lt;br /&gt;
            print(&amp;quot;Line &amp;quot; + str(count) + &#039;: &#039; + joined_seq)&lt;br /&gt;
            seq = []&lt;br /&gt;
            count += 1&lt;br /&gt;
            break&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ser.close()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ref: http://stackoverflow.com/questions/16077912/python-serial-how-to-use-the-read-or-readline-function-to-read-more-than-1-char&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
I modified the code to monitor a COM port: (Windows)&lt;br /&gt;
&lt;br /&gt;
Monitor Serial:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import serial, time, sys&lt;br /&gt;
&lt;br /&gt;
logger = open(&amp;quot;serial.txt&amp;quot;, &amp;quot;w&amp;quot;)&lt;br /&gt;
timer = time.time()&lt;br /&gt;
&lt;br /&gt;
def log(msg, head=False):&lt;br /&gt;
    msg = msg.strip()&lt;br /&gt;
    if head:&lt;br /&gt;
      msg = &amp;quot;&amp;gt;&amp;gt;&amp;gt; &amp;quot; + msg&lt;br /&gt;
    logger.write(msg + &amp;quot;\n&amp;quot;)&lt;br /&gt;
    sys.stdout.write(msg + &amp;quot;\n&amp;quot;)&lt;br /&gt;
    newtime = time.time()&lt;br /&gt;
    if newtime &amp;gt; timer + 1:&lt;br /&gt;
        logger.flush()&lt;br /&gt;
        sys.stdout.flush()&lt;br /&gt;
&lt;br /&gt;
while True:&lt;br /&gt;
&lt;br /&gt;
    ser = None&lt;br /&gt;
    try:&lt;br /&gt;
        ser = serial.Serial(&lt;br /&gt;
            port=&#039;COM1&#039;,\&lt;br /&gt;
            baudrate=115200,\&lt;br /&gt;
            parity=serial.PARITY_NONE,\&lt;br /&gt;
            stopbits=serial.STOPBITS_ONE,\&lt;br /&gt;
            bytesize=serial.EIGHTBITS,\&lt;br /&gt;
                timeout=0)&lt;br /&gt;
    except serial.serialutil.SerialException as e:&lt;br /&gt;
        log(str(e), True)&lt;br /&gt;
        time.sleep(1)&lt;br /&gt;
        continue&lt;br /&gt;
&lt;br /&gt;
    log(&amp;quot;Connected to: &amp;quot; + ser.portstr, True)&lt;br /&gt;
    count=1&lt;br /&gt;
&lt;br /&gt;
    try:&lt;br /&gt;
        line = []&lt;br /&gt;
        while True:&lt;br /&gt;
            for c in ser.readline():&lt;br /&gt;
                line.append(c)&lt;br /&gt;
                if c == &amp;quot;\n&amp;quot;:&lt;br /&gt;
                    log(&amp;quot;&amp;quot;.join(line))&lt;br /&gt;
                    line = []&lt;br /&gt;
    except serial.serialutil.SerialException as e:&lt;br /&gt;
        log(str(e), True)&lt;br /&gt;
        time.sleep(1)&lt;br /&gt;
    ser.close()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== MyBool ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; class NewBool(int):&lt;br /&gt;
...    def __new__(cls, value):&lt;br /&gt;
...        return int.__new__(cls, bool(value))&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; y = NewBool(2)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; y == 1&lt;br /&gt;
True&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
https://jfine-python-classes.readthedocs.io/en/latest/subclass-int.html&lt;br /&gt;
&lt;br /&gt;
Also check out the __cmp__&lt;br /&gt;
&lt;br /&gt;
== md5 ==&lt;br /&gt;
&lt;br /&gt;
 import md5&lt;br /&gt;
 md5.new(&amp;quot;Nobody inspects the spammish repetition&amp;quot;).hexdigest()&lt;br /&gt;
 # &#039;bb649c83dd1ea5c9d9dec9a18df0ffe9&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ echo -n &amp;quot;Nobody inspects the spammish repetition&amp;quot; | md5sum&lt;br /&gt;
bb649c83dd1ea5c9d9dec9a18df0ffe9  -&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== External Libraries ==&lt;br /&gt;
&lt;br /&gt;
=== execnet ===&lt;br /&gt;
&lt;br /&gt;
Python Package Index - execnet - https://pypi.python.org/pypi/execnet&lt;br /&gt;
&lt;br /&gt;
Examples - http://codespeak.net/execnet/examples.html&lt;br /&gt;
* basic local and remote communication - http://codespeak.net/execnet/example/test_info.html&lt;br /&gt;
&lt;br /&gt;
Execute source code in subprocess, communicate through a channel:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import execnet&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; gw = execnet.makegateway()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; channel = gw.remote_exec(&amp;quot;channel.send(channel.receive()+1)&amp;quot;)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; channel.send(1)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; channel.receive()&lt;br /&gt;
2&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Compare current working directories&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import execnet, os&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; gw = execnet.makegateway()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; ch = gw.remote_exec(&amp;quot;import os; channel.send(os.getcwd())&amp;quot;)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; res = ch.receive()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; assert res == os.getcwd()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Get information from remote ssh account&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import execnet, os&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; gw = execnet.makegateway(&amp;quot;ssh=codespeak.net&amp;quot;)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; channel = gw.remote_exec(&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
...     import sys, os&lt;br /&gt;
...     channel.send((sys.platform, sys.version_info, os.getpid()))&lt;br /&gt;
... &amp;quot;&amp;quot;&amp;quot;)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; platform, version_info, remote_pid = channel.receive()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; platform&lt;br /&gt;
&#039;linux2&#039;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; version_info&lt;br /&gt;
(2, 4, 2, &#039;final&#039;, 0)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
remote-exec a function (avoiding inlined source part I)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import execnet&lt;br /&gt;
&lt;br /&gt;
def multiplier(channel, factor):&lt;br /&gt;
    while not channel.isclosed():&lt;br /&gt;
        param = channel.receive()&lt;br /&gt;
        channel.send(param * factor)&lt;br /&gt;
&lt;br /&gt;
gw = execnet.makegateway()&lt;br /&gt;
channel = gw.remote_exec(multiplier, factor=10)&lt;br /&gt;
&lt;br /&gt;
for i in range(5):&lt;br /&gt;
    channel.send(i)&lt;br /&gt;
    result = channel.receive()&lt;br /&gt;
    assert result == i * 10&lt;br /&gt;
&lt;br /&gt;
gw.exit()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
remote-exec a module (avoiding inlined source part II)&lt;br /&gt;
:&amp;quot;You can pass a module object to remote_exec in which case its source code will be sent. No dependencies will be transferred so the module must be self-contained or only use modules that are installed on the “other” side. Module code can detect if it is running in a remote_exec situation by checking for the special __name__ attribute.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# content of a module remote1.py&lt;br /&gt;
&lt;br /&gt;
if __name__ == &#039;__channelexec__&#039;:&lt;br /&gt;
    channel.send(&#039;initialization complete&#039;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import execnet, remote1&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; gw = execnet.makegateway()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; ch = gw.remote_exec(remote1)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; print (ch.receive())&lt;br /&gt;
initialization complete&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use a callback instead of receive() and wait for completion&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import execnet&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; gw = execnet.makegateway()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; channel = gw.remote_exec(&amp;quot;for i in range(10): channel.send(i)&amp;quot;)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; l = []&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; channel.setcallback(l.append, endmarker=None)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; channel.waitclose() # waits for closing, i.e. remote exec finish&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; l&lt;br /&gt;
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, None]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
a simple command loop pattern&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# contents of: remotecmd.py&lt;br /&gt;
import os&lt;br /&gt;
&lt;br /&gt;
def simple(arg):&lt;br /&gt;
    return arg + 1&lt;br /&gt;
&lt;br /&gt;
def listdir(path):&lt;br /&gt;
    return os.listdir(path)&lt;br /&gt;
    &lt;br /&gt;
if __name__ == &#039;__channelexec__&#039;:&lt;br /&gt;
    for item in channel:&lt;br /&gt;
        channel.send(eval(item))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import execnet, remotecmd&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; gw = execnet.makegateway()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; ch = gw.remote_exec(remotecmd)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; ch.send(&#039;simple(10)&#039;) # execute func-call remotely&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; ch.receive()&lt;br /&gt;
11&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== evdev ===&lt;br /&gt;
&lt;br /&gt;
Install:&lt;br /&gt;
 apt-get install python-setuptools python-dev&lt;br /&gt;
 easy_install pip&lt;br /&gt;
 pip install evdev&lt;br /&gt;
&lt;br /&gt;
Simple read usage:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from evdev import InputDevice&lt;br /&gt;
from evdev import ecodes&lt;br /&gt;
&lt;br /&gt;
# look for a /dev/input/by-id/usb...kbd or similar&lt;br /&gt;
DEVICE = &amp;quot;/dev/input/by-id/usb-ORTEK_USB_Keyboard_Hub-event-kbd&amp;quot;&lt;br /&gt;
&lt;br /&gt;
dev = InputDevice(DEVICE)&lt;br /&gt;
&lt;br /&gt;
while True:&lt;br /&gt;
    r, w, x = select([dev], [], [], 5)&lt;br /&gt;
    for event in dev.read():&lt;br /&gt;
        if event.type == 1 and event.value == 1:&lt;br /&gt;
            print event.code&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
List LED states:&lt;br /&gt;
 dev.leds()&lt;br /&gt;
 dev.leds(verbose=True)&lt;br /&gt;
&lt;br /&gt;
Inject usage: (does not appear to really work)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from evdev import InputDevice&lt;br /&gt;
from evdev import ecodes&lt;br /&gt;
from evdev import UInput&lt;br /&gt;
&lt;br /&gt;
DEVICE = &amp;quot;/dev/input/by-id/usb-ORTEK_USB_Keyboard_Hub-event-kbd&amp;quot;&lt;br /&gt;
dev = InputDevice(DEVICE)&lt;br /&gt;
&lt;br /&gt;
ui = UInput()&lt;br /&gt;
&lt;br /&gt;
ui.write(ecodes.EV_KEY, ecodes.KEY_4, 1)&lt;br /&gt;
ui.write(ecodes.EV_KEY, ecodes.KEY_4, 0)&lt;br /&gt;
ui.syn()&lt;br /&gt;
&lt;br /&gt;
ui.write(ecodes.EV_KEY, ecodes.KEY_NUMLOCK, 1)&lt;br /&gt;
ui.write(ecodes.EV_KEY, ecodes.KEY_NUMLOCK, 0)&lt;br /&gt;
ui.syn()&lt;br /&gt;
&lt;br /&gt;
ui.close()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Tutorial:&lt;br /&gt;
* evdev documentation — python-evdev 0.4.3 documentation - http://pythonhosted.org/evdev/index.html&lt;br /&gt;
References:&lt;br /&gt;
* python-evdev/doc/tutorial.rst at master · gvalkov/python-evdev · GitHub - https://github.com/gvalkov/python-evdev/blob/master/doc/tutorial.rst&lt;br /&gt;
&lt;br /&gt;
=== ldap-python ===&lt;br /&gt;
&lt;br /&gt;
python-ldap: LDAP client API for Python - http://www.python-ldap.org/&lt;br /&gt;
&lt;br /&gt;
Index of Packages : Python Package Index - https://pypi.python.org/pypi/python-ldap/&lt;br /&gt;
&lt;br /&gt;
 yum install python-devel openldap-devel&lt;br /&gt;
 pip install python-ldap&lt;br /&gt;
&lt;br /&gt;
Articles:&lt;br /&gt;
* Python LDAP Applications: Part 1 - Installing and Configuring the Python-LDAP Library and Binding to an LDAP Directory | Packt Publishing - http://www.packtpub.com/article/installing-and-configuring-the-python-ldap-library-and-binding-to-an-ldap-directory&lt;br /&gt;
&lt;br /&gt;
=== xmmp ===&lt;br /&gt;
&lt;br /&gt;
PDF:&lt;br /&gt;
* XMPP: The Definitive Guide - Oreilly - http://oriolrius.cat/blog/wp-content/uploads/2009/10/Oreilly.XMPP.The.Definitive.Guide.May.2009.pdf&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
xmmp is the Jabber protocol&lt;br /&gt;
&lt;br /&gt;
Best options:&lt;br /&gt;
&lt;br /&gt;
MIT libraries.&lt;br /&gt;
* sleekxmpp (was: sleekxmpp) is pretty popular and is used for examples in Peter Saint-Andre&#039;s XMPP book from O&#039;Reilly. It reportedly works well, and finally got an email list in April 2010, and has a chat room at sleek@conference.jabber.org.&lt;br /&gt;
&lt;br /&gt;
GPL libraries.&lt;br /&gt;
* xmpppy is used by gajim.&lt;br /&gt;
&lt;br /&gt;
LPGL libraries.&lt;br /&gt;
* pyxmpp is pretty good and uses libxml2 internally for xml parsing.&lt;br /&gt;
* pyxmpp2 is the next version of pyxmpp, runs on python 2.7 and 3.2, and removes the libxml2 requirement. Like many, it requires dnspython.&lt;br /&gt;
* jabberpy is the original and still works for a lot of tasks, but is thoroughly unmaintained.&lt;br /&gt;
&lt;br /&gt;
Other libraries.&lt;br /&gt;
* Wokkel, mentioned in another post. That&#039;s a new one for me, based on twisted.&lt;br /&gt;
&lt;br /&gt;
chat - Best python XMPP / Jabber client library? - Stack Overflow - http://stackoverflow.com/questions/1901828/best-python-xmpp-jabber-client-library&lt;br /&gt;
&lt;br /&gt;
=== xmpppy ===&lt;br /&gt;
&lt;br /&gt;
xmpppy: the jabber python project - http://xmpppy.sourceforge.net/&lt;br /&gt;
&lt;br /&gt;
&amp;quot;xmpppy is a Python library that is targeted to provide easy scripting with Jabber. Similar projects are Twisted Words and jabber.py.&lt;br /&gt;
&lt;br /&gt;
This library was not designed from scratch. It inherits some code from jabberpy and have very similar API in many places. Though it is separate project since it have almost completely different architecture and primarily aims to work with jabberd2 - the new Open Source Jabber Server.&lt;br /&gt;
&lt;br /&gt;
xmpppy is distributed under the terms of GNU General Public License and can be freely redistributed without any charge.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 wget http://sourceforge.net/projects/xmpppy/files/xmpppy/0.4.1/xmpppy-0.4.1.tar.gz/download -O xmpppy-0.4.1.tar.gz&lt;br /&gt;
 tar -zvxf xmpppy-0.4.1.tar.gz&lt;br /&gt;
 pip install pydns&lt;br /&gt;
&lt;br /&gt;
--- basic connection ---&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
 &lt;br /&gt;
import xmpp&lt;br /&gt;
 &lt;br /&gt;
user=&amp;quot;username@gmail.com&amp;quot;&lt;br /&gt;
password=&amp;quot;password&amp;quot;&lt;br /&gt;
server=&amp;quot;gmail.com&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
jid = xmpp.JID(user)&lt;br /&gt;
connection = xmpp.Client(server,debug=[])&lt;br /&gt;
connection.connect()&lt;br /&gt;
result = connection.auth(jid.getNode(), password,&amp;quot;LFY-client&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
connection.sendInitPresence()&lt;br /&gt;
 &lt;br /&gt;
while connection.Process(1):&lt;br /&gt;
    pass&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* Use XMPP to Create Your Own Google Talk Client - LINUX For You - http://www.linuxforu.com/2012/06/use-xmpp-to-create-your-own-google-talk-client/&lt;br /&gt;
&lt;br /&gt;
--- basic receive ---&lt;br /&gt;
&lt;br /&gt;
Print messages when received:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
 &lt;br /&gt;
import xmpp&lt;br /&gt;
 &lt;br /&gt;
user=&amp;quot;username@gmail.com&amp;quot;&lt;br /&gt;
password=&amp;quot;password&amp;quot;&lt;br /&gt;
server=&amp;quot;gmail.com&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
def message_handler(connect_object, message_node):&lt;br /&gt;
        message = &amp;quot;Welcome to my first Gtalk Bot :)&amp;quot;&lt;br /&gt;
        connect_object.send( xmpp.Message( message_node.getFrom() ,message))&lt;br /&gt;
 &lt;br /&gt;
jid = xmpp.JID(user)&lt;br /&gt;
connection = xmpp.Client(server)&lt;br /&gt;
connection.connect()&lt;br /&gt;
result = connection.auth(jid.getNode(), password, &amp;quot;LFY-client&amp;quot;)&lt;br /&gt;
connection.RegisterHandler(&#039;message&#039;, message_handler)&lt;br /&gt;
 &lt;br /&gt;
connection.sendInitPresence()&lt;br /&gt;
 &lt;br /&gt;
while connection.Process(1):&lt;br /&gt;
    pass&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* Use XMPP to Create Your Own Google Talk Client - LINUX For You - http://www.linuxforu.com/2012/06/use-xmpp-to-create-your-own-google-talk-client/&lt;br /&gt;
&lt;br /&gt;
--- remote-control shell bot ---&lt;br /&gt;
&lt;br /&gt;
Replace the simple bot’s message_handler() function with this new one:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def message_handler(connect_object,message_node):&lt;br /&gt;
        command = str(message_node.getBody())&lt;br /&gt;
 &lt;br /&gt;
        process = subprocess.Popen(command,shell=True,stdout=subprocess.PIPE, stderr=subprocess.PIPE)&lt;br /&gt;
        message = process.stdout.read()&lt;br /&gt;
        if message==&amp;quot;&amp;quot;:&lt;br /&gt;
            message=process.stderr.read()&lt;br /&gt;
 &lt;br /&gt;
        connect_object.send( xmpp.Message( message_node.getFrom() ,message))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* Use XMPP to Create Your Own Google Talk Client - LINUX For You - http://www.linuxforu.com/2012/06/use-xmpp-to-create-your-own-google-talk-client/&lt;br /&gt;
&lt;br /&gt;
--- roster ---&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import xmpp&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
userID   = &#039;myname@gmail.com&#039; &lt;br /&gt;
password = &#039;mypassword&#039;&lt;br /&gt;
ressource = &#039;Script&#039;&lt;br /&gt;
&lt;br /&gt;
jid  = xmpp.protocol.JID(userID)&lt;br /&gt;
jabber  = xmpp.Client(jid.getDomain(), debug=[])&lt;br /&gt;
&lt;br /&gt;
connection = jabber.connect((&#039;talk.google.com&#039;,5222))&lt;br /&gt;
auth = jabber.auth(jid.getNode(), password, ressource)&lt;br /&gt;
&lt;br /&gt;
jabber.sendInitPresence(requestRoster=1)&lt;br /&gt;
myroster = jabber.getRoster()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To get status, you have to wait for the other clients to send you their status:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
jabber.RegisterHandler(&#039;presence&#039;, myPresenceHandler)&lt;br /&gt;
&lt;br /&gt;
def myPresenceHandler(con, event):&lt;br /&gt;
  fromjid = event.getFrom().getStripped()&lt;br /&gt;
  status = myroster.getStatus(fromjid)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
python - XMPP chat: accessing contacts&#039; status messages with xmppPy&#039;s Roster - Stack Overflow - http://stackoverflow.com/questions/2381597/xmpp-chat-accessing-contacts-status-messages-with-xmpppys-roster&lt;br /&gt;
&lt;br /&gt;
--- full roster script ---&lt;br /&gt;
&lt;br /&gt;
kparal/jabber-roster · GitHub - https://github.com/kparal/jabber-roster&lt;br /&gt;
&lt;br /&gt;
A simple Python tool for listing your Jabber roster contacts. You can use it to easily backup list of your buddies.&lt;br /&gt;
&lt;br /&gt;
This program is maintained, but not further developed. Bugs will be fixed, but no new features will be added. If you want to work on this program, don&#039;t hesitate to contact me, I will gladly assign you to the development team.&lt;br /&gt;
&lt;br /&gt;
 git clone https://github.com/kparal/jabber-roster&lt;br /&gt;
 python jabber_roster.py&lt;br /&gt;
&lt;br /&gt;
https://pypi.python.org/pypi/jabber-roster&lt;br /&gt;
&lt;br /&gt;
--- vcard ---&lt;br /&gt;
&lt;br /&gt;
This information is not in the roster. You will need to query the clients individually and get their vCard by sending this IQ :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;iq from=&#039;stpeter@jabber.org/roundabout&#039;&lt;br /&gt;
    id=&#039;v1&#039;&lt;br /&gt;
    type=&#039;get&#039;&amp;gt;&lt;br /&gt;
  &amp;lt;vCard xmlns=&#039;vcard-temp&#039;/&amp;gt;&lt;br /&gt;
&amp;lt;/iq&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
My solution:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def vcard(disp, jid):&lt;br /&gt;
    msg = xmpp.protocol.Iq()&lt;br /&gt;
    msg.setType(&#039;get&#039;)&lt;br /&gt;
    msg.setTo(jid)&lt;br /&gt;
    qc = msg.addChild(&#039;vCard&#039;)&lt;br /&gt;
    qc.setAttr(&#039;xmlns&#039;, &#039;vcard-temp&#039;)&lt;br /&gt;
    rep = disp.SendAndWaitForResponse(msg)&lt;br /&gt;
    # to see what other fields are available in the XML output:&lt;br /&gt;
    # print rep&lt;br /&gt;
    userid=fname=lname=title=department=region=None&lt;br /&gt;
    for i in rep.getChildren():&lt;br /&gt;
        for j in i.getChildren():&lt;br /&gt;
            if j.getName() == &amp;quot;TITLE&amp;quot;:&lt;br /&gt;
                title = j.getData().encode(&#039;utf-8&#039;)&lt;br /&gt;
            for k in j.getChildren():&lt;br /&gt;
                if k.getName() == &amp;quot;GIVEN&amp;quot;:&lt;br /&gt;
                    fname = k.getData().encode(&#039;utf-8&#039;)&lt;br /&gt;
                if k.getName() == &amp;quot;FAMILY&amp;quot;:&lt;br /&gt;
                    lname = k.getData().encode(&#039;utf-8&#039;)&lt;br /&gt;
                if k.getName() == &amp;quot;ORGUNIT&amp;quot;:&lt;br /&gt;
                    department = k.getData().encode(&#039;utf-8&#039;)&lt;br /&gt;
                if k.getName() == &amp;quot;REGION&amp;quot;:&lt;br /&gt;
                    region = k.getData().encode(&#039;utf-8&#039;)&lt;br /&gt;
    return fname, lname, title, department, region&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* xmpppy - Retrieve gtalk nickname in python xmpp - Stack Overflow - http://stackoverflow.com/questions/4539477/retrieve-gtalk-nickname-in-python-xmpp&lt;br /&gt;
* XEP-0054: vcard-temp - http://xmpp.org/extensions/xep-0054.html&lt;br /&gt;
&lt;br /&gt;
=== google-api-python-client ===&lt;br /&gt;
&lt;br /&gt;
Google APIs Client Library for Python, which includes:&lt;br /&gt;
* google-api-python-client: The core Python library for accessing Google APIs.&lt;br /&gt;
* oauth2client: A Python client library for OAuth 2.0.&lt;br /&gt;
* Sample applications using google-api-python-client and oauth2client &lt;br /&gt;
&lt;br /&gt;
-&lt;br /&gt;
&lt;br /&gt;
https://developers.google.com/api-client-library/python/start/installation&lt;br /&gt;
* Calendar API - Python/Command Line&lt;br /&gt;
&lt;br /&gt;
-&lt;br /&gt;
Download:&lt;br /&gt;
 wget https://code.google.com/p/google-api-python-client/downloads/detail?name=google-api-python-client-1.2.zip&lt;br /&gt;
 wget https://code.google.com/p/google-api-python-client/downloads/detail?name=oauth2client-1.2.zip&lt;br /&gt;
&lt;br /&gt;
Git:&lt;br /&gt;
 git clone https://github.com/google/google-api-python-client&lt;br /&gt;
 git clone https://github.com/google/oauth2client&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* google-api-python-client - Google APIs Client Library for Python - Google Project Hosting - https://code.google.com/p/google-api-python-client/&lt;br /&gt;
&lt;br /&gt;
== Documentation Tools ==&lt;br /&gt;
&lt;br /&gt;
=== pydoc ===&lt;br /&gt;
&lt;br /&gt;
pydoc - http://docs.python.org/library/pydoc.html&lt;br /&gt;
: Documentation generator and online help system&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Doxygen and Doxypy ===&lt;br /&gt;
&lt;br /&gt;
See [[Python/Doxygen]]&lt;br /&gt;
&lt;br /&gt;
=== Sphinx ===&lt;br /&gt;
&lt;br /&gt;
Sphinx - http://sphinx.pocoo.org/&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Sphinx is a tool that makes it easy to create intelligent and beautiful documentation, written by Georg Brandl and licensed under the BSD license.&lt;br /&gt;
&lt;br /&gt;
It was originally created for the new Python documentation, and it has excellent facilities for the documentation of Python projects, but C/C++ is already supported as well, and it is planned to add special support for other languages as well. Of course, this site is also created from reStructuredText sources using Sphinx!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== epydoc ===&lt;br /&gt;
&lt;br /&gt;
epydoc - http://epydoc.sourceforge.net/&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Epydoc is a tool for generating API documentation for Python modules, based on their docstrings. For an example of epydoc&#039;s output, see the API documentation for epydoc itself (html, pdf). A lightweight markup language called epytext can be used to format docstrings, and to add information about specific fields, such as parameters and instance variables. Epydoc also understands docstrings written in reStructuredText, Javadoc, and plaintext. For a more extensive example of epydoc&#039;s output, see the API documentation for Python 2.5. &amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Python 3 ==&lt;br /&gt;
&lt;br /&gt;
=== Python 3 Wall of Superpowers ===&lt;br /&gt;
&lt;br /&gt;
Python 3 Wall of Superpowers - https://python3wos.appspot.com/&lt;br /&gt;
&lt;br /&gt;
&amp;quot;As listed on PyPI - packages in red don&#039;t support python 3, packages in green do. Hopefully one day everything will be greener. &amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== New in Python 3 ===&lt;br /&gt;
&lt;br /&gt;
==== qualnames ====&lt;br /&gt;
&lt;br /&gt;
New in 3.3&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; def f():&lt;br /&gt;
...   def g():&lt;br /&gt;
...     class H: pass&lt;br /&gt;
...     return H&lt;br /&gt;
...   return g&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; H=f()()&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; # 3.3:&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; H&lt;br /&gt;
&amp;lt;class &#039;__main__.f.&amp;lt;locals&amp;gt;.g.&amp;lt;locals&amp;gt;.H&#039;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; H.__qualname__&lt;br /&gt;
&#039;f.&amp;lt;locals&amp;gt;.g.&amp;lt;locals&amp;gt;.H&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; # 2.6:&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; H&lt;br /&gt;
&amp;lt;class __main__.H at 0x2b885044b890&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; H.__qualname__&lt;br /&gt;
AttributeError: class H has no attribute &#039;__qualname__&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Python 2 or Python 3 ==&lt;br /&gt;
&lt;br /&gt;
Python2orPython3 - PythonInfo Wiki - http://wiki.python.org/moin/Python2orPython3&lt;br /&gt;
:Short version: Python 2.x is the status quo, Python 3.x is the shiny new thing.&lt;br /&gt;
:At the time of writing (July 4, 2010), the final 2.7 release is out, with a statement of extended support for this end-of-life release. The 2.x branch will see no new major releases after that. 3.x is under active and continued development, with 3.1 already available and 3.2 due for release around the turn of the year.&lt;br /&gt;
&lt;br /&gt;
Python 2.7.1 Release - http://www.python.org/download/releases/2.7.1/&lt;br /&gt;
&lt;br /&gt;
What’s New In Python 3.0 — Python v3.0.1 documentation - http://docs.python.org/release/3.0.1/whatsnew/3.0.html&lt;br /&gt;
* print() requires parenthesis&lt;br /&gt;
* raw_input() is now input()&lt;br /&gt;
&lt;br /&gt;
== Python for Windows ==&lt;br /&gt;
&lt;br /&gt;
Python for Windows - http://www.python.org/download/windows/&lt;br /&gt;
&lt;br /&gt;
=== Windows IDEs ===&lt;br /&gt;
&lt;br /&gt;
==== PyCharm ====&lt;br /&gt;
&lt;br /&gt;
 http://www.pycharm.com/&lt;br /&gt;
&lt;br /&gt;
=== Hide Console ===&lt;br /&gt;
&lt;br /&gt;
fork() does not work on windows.  So what else can we do?&lt;br /&gt;
&lt;br /&gt;
How to hide console window in python? - http://stackoverflow.com/questions/764631/how-to-hide-console-window-in-python&lt;br /&gt;
* &amp;quot;Simply save it with a .pyw extension. This will prevent the console window from opening. Explanation at the bottom of section [http://docs.python.org/2/tutorial/interpreter.html#executable-python-scripts]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== 32bit vs 64bit ===&lt;br /&gt;
&lt;br /&gt;
IDLE:&lt;br /&gt;
&lt;br /&gt;
32bit:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
C:\Python27&amp;gt;python&lt;br /&gt;
Python 2.7.6 (default, Nov 10 2013, 19:24:18) [MSC v.1500 32 bit (Intel)] on win32&lt;br /&gt;
Type &amp;quot;help&amp;quot;, &amp;quot;copyright&amp;quot;, &amp;quot;credits&amp;quot; or &amp;quot;license&amp;quot; for more information.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
64bit: (note: default path is C:\Python27)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
C:\Python27-64bit&amp;gt;python.exe&lt;br /&gt;
Python 2.7.6 (default, Nov 10 2013, 19:24:24) [MSC v.1500 64 bit (AMD64)] on win32&lt;br /&gt;
Type &amp;quot;help&amp;quot;, &amp;quot;copyright&amp;quot;, &amp;quot;credits&amp;quot; or &amp;quot;license&amp;quot; for more information.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Task Manager:&lt;br /&gt;
 python.exe *32&lt;br /&gt;
&lt;br /&gt;
 python.exe&lt;br /&gt;
&lt;br /&gt;
Platform:&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; import platform&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; platform.python_compiler()&lt;br /&gt;
 &#039;MSC v.1500 32 bit (Intel)&#039;&lt;br /&gt;
&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; import platform&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; platform.python_compiler()&lt;br /&gt;
 &#039;MSC v.1500 64 bit (AMD64)&#039;&lt;br /&gt;
&lt;br /&gt;
Code: [http://stackoverflow.com/questions/2208828/detect-64bit-os-windows-in-python]&lt;br /&gt;
 import struct&lt;br /&gt;
 def is_python_64bit():&lt;br /&gt;
     return (struct.calcsize(&amp;quot;P&amp;quot;) == 8)&lt;br /&gt;
&lt;br /&gt;
=== Stand-Alone Executable ===&lt;br /&gt;
&lt;br /&gt;
==== Python ZIP Application ====&lt;br /&gt;
&lt;br /&gt;
Python can be run from a single bundled zip file - similar to a Java WAR!  Python has been able to (Allow interpreter to execute a zip file http://bugs.python.org/issue1739468)&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Python quietly added a new feature in 2.6 that makes it possible to bundle up a directory full of Python code into a single executable file.&amp;quot; [http://blog.ablepear.com/2012/10/bundling-python-files-into-stand-alone.html]&lt;br /&gt;
&lt;br /&gt;
When a python zip application is executed, it will execute &#039;__main__.py&#039; [http://docs.python.org/using/cmdline.html#interface-options]&lt;br /&gt;
&lt;br /&gt;
 mkdir app&lt;br /&gt;
 touch app/__main__.py&lt;br /&gt;
 cd app&lt;br /&gt;
 zip -r ../app.zip *&lt;br /&gt;
 cd ..&lt;br /&gt;
 python app.zip&lt;br /&gt;
&lt;br /&gt;
Load a resource - The easiest way to find and load a program bundle like this is to use the pkg_resources module. - http://packages.python.org/distribute/pkg_resources.html&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# file: app/__main__.py&lt;br /&gt;
&lt;br /&gt;
import pkg_resources&lt;br /&gt;
&lt;br /&gt;
def main():&lt;br /&gt;
  print(&#039;The rain in Spain falls mainly in the plain.&#039;)&lt;br /&gt;
  print(pkg_resources.resource_string(&#039;resources&#039;, &#039;inFrance.txt&#039;))&lt;br /&gt;
&lt;br /&gt;
if __name__ == &#039;__main__&#039;:&lt;br /&gt;
  main()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now use a bit of UNIX magic to turn app2.zip into an executable:&lt;br /&gt;
 echo &#039;#!/usr/bin/env python&#039; | cat - app2.zip &amp;gt; app2&lt;br /&gt;
 chmod +x app2&lt;br /&gt;
&lt;br /&gt;
&amp;quot;The zip file format is designed to allow a small executable program to be inserted at the front (that&#039;s how self-extracting zip files are created), so this is kosher and doesn&#039;t corrupt the zip file.&amp;quot; [http://blog.ablepear.com/2012/10/bundling-python-files-into-stand-alone.html]&lt;br /&gt;
&lt;br /&gt;
Now you can simply run app2 like any executable.&lt;br /&gt;
 $ ./app2&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* Able Pear Software: Bundling Python files into a stand-alone executable - http://blog.ablepear.com/2012/10/bundling-python-files-into-stand-alone.html&lt;br /&gt;
* PEP 441 -- Improving Python ZIP Application Support - http://www.python.org/dev/peps/pep-0441/&lt;br /&gt;
* Issue 1739468: Allow interpreter to execute a zip file - Python tracker - http://bugs.python.org/issue1739468&lt;br /&gt;
* Package Discovery and Resource Access using pkg_resources — Distribute documentation - http://packages.python.org/distribute/pkg_resources.html&lt;br /&gt;
&lt;br /&gt;
==== Shell Python Loader ====&lt;br /&gt;
&lt;br /&gt;
Came before the Python ZIP Application support.&lt;br /&gt;
&lt;br /&gt;
Python zip exe - Noah.org - http://www.noah.org/wiki/Python_zip_exe&lt;br /&gt;
&lt;br /&gt;
&amp;quot;This takes your Python application and packages it into a single executable shell script. You application can be made of up multiple python scripts. The executable shell script is also compressed, so the resulting script is smaller than the original. This should work on any system that has Python and a Bourne shell (works on Cygwin too). Note that this does not package the Python interpreter into the executable. This packages only you python code into a zip file, but this still allows you to distribute your application as a single shell script that will run on any system with Python installed.  In theory, you could zip the .pyc files, but the byte code is guaranteed to run only on exactly the same version Python interpreter (including minor version). It is safer to just package the .py files.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
First you need to zip all your python files:&lt;br /&gt;
 zip main.zip main.py spam.py eggs.py&lt;br /&gt;
&lt;br /&gt;
zipheader.sh:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/sh&lt;br /&gt;
# This is a self-extracting executable.&lt;br /&gt;
# Execute this like any normal executable.&lt;br /&gt;
# You may need to &amp;quot;chmod a+x&amp;quot; this file.&lt;br /&gt;
# This is a binary ZIP file with a Python loader header.&lt;br /&gt;
#&lt;br /&gt;
# Bourne shell loader:&lt;br /&gt;
PYTHON=$(which python 2&amp;gt;/dev/null)&lt;br /&gt;
if [ ! -x &amp;quot;$PYTHON&amp;quot; ] ; then&lt;br /&gt;
    echo &amp;quot;Python not found!&amp;quot;&lt;br /&gt;
    exit 1&lt;br /&gt;
fi&lt;br /&gt;
exec $PYTHON -c &amp;quot;&lt;br /&gt;
# Python loader:&lt;br /&gt;
import sys, os&lt;br /&gt;
if int(sys.version[0])&amp;lt;2:&lt;br /&gt;
    print &#039;Python version 2.3 final or greater is required.&#039;&lt;br /&gt;
    print &#039;Your version is&#039;, sys.version&lt;br /&gt;
    os._exit(1)&lt;br /&gt;
major = sys.version_info[0]&lt;br /&gt;
minor = sys.version_info[1]&lt;br /&gt;
releaselevel = sys.version_info[3]&lt;br /&gt;
if (major==2 and minor&amp;lt;3) or (major==2 and minor==3 and releaselevel!=&#039;final&#039;):&lt;br /&gt;
    print &#039;Python version 2.3 final or greater is required.&#039;&lt;br /&gt;
    print &#039;Your version is&#039;, sys.version&lt;br /&gt;
    os._exit(1)&lt;br /&gt;
sys.path.insert(0, sys.argv[1])&lt;br /&gt;
del sys.argv[0:1]&lt;br /&gt;
import main&lt;br /&gt;
main.main()&lt;br /&gt;
&amp;quot; $0 $@&lt;br /&gt;
# Zip file:&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Concatinate zipheader.sh with the zip file.&lt;br /&gt;
 cat zipheader.sh main.zip &amp;gt; main&lt;br /&gt;
&lt;br /&gt;
Set main as executable.&lt;br /&gt;
 chmod +x main&lt;br /&gt;
&lt;br /&gt;
&amp;quot;This is an improvement on Joerg Raedler&#039;s Python recipe, [http://code.activestate.com/recipes/215301-binding-main-skript-and-modules-to-one-executable-/ 215301]. The original closes stdin. The herefile in the shell script redirects stdin before python gets a chance to start. This disables raw_input() and anything else that reads sys.stdin. Unfortunately, Raedler&#039;s boot script closes stdin, which is a fairly big limitation. The herefile in the shell script (END_OF_PYTHON_CODE) redirects stdin before python starts; stdin is closed at the end of the herefile. This disables raw_input() and anything else that reads sys.stdin. &amp;quot;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* Python zip exe - Noah.org - http://www.noah.org/wiki/Python_zip_exe&lt;br /&gt;
* Build a compressed self-extracting executable script on UNIX « Python recipes « ActiveState Code - http://code.activestate.com/recipes/497000-build-a-compressed-self-extracting-executable-scri/&lt;br /&gt;
* binding main skript and modules to one executable with python-2.3 under UNIX « Python recipes « ActiveState Code - http://code.activestate.com/recipes/215301-binding-main-skript-and-modules-to-one-executable-/&lt;br /&gt;
&lt;br /&gt;
==== py2exe ====&lt;br /&gt;
&lt;br /&gt;
py2exe - http://www.py2exe.org/&lt;br /&gt;
: &amp;quot;py2exe is a Python Distutils extension which converts Python scripts into executable Windows programs, able to run without requiring a Python installation. &amp;quot;&lt;br /&gt;
&lt;br /&gt;
Tutorial - http://www.py2exe.org/index.cgi/Tutorial&lt;br /&gt;
&lt;br /&gt;
Note: Install the version that matches your version of python&lt;br /&gt;
&lt;br /&gt;
Note: run installer &amp;quot;as administrator&amp;quot;&lt;br /&gt;
&lt;br /&gt;
setup.py&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from distutils.core import setup&lt;br /&gt;
import py2exe&lt;br /&gt;
&lt;br /&gt;
setup(console=[&#039;hello.py&#039;])&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
No console window version: [http://ubuntuforums.org/showthread.php?t=728170] [http://stackoverflow.com/questions/3275293/hiding-console-window-of-python-gui-app-with-py2exe]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from distutils.core import setup&lt;br /&gt;
import py2exe&lt;br /&gt;
&lt;br /&gt;
setup(windows=[&#039;hello.py&#039;])&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Build:&lt;br /&gt;
 python setup.py py2exe&lt;br /&gt;
&lt;br /&gt;
pygame is more complex: http://www.pygame.org/wiki/Pygame2exe&lt;br /&gt;
&lt;br /&gt;
==== py2app ====&lt;br /&gt;
&lt;br /&gt;
==== pyinstaller ====&lt;br /&gt;
&lt;br /&gt;
==== cx_Freeze ====&lt;br /&gt;
&lt;br /&gt;
=== Windows Libraries ===&lt;br /&gt;
&lt;br /&gt;
==== Python for Windows Extensions - PyWin32 ====&lt;br /&gt;
&lt;br /&gt;
Python for Windows Extensions - http://starship.python.net/~skippy/win32/&lt;br /&gt;
* There is a build for each python version and architecture (32bit vs 64bit)&lt;br /&gt;
&lt;br /&gt;
Follow event viewer&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import win32evtlog  # install Python for Windows Extensions - http://starship.python.net/~skippy/win32/&lt;br /&gt;
&lt;br /&gt;
# open event viewer&lt;br /&gt;
server = &amp;quot;localhost&amp;quot;&lt;br /&gt;
source = &amp;quot;System&amp;quot;&lt;br /&gt;
handle = win32evtlog.OpenEventLog(server, source)&lt;br /&gt;
&lt;br /&gt;
# seek to end of log&lt;br /&gt;
flags = win32evtlog.EVENTLOG_BACKWARDS_READ | win32evtlog.EVENTLOG_SEQUENTIAL_READ&lt;br /&gt;
events = win32evtlog.ReadEventLog(handle, flags, 0)&lt;br /&gt;
&lt;br /&gt;
# return to normal reading direction&lt;br /&gt;
flags = win32evtlog.EVENTLOG_FORWARDS_READ | win32evtlog.EVENTLOG_SEQUENTIAL_READ&lt;br /&gt;
win32evtlog.ReadEventLog(handle, flags, 0)  # ignore initial logs&lt;br /&gt;
&lt;br /&gt;
# loop through events&lt;br /&gt;
while True:&lt;br /&gt;
    events = win32evtlog.ReadEventLog(handle, flags, 0)&lt;br /&gt;
    if events:&lt;br /&gt;
        for event in events:&lt;br /&gt;
            data = event.StringInserts&lt;br /&gt;
            if data:&lt;br /&gt;
                # Example: 07/03/14 12:34:35 - MYEVENTSOURCE - 0 - 1 - 4  &amp;quot;HELLO&amp;quot;&lt;br /&gt;
                print event.TimeGenerated, &#039;-&#039;, event.SourceName, &#039;-&#039;, event.EventCategory, &#039;-&#039;, event.EventID, &#039;-&#039;, event.EventType, &#039;-&#039;, &#039;&amp;quot;%s&amp;quot;&#039; % &amp;quot; &amp;quot;.join(data)&lt;br /&gt;
    time.sleep(.5)  # yield cpu&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* PyWin32: Getting Windows Event Logs « The Mouse Vs. The Python - http://www.blog.pythonlibrary.org/2010/07/27/pywin32-getting-windows-event-logs/&lt;br /&gt;
&lt;br /&gt;
==== PyCrypto for Windows ====&lt;br /&gt;
&lt;br /&gt;
Download Install: http://www.voidspace.org.uk/python/modules.shtml#pycrypto&lt;br /&gt;
&lt;br /&gt;
Installation: [http://stackoverflow.com/questions/11405549/how-do-i-install-pycrypto-on-windows]&lt;br /&gt;
 easy_install http://www.voidspace.org.uk/downloads/pycrypto26/pycrypto-2.6.win32-py2.7.exe&lt;br /&gt;
 easy_install http://www.voidspace.org.uk/downloads/pycrypto26/pycrypto-2.6.win-amd64-py2.7.exe&lt;br /&gt;
&lt;br /&gt;
==== Paramiko for Windows ====&lt;br /&gt;
&lt;br /&gt;
# Install PyCrypto (above)&lt;br /&gt;
# pip install paramiko&lt;br /&gt;
&lt;br /&gt;
==== PyGame for Windows ====&lt;br /&gt;
&lt;br /&gt;
Download - http://www.pygame.org/download.shtml&lt;br /&gt;
* http://pygame.org/ftp/pygame-1.9.1.win32-py2.7.msi&lt;br /&gt;
&lt;br /&gt;
== Indentation ==&lt;br /&gt;
&lt;br /&gt;
Python: Myths about Indentation - http://www.secnetix.de/olli/Python/block_indentation.hawk&lt;br /&gt;
:There are quite some prejudices and myths about Python&#039;s indentation rules among people who don&#039;t really know Python. I&#039;ll try to address a few of these concerns on this page. &lt;br /&gt;
*&amp;quot;Whitespace is significant in Python source code.&amp;quot;&lt;br /&gt;
*&amp;quot;Python forces me to use a certain indentation style.&amp;quot;&lt;br /&gt;
*&amp;quot;You cannot safely mix tabs and spaces in Python.&amp;quot;&lt;br /&gt;
*&amp;quot;I just don&#039;t like it.&amp;quot;&lt;br /&gt;
*&amp;quot;How does the compiler parse the indentation?&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== PEP - Python Enhancement Proposals ==&lt;br /&gt;
&lt;br /&gt;
Python Enhancement Proposals (PEPs)&lt;br /&gt;
&lt;br /&gt;
* Index of Python Enhancement Proposals (PEPs) - http://www.python.org/dev/peps/&lt;br /&gt;
&lt;br /&gt;
== Convert Tabs to Spaces ==&lt;br /&gt;
&lt;br /&gt;
Convert tabs to 4 spaces:&lt;br /&gt;
 sed -i &#039;s/\t/    /g&#039;  script.py&lt;br /&gt;
&lt;br /&gt;
== Linting ==&lt;br /&gt;
&lt;br /&gt;
* pep8 - python style guide checker&lt;br /&gt;
* pychecker - more verbose, imports code, slower&lt;br /&gt;
* pylint - most verbose, configurable, &amp;quot;rates&amp;quot; code&lt;br /&gt;
* pyflakes - least verbose (dead/redundant code)&lt;br /&gt;
&lt;br /&gt;
rpmforge:&lt;br /&gt;
 yum install pyflakes pychecker&lt;br /&gt;
 # pylint - not sure which pacakge includes&lt;br /&gt;
&lt;br /&gt;
=== pep8 ===&lt;br /&gt;
&lt;br /&gt;
See [[Python/pep8]]&lt;br /&gt;
&lt;br /&gt;
=== pychecker ===&lt;br /&gt;
&lt;br /&gt;
See [[Python/pychecker]]&lt;br /&gt;
&lt;br /&gt;
=== pylint ===&lt;br /&gt;
&lt;br /&gt;
See [[Python/pylint]]&lt;br /&gt;
&lt;br /&gt;
== PEP8 Style Guidlines ==&lt;br /&gt;
&lt;br /&gt;
PEP 8 -- Style Guide for Python Code - http://www.python.org/dev/peps/pep-0008/&lt;br /&gt;
&lt;br /&gt;
* Use spaces - Use 4 spaces per indentation level.&lt;br /&gt;
* Never mix tabs and spaces.&lt;br /&gt;
* Limit all lines to a maximum of 79 characters.&lt;br /&gt;
* Line wrapping - The preferred way of wrapping long lines is by using Python&#039;s implied line continuation inside parentheses, brackets and braces.  Long lines can be broken over multiple lines by wrapping expressions in parentheses.&lt;br /&gt;
* Encoding - For Python 3.0 and beyond, UTF-8 is preferred over Latin-1, see PEP 3120.&lt;br /&gt;
* Imports should usually be on separate lines&lt;br /&gt;
* Avoid extraneous whitespace in most situations&lt;br /&gt;
* Always use &#039;self&#039; for the first argument to instance methods.&lt;br /&gt;
&lt;br /&gt;
=== PEP8 Style Checker ===&lt;br /&gt;
&lt;br /&gt;
See [[#pep8]]&lt;br /&gt;
&lt;br /&gt;
== Benefits of Python ==&lt;br /&gt;
&lt;br /&gt;
What is the return on investment for this group by learning Python? The list of benefits below sums up what the language has to offer:&lt;br /&gt;
* Python is designed from the ground up to encourage maintainable, readable and reusable code. It has great support for particular paradigms such as object-oriented programming.&lt;br /&gt;
* Python code is usually around a quarter of the length of code generated by C++ or Java - less typing, less debugging and less maintenance.&lt;br /&gt;
* Python does not need to be compiled or linked, which allows for a more iterative programming style and a quicker development cycle.&lt;br /&gt;
* Python is extremely portable. Code can be easily exchanged between Windows, Mac OS and Linux with little to no modification.&lt;br /&gt;
* Python comes with a staggering array of standard libraries and mature third-party projects. Web development, scientific computing, operator system access and network scripting are all supported.&lt;br /&gt;
* Python can talk with many other languages easily. It has support for invoking C and C++ code and can itself be called from libraries written in these languages. &lt;br /&gt;
&lt;br /&gt;
Source: http://quantstart.com/articles/Quant-Reading-List-Python-Programming/ - Quant Reading List Python Programming&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Benefits of Python:&lt;br /&gt;
* Python is available for most operating systems, including Windows, UNIX, Linux, and Mac OS.&lt;br /&gt;
* Python&#039;s clean object-oriented design and extensive support libraries offer two to ten fold the programmer productivity seen with languages like C, C++, C#, Java, VB, and Perl.&lt;br /&gt;
&lt;br /&gt;
Source: Python Development - Benefits of Python - Digital Mesh - http://www.digitalmesh.com/offshore-development-center/python-development/benefits-of-python.html&lt;br /&gt;
&lt;br /&gt;
== Python Package Management ==&lt;br /&gt;
&lt;br /&gt;
=== Install Module ===&lt;br /&gt;
&lt;br /&gt;
Installing Python Modules — Python v2.7.1 documentation - http://docs.python.org/install/index.html&lt;br /&gt;
&lt;br /&gt;
The new standard: Distutils&lt;br /&gt;
 python setup.py install&lt;br /&gt;
&lt;br /&gt;
Download and extract target package, then:&lt;br /&gt;
 sudo python setup.py install&lt;br /&gt;
&lt;br /&gt;
Note: Running setup.py install builds and installs all modules in one run&lt;br /&gt;
&lt;br /&gt;
Help:&lt;br /&gt;
 python setup.py --help&lt;br /&gt;
&lt;br /&gt;
Incremental method:&lt;br /&gt;
 python setup.py build&lt;br /&gt;
 python setup.py install&lt;br /&gt;
 python setup.py build --help   # help&lt;br /&gt;
&lt;br /&gt;
Force rebuild and install:&lt;br /&gt;
 python setup.py build --force    # if have to repeat&lt;br /&gt;
 python setup.py install --force  # if have to repeat&lt;br /&gt;
&lt;br /&gt;
Default installation paths:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Platform	Standard installation location		Default value&lt;br /&gt;
Unix (pure)	prefix/lib/pythonX.Y/site-packages	/usr/local/lib/pythonX.Y/site-packages&lt;br /&gt;
Unix (non-pure)	exec-prefix/lib/pythonX.Y/site-packages	/usr/local/lib/pythonX.Y/site-packages&lt;br /&gt;
Windows		prefix					C:\Python&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alternate install path:&lt;br /&gt;
 python setup.py install --home=&amp;lt;dir&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alternate base folders:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Type of file			Installation Directory	Override option&lt;br /&gt;
pure module distribution	home/lib/python		--install-purelib&lt;br /&gt;
non-pure module distribution	home/lib/python		--install-platlib&lt;br /&gt;
scripts				home/bin		--install-scripts&lt;br /&gt;
data				home/share		--install-data&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Modifying Python’s Search Path:&lt;br /&gt;
 import sys&lt;br /&gt;
 sys.path.append(&#039;/www/python/&#039;)&lt;br /&gt;
&lt;br /&gt;
=== Python Package Index ===&lt;br /&gt;
&lt;br /&gt;
user-submitted Python packages:&lt;br /&gt;
 http://pypi.python.org/pypi&lt;br /&gt;
&lt;br /&gt;
 sudo python setup.py install&lt;br /&gt;
&lt;br /&gt;
Package Site:&lt;br /&gt;
 http://pypi.python.org/pypi/[PACKAGE]&lt;br /&gt;
 http://pypi.python.org/pypi/test&lt;br /&gt;
&lt;br /&gt;
If they are on http://pypi.python.org/:&lt;br /&gt;
 pip install foo&lt;br /&gt;
&lt;br /&gt;
[http://stackoverflow.com/questions/410163/for-python-programmers-is-there-anything-equivalent-to-perls-cpan For Python programmers, is there anything equivalent to Perl&#039;s CPAN? - Stack Overflow]&lt;br /&gt;
&lt;br /&gt;
=== Easy Installation ===&lt;br /&gt;
&lt;br /&gt;
EasyInstall - The PEAK Developers&#039; Center - http://peak.telecommunity.com/DevCenter/EasyInstall&lt;br /&gt;
: Easy Install is a python module (easy_install) bundled with setuptools that lets you automatically download, build, install, and manage Python packages.&lt;br /&gt;
&lt;br /&gt;
CheeseShopTutorial - PythonInfo Wiki - http://wiki.python.org/moin/CheeseShopTutorial&lt;br /&gt;
: EasyInstall (easy_install) gives you a quick and painless way to install packages remotely by connecting to the Package Index or even other websites via HTTP. It is somewhat analogous to the CPAN and PEAR tools for Perl and PHP, respectively.&lt;br /&gt;
&lt;br /&gt;
=== pip ===&lt;br /&gt;
&lt;br /&gt;
See [[Python/pip]]&lt;br /&gt;
&lt;br /&gt;
==== Create PIP Package ====&lt;br /&gt;
&lt;br /&gt;
See [[Python/pip#Create PIP Package]]&lt;br /&gt;
&lt;br /&gt;
=== Distribute ===&lt;br /&gt;
&lt;br /&gt;
distribute - Easily download, build, install, upgrade, and uninstall Python packages&lt;br /&gt;
&lt;br /&gt;
distribute 0.6.24 : Python Package Index - http://pypi.python.org/pypi/distribute&lt;br /&gt;
&lt;br /&gt;
Installation:&lt;br /&gt;
 mkdir -p ~/.src ; cd ~/.src&lt;br /&gt;
 wget http://pypi.python.org/packages/source/d/distribute/distribute-0.6.24.tar.gz#md5=17722b22141aba8235787f79800cc452&lt;br /&gt;
 tar -zvxf distribute-0.6.24.tar.gz&lt;br /&gt;
 cd distribute-0.6.24&lt;br /&gt;
 sudo python setup.py install&lt;br /&gt;
&lt;br /&gt;
Test:&lt;br /&gt;
 echo &amp;quot;import distribute&amp;quot; | grep python&lt;br /&gt;
&lt;br /&gt;
== Named Parameters ==&lt;br /&gt;
&lt;br /&gt;
http://diveintopython.org/power_of_introspection/optional_arguments.html&lt;br /&gt;
&lt;br /&gt;
Python allows function arguments to have default values; if the function is called without the argument, the argument gets its default value. Futhermore, arguments can be specified in any order by using named arguments. Stored procedures in SQL Server Transact/SQL can do this, so if you&#039;re a SQL Server scripting guru, you can skim this part.&lt;br /&gt;
&lt;br /&gt;
Here is an example of info, a function with two optional arguments:&lt;br /&gt;
&lt;br /&gt;
 def info(object, spacing=10, collapse=1):&lt;br /&gt;
&lt;br /&gt;
spacing and collapse are optional, because they have default values defined. object is required, because it has no default value. If info is called with only one argument, spacing defaults to 10 and collapse defaults to 1. If info is called with two arguments, collapse still defaults to 1.&lt;br /&gt;
&lt;br /&gt;
Say you want to specify a value for collapse but want to accept the default value for spacing. In most languages, you would be out of luck, because you would need to call the function with three arguments. But in Python, arguments can be specified by name, in any order. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
http://www.wellho.net/mouth/1871_Optional-and-named-parameters-in-Python.html&lt;br /&gt;
&lt;br /&gt;
If you add a parameter with two asterixes (**) on the end of a function definition, that parameter is taken as being the name of a dictionary into which all otherwise unidentified parameters are stored. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def getnet(gross, taxrate=17.5, **others):&lt;br /&gt;
  net = gross / (1.0 + taxrate*0.01)&lt;br /&gt;
  for more in others.keys():&lt;br /&gt;
    print &amp;quot;GETNET:&amp;quot;,more,&amp;quot; - &amp;quot;,others[more]&lt;br /&gt;
  return neto&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Python vs other languages ==&lt;br /&gt;
&lt;br /&gt;
[http://www.strombergers.com/python/ Python is Cool (and Perl is not), Especially for C/C++ Programmers]&lt;br /&gt;
&lt;br /&gt;
==Experimenting with Memory Remanence==&lt;br /&gt;
[http://citp.princeton.edu/memory/exp/ Experimenting with Memory Remanence]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    #!/usr/bin/env python&lt;br /&gt;
&lt;br /&gt;
    # a pirate&#039;s favorite chemical element&lt;br /&gt;
    a = &amp;quot;&amp;quot;&lt;br /&gt;
    while 1: a += &amp;quot;ARGON&amp;quot; &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 sudo strings /dev/mem | less&lt;br /&gt;
&lt;br /&gt;
==UTOSC 2008 - 90 percent of the Python you need to know (in 90 minutes)==&lt;br /&gt;
See [[UTOSC 2008 - 90 percent of the Python you need to know (in 90 minutes)]]&lt;br /&gt;
&lt;br /&gt;
== Program Layout Best Practices Presentation ==&lt;br /&gt;
&lt;br /&gt;
Program layout best practices - Seth House &amp;lt;seth@eseth.com&amp;gt; - Utah Django User Group - 2011-06-23&lt;br /&gt;
* Slides - https://github.com/whiteinge/presentations/tree/master/upyug_2011-06-09_program-layout&lt;br /&gt;
* Video - http://blip.tv/utah-open-source/python-layout-best-practices-for-modules-django-cli-utah-django-user-group-5315808&lt;br /&gt;
&lt;br /&gt;
Module skeleton:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
# coding: utf-8&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;Module docstring&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
__author__ = ’Mr. Me &amp;lt;me@example.net&amp;gt;’&lt;br /&gt;
__version__ = ’1.2.3’&lt;br /&gt;
&lt;br /&gt;
if __name__==’__main__’:&lt;br /&gt;
 main()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Executing modules as scripts&lt;br /&gt;
 # PEP 338:&lt;br /&gt;
 python -m SimpleHTTPServer&lt;br /&gt;
&lt;br /&gt;
== CLI package ==&lt;br /&gt;
&lt;br /&gt;
cli — command line tools — pyCLI v1.1.1 documentation - http://packages.python.org/pyCLI/&lt;br /&gt;
&lt;br /&gt;
== Python IDE ==&lt;br /&gt;
&lt;br /&gt;
IntegratedDevelopmentEnvironments - PythonInfo Wiki - http://wiki.python.org/moin/IntegratedDevelopmentEnvironments&lt;br /&gt;
* IDEs with introspection-based code completion and integrated debugger&lt;br /&gt;
* IDEs with introspection-based code completion /or/ integrated debugger&lt;br /&gt;
* IDEs with integrated gui builder&lt;br /&gt;
* Editors&lt;br /&gt;
* Reviews&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Is there a good, free Python IDE for Windows? - Stack Overflow - http://stackoverflow.com/questions/126753/is-there-a-good-free-python-ide-for-windows&lt;br /&gt;
* Eclipse with PyDev&lt;br /&gt;
* Aptana Studio 3&lt;br /&gt;
* Active State also offers Komodo Edit&lt;br /&gt;
* WingWare - http://www.wingware.com/&lt;br /&gt;
* Eric IDE - http://www.die-offenbachs.de/eric/index.html&lt;br /&gt;
* MMM-Experts - Products - http://mmm-experts.com/Products.aspx?ProductId=4&lt;br /&gt;
** PyScripter is a Python IDE built in Python for Delphi(P4D) components and created with the ambition to become competitive in functionality with commercial Windows-based IDEs available for other languages. Being built in a compiled language is rather snappier than some of the other Python IDEs and provides an extensive blend of features that make it a productive Python development environment. &lt;br /&gt;
* ActiveState Python comes with PythonWin which is reasonably good&lt;br /&gt;
* PyCharm from JetBrains is not free in general, but has free early access program.&lt;br /&gt;
* SPE - Stani&#039;s Python Editor, is pretty awesome. See http://pythonide.blogspot.com/.&lt;br /&gt;
* You may want to take a look at the pdb module - http://docs.python.org/lib/module-pdb.html&lt;br /&gt;
* Geany (http://www.geany.org/) is a fairly light text editor that does a lot of IDE-like stuff.&lt;br /&gt;
* SciTE: http://www.scintilla.org/SciTE.html&lt;br /&gt;
* Editra: http://editra.org/ &lt;br /&gt;
* Netbeans has support for python development in their Python Early Access version. - http://www.netbeans.org/features/python/&lt;br /&gt;
* I use Notepad++ with the appropriate settings.&lt;br /&gt;
* The Eric Python IDE - http://www.die-offenbachs.de/eric/index.html&lt;br /&gt;
* BOa Constructor www.boa-constructor.sourceforge.net really nice! drag and drop stuff!&lt;br /&gt;
* DrPtyhon is also very nice, and has many plug-ins. http://drpython.sourceforge.net/&lt;br /&gt;
* Vim&lt;br /&gt;
* I will make a plug for my preference of Python development environments: SPE. SPE is an integrated development environment that provides code completion, integrated Python shell, calltips, and various helper tools like notes and todo lists. It also includes wxGlade so you can make wxPython applications easily. Plus, it includes the python debugger WinPdb.&lt;br /&gt;
* http://groups.google.com.tr/group/python_opengl this software is my sample visual python ide.its demo version.&lt;br /&gt;
* I use PyScripter, and find it pretty awesome.&lt;br /&gt;
* There is one Python IDE written in Java: jHepWork: http://jwork.org/jhepwork/ it can detect Python&#039;s indentation rules rather nicely (+ detects structure of a code and syntax)&lt;br /&gt;
* gvim built with your python version support and with this plugins:&lt;br /&gt;
** NERDTree (don&#039;t read he&#039;s blog ;)&lt;br /&gt;
** matchit (it&#039;s builtin in new versions just put a symlink or junction)&lt;br /&gt;
** pyflakes&lt;br /&gt;
** pysmell&lt;br /&gt;
* Try Python Tools for Visual Studio. Supports CPython and IronPython. - http://pytools.codeplex.com/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
PythonEditors - PythonInfo Wiki - http://wiki.python.org/moin/PythonEditors&lt;br /&gt;
* List of editors&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Python Ide - http://c2.com/cgi/wiki?PythonIde&lt;br /&gt;
: There are a lot of Ides for PythonLanguage springing up. Many of them written in Python &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Is there a better Python IDE? « Lennart Regebro: Python, Plone, Web - http://regebro.wordpress.com/2010/10/09/is-there-a-better-python-ide/&lt;br /&gt;
: I’m currently a user of WingIDE, but sometimes I feel the need for something better, mainly something that is a bit more stable. WingIDE often hangs when switching projects, sometimes the file listing decides that you must double-click on the expand arrow instead of just click on it, etc. It still doesn’t have macros despite this being a much requested feature (how hard can it be to add, really?) and I never really get the hang of the SVN integration, so I just ignore it. And they keep recommending me to use WingIDE’s separate instance of GTK instead of the System GTK, which is daft. Their designs are ugly, and it should work with the system GTK so it looks the same. Anything else is just silly.&lt;br /&gt;
&lt;br /&gt;
=== Open Komodo ===&lt;br /&gt;
&lt;br /&gt;
Open Komodo - http://www.openkomodo.com/&lt;br /&gt;
: Open Komodo is the source code repository for Komodo Edit - a free multi-language editor for dynamic languages, based on the award-winning Komodo IDE. ActiveState created the Open Komodo code repository in August 2007 and it has been used since then for building all Komodo Edit releases.&lt;br /&gt;
&lt;br /&gt;
=== Eclipse ===&lt;br /&gt;
&lt;br /&gt;
Build an Eclipse development environment for Perl, Python, and PHP - http://www.eclipse.org/resources/resource.php?id=485&lt;br /&gt;
: This tutorial shows how Eclipse&#039;s DLTK makes it possible to build development tools for scripting languages. In particular, it explains how to implement syntax coloring, user preferences, and interpreter integration in a plug-in-based project.&lt;br /&gt;
&lt;br /&gt;
See [[#PyDev]]&lt;br /&gt;
&lt;br /&gt;
=== EasyEclipse ===&lt;br /&gt;
&lt;br /&gt;
EasyEclipse - http://www.easyeclipse.org/&lt;br /&gt;
:EasyEclipse packages together Eclipse, the open-source software&lt;br /&gt;
development platform, and selected open source plugins.&lt;br /&gt;
:We select, assemble, test, patch, build installers and document&lt;br /&gt;
a full IDE, offered as reliable distributions and plugins.&lt;br /&gt;
:EasyEclipse is:&lt;br /&gt;
* Free and open-source,&lt;br /&gt;
* Easy to download and install, and&lt;br /&gt;
* Simple to maintain, without version and dependency issues.&lt;br /&gt;
&lt;br /&gt;
EasyEclipse for Python - http://www.easyeclipse.org/site/distributions/python.html&lt;br /&gt;
&lt;br /&gt;
EclipsePythonIntegration - PythonInfo Wiki - http://wiki.python.org/moin/EclipsePythonIntegration&lt;br /&gt;
: Using Eclipse as a Python editor&lt;br /&gt;
&lt;br /&gt;
=== PyDev ===&lt;br /&gt;
&lt;br /&gt;
PyDev - http://pydev.org/&lt;br /&gt;
: PyDev is a Python IDE for Eclipse, which may be used in Python, Jython and IronPython development.&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
Pydev - http://pydev.sourceforge.net/ (old link)&lt;br /&gt;
&lt;br /&gt;
How to Configure Eclipse for Python - http://www.rose-hulman.edu/class/csse/resources/Eclipse/eclipse-python-configuration.htm&lt;br /&gt;
&lt;br /&gt;
Python Development with PyDev and Eclipse - Tutorial - http://www.vogella.de/articles/Python/article.html&lt;br /&gt;
: This article describes how to write and debug Python programs with Eclipse&lt;br /&gt;
&lt;br /&gt;
PyDev Getting Started - http://pydev.org/manual_101_root.html&lt;br /&gt;
&lt;br /&gt;
Running a program - http://pydev.org/manual_101_run.html&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
Supported Task Tags:&lt;br /&gt;
* TODO:&lt;br /&gt;
* TASK:&lt;br /&gt;
* FIXME:&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
Installation:&lt;br /&gt;
# Platform Runtime Binary (download around 45-50 MB) - http://download.eclipse.org/eclipse/downloads/ or http://www.eclipse.org/downloads/&lt;br /&gt;
#* Example: Eclipse Classic 4.2.2&lt;br /&gt;
# Eclipse Software Add - PyDev: http://pydev.org/updates&lt;br /&gt;
# Eclipse Software Add - MercurialEclipse: http://cbes.javaforge.com/update  [http://javaforge.com/project/HGE] [http://mercurial.selenic.com/wiki/MercurialEclipse]&lt;br /&gt;
# Switch perspectives to PyDev&lt;br /&gt;
&lt;br /&gt;
=== The Eric Python IDE ===&lt;br /&gt;
&lt;br /&gt;
The Eric Python IDE - http://eric-ide.python-projects.org/&lt;br /&gt;
:Eric is a full featured Python and Ruby editor and IDE, written in python. It is based on the cross platform Qt gui toolkit, integrating the highly flexible Scintilla editor control. It is designed to be usable as everdays&#039; quick and dirty editor as well as being usable as a professional project management tool integrating many advanced features Python offers the professional coder. eric4 includes a plugin system, which allows easy extension of the IDE functionality with plugins downloadable from the net.&lt;br /&gt;
&lt;br /&gt;
Eric Python IDE - Wikipedia - http://en.wikipedia.org/wiki/Eric_Python_IDE&lt;br /&gt;
&lt;br /&gt;
=== Wingware Python IDE ===&lt;br /&gt;
&lt;br /&gt;
The Intelligent Development Environment for Python Programmers - Wingware Python IDE - http://www.wingware.com/&lt;br /&gt;
:Wingware&#039;s Python IDE is an Integrated Development Environment designed specifically for the Python programming language. Since 1999, Wingware has focused on Python.&lt;br /&gt;
&lt;br /&gt;
=== VIM ===&lt;br /&gt;
&lt;br /&gt;
Python .vimrc:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;quot; Kenneth&#039;s Preferences&lt;br /&gt;
&lt;br /&gt;
set nobackup            &amp;quot; don&#039;t create backup files&lt;br /&gt;
&amp;quot;set nohlsearch          &amp;quot; don&#039;t highlight search results&lt;br /&gt;
set hlsearch            &amp;quot; do highlight search results&lt;br /&gt;
set incsearch           &amp;quot; incremental search&lt;br /&gt;
set ignorecase          &amp;quot; ignore case during search&lt;br /&gt;
set smartcase           &amp;quot; do case sensitive search when upper case is typed&lt;br /&gt;
set shiftwidth=4        &amp;quot; shift blocks in 4 space increments&lt;br /&gt;
set tabstop=4           &amp;quot; the (typewriter) tab stops are every 4 spaces&lt;br /&gt;
set smarttab            &amp;quot; tab at beginning of line inserts 4 spaces (shiftwidth)&lt;br /&gt;
set showmatch           &amp;quot; briefly highlight matching bracket&lt;br /&gt;
set matchtime=1         &amp;quot; highlight match for 0.1 seconds&lt;br /&gt;
set background=dark     &amp;quot; black background&lt;br /&gt;
set shiftwidth=4        &amp;quot; shift blocks by 4 spaces&lt;br /&gt;
set shortmess=at        &amp;quot; use short messages so we don&#039;t have to hit enter&lt;br /&gt;
set expandtab           &amp;quot; expand tabs into spaces&lt;br /&gt;
set scrolloff=5         &amp;quot; always show 5 lines before &amp;amp; after cursor&lt;br /&gt;
set shell=bash          &amp;quot; use bash for the command shell&lt;br /&gt;
set shellcmdflag=-lc    &amp;quot; make bash startup as a login shell for ~/.bashrc&lt;br /&gt;
&amp;quot;set nowrap              &amp;quot; do not wrap long lines&lt;br /&gt;
set visualbell          &amp;quot; flash the screen rather than beep&lt;br /&gt;
set noerrorbells        &amp;quot; don&#039;t beep on errors&lt;br /&gt;
set wildmenu            &amp;quot; enable filename tab completion&lt;br /&gt;
set ruler               &amp;quot; display the ruler: shows cursor position&lt;br /&gt;
set cpoptions+=$        &amp;quot; display &#039;$&#039; at end of cw sequence&lt;br /&gt;
set title               &amp;quot; display filename and vim info in window title bar&lt;br /&gt;
set modelines=5         &amp;quot; search the first and last 5 lines for &amp;quot;vim:&amp;quot; modeline&lt;br /&gt;
set backspace=2         &amp;quot; backspace deletes&lt;br /&gt;
&lt;br /&gt;
set wildignore=*.o,*.class,*.pyc,*.pyo,*.a,*.so,*.dll,*.exe,core,*.jar,*.zip&lt;br /&gt;
&lt;br /&gt;
&amp;quot;let loaded_matchparen = 1 &amp;quot; don&#039;t highlight parenthesis match&lt;br /&gt;
&lt;br /&gt;
filetype indent on&lt;br /&gt;
&lt;br /&gt;
&amp;quot;if v:version &amp;gt; 700&lt;br /&gt;
&amp;quot;    set cursorline          &amp;quot; underline the current line&lt;br /&gt;
&amp;quot;endif&lt;br /&gt;
&lt;br /&gt;
if &amp;amp;t_Co &amp;gt; 2 || has( &amp;quot;gui_running&amp;quot; )&lt;br /&gt;
    syntax on&lt;br /&gt;
endif&lt;br /&gt;
&lt;br /&gt;
if has( &#039;mouse&#039; )&lt;br /&gt;
    set mouse=a &amp;quot; enable mouse&lt;br /&gt;
endif&lt;br /&gt;
&lt;br /&gt;
if has( &amp;quot;autocmd&amp;quot; )&lt;br /&gt;
    &amp;quot; open the file in the last place we were editing&lt;br /&gt;
    autocmd BufReadPost *&lt;br /&gt;
        \ if line(&amp;quot;&#039;\&amp;quot;&amp;quot;) &amp;gt; 1 &amp;amp;&amp;amp; line(&amp;quot;&#039;\&amp;quot;&amp;quot;) &amp;lt;= line(&amp;quot;$&amp;quot;) |&lt;br /&gt;
        \     exe &amp;quot;normal! g&#039;\&amp;quot;&amp;quot; |&lt;br /&gt;
        \ endif&lt;br /&gt;
endif&lt;br /&gt;
&lt;br /&gt;
&amp;quot;folding settings&lt;br /&gt;
set foldmethod=indent   &amp;quot;fold based on indent&lt;br /&gt;
set foldnestmax=10      &amp;quot;deepest fold is 10 levels&lt;br /&gt;
set nofoldenable        &amp;quot;dont fold by default&lt;br /&gt;
set foldlevel=10        &amp;quot;this is just what i use&lt;br /&gt;
&lt;br /&gt;
&amp;quot; Auto clear trailing white space in Python files&lt;br /&gt;
func! DeleteTrailingWS()&lt;br /&gt;
    exec &amp;quot;normal mz&amp;quot;&lt;br /&gt;
    %s/\s\+$//ge&lt;br /&gt;
    exe &amp;quot;normal `z&amp;quot;&lt;br /&gt;
endfunc&lt;br /&gt;
autocmd BufWrite *.py :call DeleteTrailingWS()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Older versions:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;quot; KENNETH SETTINGS&lt;br /&gt;
set nocp                &amp;quot; turn off compatibility mode&lt;br /&gt;
set nomodeline          &amp;quot; do not allow files to dictate vim behavior&lt;br /&gt;
&lt;br /&gt;
set incsearch           &amp;quot; incremental search&lt;br /&gt;
set ignorecase          &amp;quot; ignore case during search&lt;br /&gt;
&lt;br /&gt;
set visualbell          &amp;quot; flash the screen rather than beep&lt;br /&gt;
set noerrorbells        &amp;quot; don&#039;t beep on errors&lt;br /&gt;
set background=dark     &amp;quot; black background&lt;br /&gt;
syntax on               &amp;quot; turn on syntax highlighting&lt;br /&gt;
set hlsearch            &amp;quot; highligh last search pattern&lt;br /&gt;
&lt;br /&gt;
set nowrap              &amp;quot; do not wrap long lines&lt;br /&gt;
set scrolloff=5         &amp;quot; always show 5 lines before &amp;amp; after cursor&lt;br /&gt;
set ruler               &amp;quot; show the cursor position all the time&lt;br /&gt;
set backspace=2         &amp;quot; allow backspace deletion&lt;br /&gt;
set bs=indent,eol,start &amp;quot; allow backspacing over everything in insert mode&lt;br /&gt;
&lt;br /&gt;
set shiftwidth=4        &amp;quot; shift blocks in 4 space increments&lt;br /&gt;
set tabstop=4           &amp;quot; the (typewriter) tab stops are every 4 spaces&lt;br /&gt;
set expandtab           &amp;quot; expand tab into spaces&lt;br /&gt;
set smarttab            &amp;quot; tab at beginning of line inserts 4 spaces (shiftwidth)&lt;br /&gt;
filetype indent on      &amp;quot; turn on auto indent for specific file types&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Other options:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
set number              &amp;quot; show line numbers&lt;br /&gt;
set numberwidth=1       &amp;quot; remove space before largest line numbers&lt;br /&gt;
&lt;br /&gt;
set smartindent         &amp;quot; ?? - maybe included in &#039;filetype indent on&#039;&lt;br /&gt;
&lt;br /&gt;
set ai                  &amp;quot; always auto indent&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
if has( &amp;quot;autocmd&amp;quot; )&lt;br /&gt;
    &amp;quot; open the file in the last place we were editing&lt;br /&gt;
    autocmd BufReadPost *&lt;br /&gt;
        \ if line(&amp;quot;&#039;\&amp;quot;&amp;quot;) &amp;gt; 1 &amp;amp;&amp;amp; line(&amp;quot;&#039;\&amp;quot;&amp;quot;) &amp;lt;= line(&amp;quot;$&amp;quot;) |&lt;br /&gt;
        \     exe &amp;quot;normal! g&#039;\&amp;quot;&amp;quot; |&lt;br /&gt;
        \ endif&lt;br /&gt;
endif&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Kenneth&#039;s fio .vimrc:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;quot;source $VIM/mswin.vim&lt;br /&gt;
&lt;br /&gt;
set nobackup            &amp;quot; don&#039;t create backup files&lt;br /&gt;
&amp;quot;set nohlsearch          &amp;quot; don&#039;t highlight search results&lt;br /&gt;
set incsearch           &amp;quot; incremental search&lt;br /&gt;
set ignorecase          &amp;quot; ignore case during search&lt;br /&gt;
set smartcase           &amp;quot; do case sensitive search when upper case is typed&lt;br /&gt;
set shiftwidth=4        &amp;quot; shift blocks in 4 space increments&lt;br /&gt;
set tabstop=4           &amp;quot; the (typewriter) tab stops are every 4 spaces&lt;br /&gt;
set smarttab            &amp;quot; tab at beginning of line inserts 4 spaces (shiftwidth)&lt;br /&gt;
set showmatch           &amp;quot; briefly highlight matching bracket&lt;br /&gt;
set matchtime=1         &amp;quot; highlight match for 0.1 seconds&lt;br /&gt;
set background=dark     &amp;quot; black background&lt;br /&gt;
set shiftwidth=4        &amp;quot; shift blocks by 4 spaces&lt;br /&gt;
set shortmess=at        &amp;quot; use short messages so we don&#039;t have to hit enter&lt;br /&gt;
set expandtab           &amp;quot; expand tabs into spaces&lt;br /&gt;
set scrolloff=5         &amp;quot; always show 5 lines before &amp;amp; after cursor&lt;br /&gt;
set shell=bash          &amp;quot; use bash for the command shell&lt;br /&gt;
set shellcmdflag=-lc    &amp;quot; make bash startup as a login shell for ~/.bashrc&lt;br /&gt;
&amp;quot;set nowrap              &amp;quot; do not wrap long lines&lt;br /&gt;
set visualbell          &amp;quot; flash the screen rather than beep&lt;br /&gt;
set noerrorbells        &amp;quot; don&#039;t beep on errors&lt;br /&gt;
set wildmenu            &amp;quot; enable filename tab completion&lt;br /&gt;
set ruler               &amp;quot; display the ruler: shows cursor position&lt;br /&gt;
set cpoptions+=$        &amp;quot; display &#039;$&#039; at end of cw sequence&lt;br /&gt;
set title               &amp;quot; display filename and vim info in window title bar&lt;br /&gt;
set modelines=5         &amp;quot; search the first and last 5 lines for &amp;quot;vim:&amp;quot; modeline&lt;br /&gt;
&lt;br /&gt;
set wildignore=*.o,*.class,*.pyc,*.pyo,*.a,*.so,*.dll,*.exe,core,*.jar,*.zip&lt;br /&gt;
&lt;br /&gt;
&amp;quot;let loaded_matchparen = 1 &amp;quot; don&#039;t highlight parenthesis match&lt;br /&gt;
&lt;br /&gt;
filetype indent on&lt;br /&gt;
&lt;br /&gt;
if v:version &amp;gt; 700&lt;br /&gt;
    set cursorline          &amp;quot; underline the current line&lt;br /&gt;
endif&lt;br /&gt;
&lt;br /&gt;
if &amp;amp;t_Co &amp;gt; 2 || has( &amp;quot;gui_running&amp;quot; )&lt;br /&gt;
    syntax on&lt;br /&gt;
endif&lt;br /&gt;
&lt;br /&gt;
if has( &#039;mouse&#039; )&lt;br /&gt;
    set mouse=a &amp;quot; enable mouse&lt;br /&gt;
endif&lt;br /&gt;
&lt;br /&gt;
if has( &amp;quot;autocmd&amp;quot; )&lt;br /&gt;
    &amp;quot; open the file in the last place we were editing&lt;br /&gt;
    autocmd BufReadPost *&lt;br /&gt;
        \ if line(&amp;quot;&#039;\&amp;quot;&amp;quot;) &amp;gt; 1 &amp;amp;&amp;amp; line(&amp;quot;&#039;\&amp;quot;&amp;quot;) &amp;lt;= line(&amp;quot;$&amp;quot;) |&lt;br /&gt;
        \     exe &amp;quot;normal! g&#039;\&amp;quot;&amp;quot; |&lt;br /&gt;
        \ endif&lt;br /&gt;
endif&lt;br /&gt;
&lt;br /&gt;
&amp;quot;folding settings&lt;br /&gt;
set foldmethod=indent   &amp;quot;fold based on indent&lt;br /&gt;
set foldnestmax=10      &amp;quot;deepest fold is 10 levels&lt;br /&gt;
set nofoldenable        &amp;quot;dont fold by default&lt;br /&gt;
set foldlevel=10        &amp;quot;this is just what i use&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Interpreter vs Script ==&lt;br /&gt;
&lt;br /&gt;
Interpreter:&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; import os&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; os.uname()&lt;br /&gt;
 (&#039;Linux&#039;, &#039;demo.oeey.com&#039;, &#039;2.6.18-194.8.1.el5&#039;, &#039;#1 SMP Thu Jul 1 19:07:06 EDT 2010&#039;, &#039;i686&#039;)&lt;br /&gt;
&lt;br /&gt;
Script:&lt;br /&gt;
 #!/usr/bin/env python&lt;br /&gt;
 import os&lt;br /&gt;
 print os.uname()&lt;br /&gt;
&lt;br /&gt;
== Web Development ==&lt;br /&gt;
&lt;br /&gt;
WebProgramming - PythonInfo Wiki - http://wiki.python.org/moin/WebProgramming&lt;br /&gt;
: This topic guide attempts to cover every aspect of programming Web applications (both clients and servers) using Python. &lt;br /&gt;
&lt;br /&gt;
HOWTO Use Python in the web — Python v2.7.2 documentation - http://docs.python.org/howto/webservers.html&lt;br /&gt;
: This document shows how Python fits into the web. It presents some ways to integrate Python with a web server, and general practices useful for developing web sites.&lt;br /&gt;
&lt;br /&gt;
=== Plug Simple Python Web App ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
-------- Original Message --------&lt;br /&gt;
Subject: 	Re: Writing a simple python web app&lt;br /&gt;
Date: 	Mon, 25 Oct 2010 19:03:31 -0400&lt;br /&gt;
From: 	Roberto Mello &amp;lt;roberto.mello@gmail.com&amp;gt;&lt;br /&gt;
To: 	Provo Linux Users Group &amp;lt;plug@plug.org&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
On Sat, Sep 11, 2010 at 5:40 PM, Dave Smith &amp;lt;dave@thesmithfam.org&amp;gt; wrote:&lt;br /&gt;
&amp;gt; I&#039;m creating a very simple web application, and I want to use python. My first guess was that mod_python&lt;br /&gt;
would provide the easiest entry point. Boy, was I wrong. All the mod_python tutorials spend 80% of their&lt;br /&gt;
time extolling the virtues of mod_python over CGI, but they are quite lean on specific examples. It&#039;s quite&lt;br /&gt;
disappointing. A natural progression then leads me to mod_wsgi, and since that has equally poor&lt;br /&gt;
documentation, to Django. However, Django is overkill for my app (I don&#039;t even have a database).&lt;br /&gt;
&lt;br /&gt;
For something as simple as you have described, and to run on an&lt;br /&gt;
embedded platform, I would probably stay away from frameworks designed&lt;br /&gt;
to run on full hardware, and go with something more minimalistic.&lt;br /&gt;
&lt;br /&gt;
Take a look at CherryPy [1] or web.py [2].&lt;br /&gt;
&lt;br /&gt;
[1] http://www.cherrypy.org/&lt;br /&gt;
[2] http://webpy.org/&lt;br /&gt;
&lt;br /&gt;
Roberto Mello&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
See also [[web.py]]&lt;br /&gt;
&lt;br /&gt;
See also [[CherryPy]]&lt;br /&gt;
&lt;br /&gt;
See also [[Django]]&lt;br /&gt;
&lt;br /&gt;
=== Apache CGI ===&lt;br /&gt;
&lt;br /&gt;
See [[CGI]]&lt;br /&gt;
&lt;br /&gt;
Great tutorial: https://www.tutorialspoint.com/python/python_cgi_programming.htm&lt;br /&gt;
&lt;br /&gt;
My favorite option, make all .cgi files executable: (or .py)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 DirectoryIndex index.html index.php index.py&lt;br /&gt;
 &amp;lt;Location /&amp;gt;&lt;br /&gt;
   # AddHandler cgi-script .cgi&lt;br /&gt;
   AddHandler cgi-script .py&lt;br /&gt;
   Options +ExecCGI &lt;br /&gt;
 &amp;lt;/Location&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To enable on Ubuntu:&lt;br /&gt;
 sudo a2enmod cgi&lt;br /&gt;
 service apache2 restart&lt;br /&gt;
&lt;br /&gt;
Directory index:&lt;br /&gt;
 DirectoryIndex index.py&lt;br /&gt;
&lt;br /&gt;
Or if you really want to go crazy, this will try to run *every* file: [http://blog.kapsobor.de/archives/2006/09/05/apache_addhandler_multiple_extensions/]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    # this has problems with / directory being run as a script, instead of index too!&lt;br /&gt;
    #&amp;lt;Location /&amp;gt;&lt;br /&gt;
    #    SetHandler cgi-script&lt;br /&gt;
    #    Options +ExecCGI&lt;br /&gt;
    #&amp;lt;/Location&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;Files ~ &amp;quot;.&amp;quot;&amp;gt;&lt;br /&gt;
        SetHandler cgi-script&lt;br /&gt;
        Options +ExecCGI&lt;br /&gt;
    &amp;lt;/Files&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    &amp;lt;Files ~ &amp;quot;^.[a-zA-Z]*$&amp;quot;&amp;gt;&lt;br /&gt;
        SetHandler cgi-script&lt;br /&gt;
        Options +ExecCGI&lt;br /&gt;
    &amp;lt;/Files&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Or just have index file:&lt;br /&gt;
    &amp;lt;Files &amp;quot;index&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: Place within a &amp;lt;VirtualHost&amp;gt; section if needed.&lt;br /&gt;
&lt;br /&gt;
Note: Make sure to &#039;chmod +x&#039; the files.&lt;br /&gt;
&lt;br /&gt;
Start all HTML output with:&lt;br /&gt;
 print &amp;quot;Content-Type: text/html\n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If you want just text output:&lt;br /&gt;
 print &amp;quot;Content-Type: text/plain\n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
GET (from Environment):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
print &amp;quot;&amp;amp;lt;pre&amp;gt;&amp;quot;&lt;br /&gt;
for env in os.environ:&lt;br /&gt;
    print &amp;quot;%s = %s&amp;quot; % (env, os.environ[env])&lt;br /&gt;
print &amp;quot;&amp;amp;lt;/pre&amp;gt;&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# sample for: http://oeey.com/py/test.py/test?var1=ken&amp;amp;var2=barbie&lt;br /&gt;
&lt;br /&gt;
REQUEST_URI = /py/index.py/test?var1=ken&amp;amp;var2=barbie&lt;br /&gt;
QUERY_STRING = var1=ken&amp;amp;var2=barbie&lt;br /&gt;
PATH_INFO = /test&lt;br /&gt;
REQUEST_METHOD = GET&lt;br /&gt;
&lt;br /&gt;
SCRIPT_NAME = /py/test.py&lt;br /&gt;
SERVER_NAME = oeey.com&lt;br /&gt;
REMOTE_ADDR = 216.51.42.66&lt;br /&gt;
SERVER_ADDR = 192.168.108.4&lt;br /&gt;
DOCUMENT_ROOT = /www/py&lt;br /&gt;
SCRIPT_FILENAME = /www/py/test.py&lt;br /&gt;
HTTP_HOST = cgi.oeey.com&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
POST (from stdin):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
post = sys.stdin.readline()&lt;br /&gt;
if post:&lt;br /&gt;
    print post&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CONTENT_TYPE = application/x-www-form-urlencoded&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
yin=one+two+three&amp;amp;yang=four+five+six&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
cgi helper class:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import cgi&lt;br /&gt;
&lt;br /&gt;
print &amp;quot;Content-Type: text/html\n\n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
form = cgi.FieldStorage()&lt;br /&gt;
&lt;br /&gt;
# field keys&lt;br /&gt;
print &amp;quot;fields keys: &amp;quot;, form.keys()  # list of field keys&lt;br /&gt;
&lt;br /&gt;
# fild values&lt;br /&gt;
if &amp;quot;name&amp;quot; in form:  # if form.has_key(&#039;name&#039;):&lt;br /&gt;
    print &amp;quot;field &#039;name&#039; is: &amp;quot;, form[&amp;quot;name&amp;quot;].value&lt;br /&gt;
    print &amp;quot;field &#039;name&#039; is: &amp;quot;, form.getvalue(&#039;name&#039;)&lt;br /&gt;
&lt;br /&gt;
# headers&lt;br /&gt;
print &amp;quot;dictionary of headers: &amp;quot;, form.headers&lt;br /&gt;
print form.type&lt;br /&gt;
print form.headers[&#039;content-type&#039;]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To prevent XSS escape the characters:&lt;br /&gt;
  print cgi.escape(form.getvalue(&#039;name&#039;))&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import cgi&lt;br /&gt;
&lt;br /&gt;
print &amp;quot;Content-Type: text/html\n\n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
form = cgi.FieldStorage()&lt;br /&gt;
if (form.has_key(&amp;quot;action&amp;quot;) and form.has_key(&amp;quot;name&amp;quot;) \&lt;br /&gt;
        and form.has_key(&amp;quot;age&amp;quot;)):&lt;br /&gt;
    if (form[&amp;quot;action&amp;quot;].value == &amp;quot;display&amp;quot;):&lt;br /&gt;
        print &amp;quot;%s = %s&amp;quot; % (form[&amp;quot;name&amp;quot;].value form[&amp;quot;age&amp;quot;].value)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: cgi helper class also does sessions and cookies.&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* CGI Tutorial | Web Python - http://webpython.codepoint.net/cgi_tutorial&lt;br /&gt;
* Python CGI: An Interactive Instruction - http://www.cs.virginia.edu/~lab2q/&lt;br /&gt;
&lt;br /&gt;
See also:&lt;br /&gt;
* Web Python - http://webpython.codepoint.net/&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
REST Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import os, re&lt;br /&gt;
def get_rest():&lt;br /&gt;
    if not &amp;quot;PATH_INFO&amp;quot; in os.environ:&lt;br /&gt;
        return ()&lt;br /&gt;
    # filter for garbage&lt;br /&gt;
    #print os.environ[&amp;quot;PATH_INFO&amp;quot;]&lt;br /&gt;
    path_info = re.findall(&#039;[/A-Za-z0-9_-]*&#039;, os.environ[&amp;quot;PATH_INFO&amp;quot;])&lt;br /&gt;
    if not path_info:&lt;br /&gt;
        return ()&lt;br /&gt;
    path_info = &#039;&#039;.join(path_info)&lt;br /&gt;
    # collapse empty paths&lt;br /&gt;
    paths = path_info.split(&#039;/&#039;)&lt;br /&gt;
    final_paths = []&lt;br /&gt;
    for path in paths:&lt;br /&gt;
        if path:&lt;br /&gt;
            final_paths.append(path)&lt;br /&gt;
    return tuple(final_paths)&lt;br /&gt;
rest = get_rest();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== mod_python ===&lt;br /&gt;
&lt;br /&gt;
AVOID! AVOID! AVOID! - if you want this simple, just use CGI!&lt;br /&gt;
&lt;br /&gt;
See [[Apache mod_python]]&lt;br /&gt;
&lt;br /&gt;
mod_python - http://docs.python.org/howto/webservers.html#mod-python&lt;br /&gt;
&lt;br /&gt;
Install:&lt;br /&gt;
 yum install mod_python&lt;br /&gt;
&lt;br /&gt;
Config:&lt;br /&gt;
 /etc/httpd/conf.d/python.conf&lt;br /&gt;
&lt;br /&gt;
Simple:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;quot;People coming from PHP often find it hard to grasp how to use Python in the web. Their first thought is mostly mod_python, because they think that this is the equivalent to mod_php. Actually, there are many differences. What mod_python does is embed the interpreter into the Apache process, thus speeding up requests by not having to start a Python interpreter for each request. On the other hand, it is not “Python intermixed with HTML” in the way that PHP is often intermixed with HTML. The Python equivalent of that is a template engine. mod_python itself is much more powerful and provides more access to Apache internals. It can emulate CGI, work in a “Python Server Pages” mode (similar to JSP) which is “HTML intermingled with Python”, and it has a “Publisher” which designates one file to accept all requests and decide what to do with them.&lt;br /&gt;
&lt;br /&gt;
:mod_python does have some problems. Unlike the PHP interpreter, the Python interpreter uses caching when executing files, so changes to a file will require the web server to be restarted. Another problem is the basic concept – Apache starts child processes to handle the requests, and unfortunately every child process needs to load the whole Python interpreter even if it does not use it. This makes the whole web server slower. Another problem is that, because mod_python is linked against a specific version of libpython, it is not possible to switch from an older version to a newer (e.g. 2.4 to 2.5) without recompiling mod_python. mod_python is also bound to the Apache web server, so programs written for mod_python cannot easily run on other web servers.&lt;br /&gt;
&lt;br /&gt;
:These are the reasons why mod_python should be avoided when writing new programs. In some circumstances it still might be a good idea to use mod_python for deployment, but WSGI makes it possible to run WSGI programs under mod_python as well.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== WSGI ===&lt;br /&gt;
&lt;br /&gt;
WSGI - http://docs.python.org/howto/webservers.html#mod-wsgi&lt;br /&gt;
&lt;br /&gt;
: &amp;quot;The Web Server Gateway Interface, or WSGI for short, is defined in PEP 333 and is currently the best way to do Python web programming. While it is great for programmers writing frameworks, a normal web developer does not need to get in direct contact with it. When choosing a framework for web development it is a good idea to choose one which supports WSGI.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
See [[mod_wsgi]]&lt;br /&gt;
&lt;br /&gt;
=== Django ===&lt;br /&gt;
&lt;br /&gt;
See [[Django]]&lt;br /&gt;
&lt;br /&gt;
=== CherryPy ===&lt;br /&gt;
&lt;br /&gt;
See [[CherryPy]]&lt;br /&gt;
&lt;br /&gt;
=== web.py ===&lt;br /&gt;
&lt;br /&gt;
web.py: makes web apps&lt;br /&gt;
&lt;br /&gt;
Think about the ideal way to write a web app. Write the code to make it happen.&lt;br /&gt;
&lt;br /&gt;
web.py : Python Package Index - http://pypi.python.org/pypi/web.py&lt;br /&gt;
&lt;br /&gt;
Home Page: http://webpy.org/&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Django lets you write web apps in Django. TurboGears lets you write web apps in TurboGears. Web.py lets you write web apps in Python.&amp;quot;&lt;br /&gt;
:—  Adam Atlas&lt;br /&gt;
&lt;br /&gt;
NOTE: Can modify source code without having to restart app!  :-)&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
PIP Install:&lt;br /&gt;
 pip install web.py&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
Hello World: [http://webpy.org/]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import web&lt;br /&gt;
        &lt;br /&gt;
urls = (&lt;br /&gt;
    &#039;/(.*)&#039;, &#039;hello&#039;&lt;br /&gt;
)&lt;br /&gt;
app = web.application(urls, globals())&lt;br /&gt;
&lt;br /&gt;
class hello:        &lt;br /&gt;
    def GET(self, name):&lt;br /&gt;
        if not name: &lt;br /&gt;
            name = &#039;World&#039;&lt;br /&gt;
        return &#039;Hello, &#039; + name + &#039;!&#039;&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
    app.run()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: app.py can be renamed.&lt;br /&gt;
&lt;br /&gt;
Running:&lt;br /&gt;
 python app.py&lt;br /&gt;
&lt;br /&gt;
Note: You can add an IP address/port after the &amp;quot;app.py&amp;quot; bit to control where web.py launches the server. You can also tell it to run a fastcgi or scgi server.&lt;br /&gt;
 python app.py 1234&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
Templates&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# templates/hello.html&lt;br /&gt;
$def with (name)&lt;br /&gt;
&lt;br /&gt;
$if name:&lt;br /&gt;
    I just wanted to say &amp;lt;em&amp;gt;hello&amp;lt;/em&amp;gt; to $name.&lt;br /&gt;
$else:&lt;br /&gt;
    &amp;lt;em&amp;gt;Hello&amp;lt;/em&amp;gt;, world!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 app = ...&lt;br /&gt;
 render = web.template.render(&#039;templates/&#039;)&lt;br /&gt;
&lt;br /&gt;
index.GET:&lt;br /&gt;
 name = &#039;Bob&#039;    &lt;br /&gt;
 return render.hello(name)  # render.[TEMPLATE_NAME](vars)&lt;br /&gt;
&lt;br /&gt;
get variable: (/?name=Joe)&lt;br /&gt;
 i = web.input(name=None)&lt;br /&gt;
 return render.hello(i.name)&lt;br /&gt;
&lt;br /&gt;
variable in url:&lt;br /&gt;
 urls = (&#039;/(.*)&#039;, &#039;hello&#039;)&lt;br /&gt;
&lt;br /&gt;
 class index:&lt;br /&gt;
     def GET(self, name):&lt;br /&gt;
        return render.hello(name)&lt;br /&gt;
&lt;br /&gt;
 # visit: /Joe&lt;br /&gt;
&lt;br /&gt;
multiple variables in url:&lt;br /&gt;
 urls = (&#039;/(.*)/(.*)&#039;, &#039;hello&#039;)&lt;br /&gt;
&lt;br /&gt;
  class hello:&lt;br /&gt;
    def GET(self, fname, lname):&lt;br /&gt;
        return render.hello(fname, lname)&lt;br /&gt;
&lt;br /&gt;
 # visit: /Joe/Smith&lt;br /&gt;
&lt;br /&gt;
=== lpthw.web ===&lt;br /&gt;
&lt;br /&gt;
lpthw.web: a fork of web.py for Learn Python The Hard Way&lt;br /&gt;
&lt;br /&gt;
Locks web.py at a specific version and removes some magic. Thanks to Aaron Swartz for making it originally.&lt;br /&gt;
&lt;br /&gt;
lpthw.web: a fork of web.py for Learn Python The Hard Way - http://pypi.python.org/pypi/lpthw.web&lt;br /&gt;
&lt;br /&gt;
Home Page: http://learnpythonthehardway.org/&lt;br /&gt;
&lt;br /&gt;
This conflicts with web.py, so only install one.&lt;br /&gt;
&lt;br /&gt;
=== web ===&lt;br /&gt;
&lt;br /&gt;
web - Web modules for CGI and WSGI web programming&lt;br /&gt;
&lt;br /&gt;
web : Python Package Index - http://pypi.python.org/pypi/web&lt;br /&gt;
&lt;br /&gt;
Warning: This is an alpha release for those who are interested in&lt;br /&gt;
    checking progress. No documentation and not for production use.&lt;br /&gt;
&lt;br /&gt;
Auth, session, mail, form and templating tools for writing CGI scripts or WSGI web applications.&lt;br /&gt;
&lt;br /&gt;
This version incompatible with previous versions becuase large portions of the code have been refactored into separate components.&lt;br /&gt;
&lt;br /&gt;
== Issues ==&lt;br /&gt;
&lt;br /&gt;
=== Hide DeprecationWarning ===&lt;br /&gt;
&lt;br /&gt;
==== Import DeprecationWarning ====&lt;br /&gt;
&lt;br /&gt;
Error:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/opt/xmpppy-0.4.1/xmpp/auth.py:24: DeprecationWarning: the sha module is deprecated; use the hashlib module instead&lt;br /&gt;
  import sha,base64,random,dispatcher,re&lt;br /&gt;
/opt/xmpppy-0.4.1/xmpp/auth.py:26: DeprecationWarning: the md5 module is deprecated; use hashlib instead&lt;br /&gt;
  import md5&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hide deprecation warnings with code: [http://stackoverflow.com/questions/879173/how-to-ignore-deprecation-warnings-in-python]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import warnings&lt;br /&gt;
&lt;br /&gt;
with warnings.catch_warnings():&lt;br /&gt;
    warnings.filterwarnings(&amp;quot;ignore&amp;quot;,category=DeprecationWarning)&lt;br /&gt;
    import md5, sha&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hide with header:&lt;br /&gt;
 #!/usr/bin/env python -W ignore::DeprecationWarning&lt;br /&gt;
&lt;br /&gt;
Hide from command line:&lt;br /&gt;
 python -W ignore::DeprecationWarning script.py&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* How to ignore deprecation warnings in Python - Stack Overflow - http://stackoverflow.com/questions/879173/how-to-ignore-deprecation-warnings-in-python&lt;br /&gt;
&lt;br /&gt;
==== Funciton DeprecationWarning ====&lt;br /&gt;
&lt;br /&gt;
Error:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/opt/xmpppy-0.4.1/xmpp/transports.py:307: DeprecationWarning: socket.ssl() is deprecated.  Use ssl.wrap_socket() instead.&lt;br /&gt;
  tcpsock._sslObj    = socket.ssl(tcpsock._sock, None, None)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hide with header:&lt;br /&gt;
 #!/usr/bin/env python -W ignore::DeprecationWarning&lt;br /&gt;
&lt;br /&gt;
Hide from command line:&lt;br /&gt;
 python -W ignore::DeprecationWarning script.py&lt;br /&gt;
&lt;br /&gt;
==== Ubuntu 24 pip packages ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
error: externally-managed-environment&lt;br /&gt;
&lt;br /&gt;
× This environment is externally managed&lt;br /&gt;
╰─&amp;gt; To install Python packages system-wide, try apt install&lt;br /&gt;
    python3-xyz, where xyz is the package you are trying to&lt;br /&gt;
    install.&lt;br /&gt;
&lt;br /&gt;
    If you wish to install a non-Debian-packaged Python package,&lt;br /&gt;
    create a virtual environment using python3 -m venv path/to/venv.&lt;br /&gt;
    Then use path/to/venv/bin/python and path/to/venv/bin/pip. Make&lt;br /&gt;
    sure you have python3-full installed.&lt;br /&gt;
&lt;br /&gt;
    If you wish to install a non-Debian packaged Python application,&lt;br /&gt;
    it may be easiest to use pipx install xyz, which will manage a&lt;br /&gt;
    virtual environment for you. Make sure you have pipx installed.&lt;br /&gt;
&lt;br /&gt;
    See /usr/share/doc/python3.12/README.venv for more information.&lt;br /&gt;
&lt;br /&gt;
note: If you believe this is a mistake, please contact your Python installation or OS distribution provider. You can override this, at the risk of breaking your Python installation or OS, by passing --break-system-packages.&lt;br /&gt;
hint: See PEP 668 for the detailed specification.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== keywords ==&lt;br /&gt;
&lt;br /&gt;
[[Category:Programming]]&lt;br /&gt;
[[Category:Python]]&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=Roll20&amp;diff=9859</id>
		<title>Roll20</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=Roll20&amp;diff=9859"/>
		<updated>2026-04-24T01:53:02Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: /* Call of Cthulhu Initative */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Sub Pages Table of Contents ==&lt;br /&gt;
&lt;br /&gt;
{{Special:PrefixIndex/{{PAGENAME}}/}}&lt;br /&gt;
&lt;br /&gt;
== Roll 20.net ==&lt;br /&gt;
&lt;br /&gt;
== Moving Tokens ==&lt;br /&gt;
&lt;br /&gt;
Manipulating Graphics - Roll20 Wiki - https://wiki.roll20.net/Manipulating_Graphics&lt;br /&gt;
&lt;br /&gt;
Alt key for fine movements&lt;br /&gt;
&lt;br /&gt;
Tapping ←, →, ↑ or ↓ arrow keys will move a selected token one grid unit in the specified direction&lt;br /&gt;
&lt;br /&gt;
X key for token past movement&lt;br /&gt;
&lt;br /&gt;
Q key for waypoint movement&lt;br /&gt;
&lt;br /&gt;
E and mouse wheel to rotate&lt;br /&gt;
&lt;br /&gt;
=== Rotation ===&lt;br /&gt;
&lt;br /&gt;
When token selected, blue handle will stick out the front of the token.&lt;br /&gt;
&lt;br /&gt;
Can also hold E and mouse wheel to rotate.&lt;br /&gt;
&lt;br /&gt;
Can also hold Alt + E and mouse will to rotate more accurately.&lt;br /&gt;
&lt;br /&gt;
== Roll Dice ==&lt;br /&gt;
&lt;br /&gt;
 /roll 1d20+10 vs AC&lt;br /&gt;
 /roll 1d4+9 Damage&lt;br /&gt;
 /roll 5+3&lt;br /&gt;
&lt;br /&gt;
Ref: https://wiki.roll20.net/Dice_Reference&lt;br /&gt;
&lt;br /&gt;
Ref: https://roll20.zendesk.com/hc/en-us/articles/360037773133-Dice-Reference&lt;br /&gt;
&lt;br /&gt;
=== Inline Roll ===&lt;br /&gt;
&lt;br /&gt;
 I like the number &amp;amp;#91;[1d100]] or [[5+3]]&lt;br /&gt;
&lt;br /&gt;
=== Drop/Keep ===&lt;br /&gt;
&lt;br /&gt;
Advantage/Disadvantage&lt;br /&gt;
 /r 4d20k1  # roll 4d20 keep highest&lt;br /&gt;
 /r 4d20kh1  # roll 4d20 keep highest (ditto)&lt;br /&gt;
 /r 4d20kl1  # roll 4d20 keep lowest&lt;br /&gt;
 /r 4d20dl   # drop lowest&lt;br /&gt;
 /r 4d20dl   # drop highest&lt;br /&gt;
&lt;br /&gt;
== Chat ==&lt;br /&gt;
&lt;br /&gt;
Ref: https://wiki.roll20.net/Text_Chat&lt;br /&gt;
&lt;br /&gt;
=== Whisper ===&lt;br /&gt;
&lt;br /&gt;
 /w [user] [msg]&lt;br /&gt;
&lt;br /&gt;
=== Whisper to GM ===&lt;br /&gt;
&lt;br /&gt;
 /w gm [msg]&lt;br /&gt;
&lt;br /&gt;
=== GM Roll ===&lt;br /&gt;
&lt;br /&gt;
 /gmroll 2d6+3&lt;br /&gt;
&lt;br /&gt;
=== Emote ===&lt;br /&gt;
&lt;br /&gt;
 /em ...&lt;br /&gt;
 /me rams his dagger home&lt;br /&gt;
&lt;br /&gt;
https://i.imgur.com/Re3GCjh.png&lt;br /&gt;
&lt;br /&gt;
=== Out of Character ===&lt;br /&gt;
&lt;br /&gt;
OOC entries always appear as the player (e.g. &amp;quot;Riley D.&amp;quot;) rather than the Character you have selected in the &amp;quot;Speaking As&amp;quot; drop-down (e.g. &amp;quot;Orrbain&amp;quot;). &lt;br /&gt;
 /ooc I could really use another Red Bull right now.&lt;br /&gt;
&lt;br /&gt;
=== Talk To Myself ===&lt;br /&gt;
&lt;br /&gt;
 /talktomyself or /talktomyself on&lt;br /&gt;
&lt;br /&gt;
 /talktomyself (again) or /talktomyself off&lt;br /&gt;
&lt;br /&gt;
== Chat Markup ==&lt;br /&gt;
&lt;br /&gt;
Text Chat - Roll20 Wiki&lt;br /&gt;
https://wiki.roll20.net/Text_Chat&lt;br /&gt;
&lt;br /&gt;
=== Bold ===&lt;br /&gt;
&lt;br /&gt;
 ** bold **&lt;br /&gt;
&lt;br /&gt;
=== Italicize ===&lt;br /&gt;
&lt;br /&gt;
 * italicize*&lt;br /&gt;
&lt;br /&gt;
=== Link or Image ===&lt;br /&gt;
&lt;br /&gt;
 [link or image](url)&lt;br /&gt;
 [x](img_url)&lt;br /&gt;
&lt;br /&gt;
 *I* **love** [Roll20](https://app.roll20.net)&lt;br /&gt;
&lt;br /&gt;
=== Inline Roll ===&lt;br /&gt;
&lt;br /&gt;
 Inline roll [[1d20+5]]&lt;br /&gt;
&lt;br /&gt;
=== Colored Text ===&lt;br /&gt;
&lt;br /&gt;
NOTE: Doesn&#039;t appear to work...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 &amp;lt;inline style=&amp;quot;color: rgb( 31 , 73 , 125 )&amp;quot;&amp;gt;blue&amp;lt;/inline&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 &amp;lt;span style=&amp;quot;background: yellow&amp;quot;&amp;gt;OOC: What is this?&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Community Forums: Colored text | Roll20: Online virtual tabletop&lt;br /&gt;
https://app.roll20.net/forum/post/2069398/colored-text&lt;br /&gt;
&lt;br /&gt;
=== Escape Text ===&lt;br /&gt;
&lt;br /&gt;
Start line with back tick `&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
`&amp;amp;{template:default} {{attack=[[1d20]]}}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Useful for sharing Macros&lt;br /&gt;
&lt;br /&gt;
=== GM Descriptions ===&lt;br /&gt;
&lt;br /&gt;
 /desc  (description not spoken by anyone: center aligned, bold, italicized, black font, light grey highlight)&lt;br /&gt;
 /as&lt;br /&gt;
 /emas&lt;br /&gt;
&lt;br /&gt;
 /gmroll in secret&lt;br /&gt;
 /gr&lt;br /&gt;
&lt;br /&gt;
=== Talk to Myself ===&lt;br /&gt;
&lt;br /&gt;
 /talktomyself on&lt;br /&gt;
 /talktomyself off&lt;br /&gt;
&lt;br /&gt;
=== Images ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[Gold the Great](https://s3.amazonaws.com/files.d20.io/images/1725103/oXeN9hS_kB395ps0zsHD9Q/med.gif?1377575057&amp;amp;size=200x200#.gif)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
https://i.imgur.com/UKWY24U.png&lt;br /&gt;
&lt;br /&gt;
Ref: https://app.roll20.net/forum/post/1793704/how-to-show-pictures-slash-images-to-players&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
Image by choice: (will ask for caption, and url, but provides defaults)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[?{Caption|no caption}](?{URL|http://www.d20pfsrd.com/_/rsrc/1420094759946/config/customLogo.gif?revision=40}#.png)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Macros ==&lt;br /&gt;
&lt;br /&gt;
Anything you can command.  Name the macro, and you can then call it with #[MACRO_NAME]&lt;br /&gt;
&lt;br /&gt;
(Nesting Macros) Macros can also call other macros with the #[MACRO_NAME]&lt;br /&gt;
&lt;br /&gt;
Use selected token:  (user bar1 value&lt;br /&gt;
 /r 1d20 + @{selected|bar1}&lt;br /&gt;
&lt;br /&gt;
 /r 1d20 + @{selected|Intelligence}&lt;br /&gt;
&lt;br /&gt;
 /r 1d20 + @{selected|token_name} fires his gun!  # use selected name&lt;br /&gt;
 /r 1d20 + @{selected|character_name} fires his gun!  # use selected name&lt;br /&gt;
&lt;br /&gt;
ref: https://wiki.roll20.net/Macros&lt;br /&gt;
&lt;br /&gt;
=== Roll Query ===&lt;br /&gt;
&lt;br /&gt;
 ?{Prompt Message}&lt;br /&gt;
&lt;br /&gt;
 //Example:&lt;br /&gt;
 /roll ?{Number of Dice}d20&lt;br /&gt;
&lt;br /&gt;
 //You can also include a default value:  (1 is default)&lt;br /&gt;
 /roll ?{Number of Dice|1}d20&lt;br /&gt;
&lt;br /&gt;
 ?{Which macro?|Attack,#use-sword |Defend,#use-shield }&lt;br /&gt;
&lt;br /&gt;
ref: https://wiki.roll20.net/Dice_Reference#Roll_Queries&lt;br /&gt;
&lt;br /&gt;
=== Choice ===&lt;br /&gt;
&lt;br /&gt;
 ?{Which |Charm, #Charm |Fear, #Fear |}&lt;br /&gt;
&lt;br /&gt;
Ref: https://app.roll20.net/forum/post/5220046/macro-with-choices&lt;br /&gt;
&lt;br /&gt;
=== Share Macros ===&lt;br /&gt;
&lt;br /&gt;
There is a &amp;quot;Visible To&amp;quot; setting to share Macros with players.  (Have to scroll down in the Macro edit).&lt;br /&gt;
&lt;br /&gt;
=== Calculator Macro ===&lt;br /&gt;
&lt;br /&gt;
Popup to do some calculations.  Only slightly cooler than just typing them in the chat window directly.&lt;br /&gt;
 **=** [[?{Calculator}}]]&lt;br /&gt;
&lt;br /&gt;
note: the double asterisks simply make the = bold. The only Part you really need is in the brackets.&lt;br /&gt;
&lt;br /&gt;
ref: [https://wiki.roll20.net/Useful_Macros#D20_Based_Systems]&lt;br /&gt;
&lt;br /&gt;
=== True False Macro ===&lt;br /&gt;
&lt;br /&gt;
On a character sheet,&lt;br /&gt;
&lt;br /&gt;
Create an ability:&lt;br /&gt;
 [Do I Like It?](~selected|bool[[ [[1d2]] ]])&lt;br /&gt;
&lt;br /&gt;
Create a &amp;quot;bool1&amp;quot; with &amp;quot;True&amp;quot; and a &amp;quot;bool2&amp;quot; with &amp;quot;False&amp;quot; ability.&lt;br /&gt;
&lt;br /&gt;
Ref: [https://app.roll20.net/forum/post/3346272/5e-ogl-use-boolean-value-for-text]&lt;br /&gt;
&lt;br /&gt;
== Templates ==&lt;br /&gt;
&lt;br /&gt;
=== Default Template ===&lt;br /&gt;
&lt;br /&gt;
Works on any character sheet&lt;br /&gt;
&lt;br /&gt;
https://i.imgur.com/814INLA.png&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;amp;{template:default} {{name=Fey Presence}} {{Charm = [Roll20 Logo](gif)}} {{Effect= A charmed creature can’t Attack the charmer or target&lt;br /&gt;
the charmer with harmful Abilities or magical effects. The charmer has advantage on any ability check to interact socially with the creature.}} &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 1d20 ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;amp;{template:default} {{name=Rolls a 1d20  [[1d20]]}}&lt;br /&gt;
&lt;br /&gt;
&amp;amp;{template:default} {{name=Player Name}} {{Rolls a 1d20=[[1d20]]}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Roll Some Dice ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;amp;{template:default} {{name=Roll Some Dice}} {{1d4 = [[1d4]]}} {{1d6 = [[1d6]]}} {{1d10 = [[1d10]]}} {{1d12 = [[1d12]]}} {{1d20 = [[1d20]]}} {{1d100 = [[1d100]]}}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== DnD Templates ==&lt;br /&gt;
&lt;br /&gt;
WARNING: TEMPLATES ARE CHARACTER SHEET SPECIFIC!&lt;br /&gt;
&lt;br /&gt;
=== Roll Stats ===&lt;br /&gt;
&lt;br /&gt;
https://i.imgur.com/lVJujtQ.png&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;amp;{template:default} {{name= Ability Scores}} {{[[4d6kh3]][[4d6kh3]][[4d6kh3]][[4d6kh3]][[4d6kh3]][[4d6kh3]]}}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Other ===&lt;br /&gt;
&lt;br /&gt;
https://i.imgur.com/lVJujtQ.png&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;amp;{template:default} {{name= Ability Scores}} {{[[4d6kh3]][[4d6kh3]][[4d6kh3]][[4d6kh3]][[4d6kh3]][[4d6kh3]]}}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://i.imgur.com/LlHtoyG.png&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;amp;{template:desc} {{desc=desc}}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://i.imgur.com/lypdXox.png&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;amp;{template:simple} {{rname=rname}} {{mod=mod}} {{r1=r1}} {{always=1}} {{r2=r2}} {{charname=charname}}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://wiki.roll20.net/images/b/b8/D%26D_5E_OGL_Spell_Template.jpg&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;amp;{template:spell} {{level=school level}} {{name=name}} {{castingtime=castingtime}} {{range=range}} {{target=target}} {{v=1}} {{s=1}} {{m=1}} {{material=material}} {{duration=duration}} {{description=description}} {{athigherlevels=athigherlevels}} {{ritual=1}} {{concentration=1}} {{charname=charname}}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://wiki.roll20.net/images/3/3e/D%26D_5E_OGL_NpcAction_Template.jpg&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;amp;{template:npcaction} {{attack=1}} {{damage=1}} {{dmg1flag=1}} {{dmg2flag=1}} {{name=name}} {{rname=rname}} {{r1=r1}} {{always=1}} {{r2=r2}} {{dmg1=dmg1}} {{dmg1type=dmg1type}} {{crit1=crit1}} {{dmg2=dmg2}} {{dmg2type=dmg2type}} {{crit2=crit2}} {{description=description}}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://wiki.roll20.net/images/9/96/D%26D_5E_OGL_NpcAtk_Template.jpg&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;amp;{template:npcatk} {{attack=1}} {{name=name}} {{rname=rname}} {{rnamec=rnamec}} {{r1=r1}} {{always=1}} {{r2=r2}} {{description=description}}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For more templates: https://wiki.roll20.net/D%26D_5e_by_Roll20_Roll_Templates&lt;br /&gt;
&lt;br /&gt;
==== My Template Creations ====&lt;br /&gt;
&lt;br /&gt;
Character Initiative:&amp;lt;br&amp;gt;&lt;br /&gt;
https://i.imgur.com/dR17tyh.png&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;amp;{template:simple} {{rname=INITIATIVE}} {{mod= @{selected|initiative_bonus} }} {{r1= [[ 1d20 + @{selected|initiative_bonus} &amp;amp;{tracker} ]] }} {{normal=Hello World}}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
NPC Initiative:&amp;lt;br&amp;gt;&lt;br /&gt;
https://i.imgur.com/nv1wZ5g.png&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;amp;{template:npcaction} {{rname=Initiative}} {{description=Initiative: [[ 1d20 + @{selected|initiative_bonus} &amp;amp;{tracker} ]] }}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== CoC Templates ==&lt;br /&gt;
&lt;br /&gt;
=== Call of Cthulhu Initative ===&lt;br /&gt;
&lt;br /&gt;
Base character sheet:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;amp;{template:callofcthulhu}{{name=@{Clarence|character_name}}}{{title=Initiative}}{{roll=[[@{selected|dexterity} &amp;amp;{tracker}]]}}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Simple:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
@{selected|token_name} has [[ @{selected|dexterity} &amp;amp;{tracker} ]] for initiative.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With readied weapon:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
@{selected|token_name} has [[ 50+@{selected|dexterity} &amp;amp;{tracker} ]] for initiative.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Old one I used:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/me rolls [[ @{selected|dexterity_mod}+1d20 &amp;amp;{tracker} ]] for initiative.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Call of Cthulhu Sheet ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;amp;{template:callofcthulhu} {{name=Some test...}}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Roll Stats ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;amp;{template:default} {{name=ATTRS}} {{STR=[[3d6*5]]}} {{CON=[[3d6*5]]}} {{POW=[[3d6*5]]}} {{DEX=[[3d6*5]]}} {{APP=[[3d6*5]]}} {{SIZ=[[(2d6+6)*5]]}} {{INT=[[(2d6+6)*5]]}} {{EDU=[[(2d6+6)*5]]}} {{LCK=[[3d6*5]]}}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ref: [https://wiki.roll20.net/index.php?title=Macros/Call_of_Cthulhu_Examples]&lt;br /&gt;
&lt;br /&gt;
=== Roll 1d100 and 1d10 ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;amp;{template:default} {{name=Roll 1d10}} {{Result = [[1d10]]}}&lt;br /&gt;
&lt;br /&gt;
&amp;amp;{template:default} {{name=Roll 1d100}} {{Result = [[1d100]]}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;amp;{template:default} {{name=Roll 1d4: ?{For|}}} {{Result = [[1d4]]}}&lt;br /&gt;
&lt;br /&gt;
&amp;amp;{template:default} {{name=Roll 1d6: ?{For|}}} {{Result = [[1d6]]}}&lt;br /&gt;
&lt;br /&gt;
&amp;amp;{template:default} {{name=Roll 1d10: ?{For|}}} {{Result = [[1d10]]}}&lt;br /&gt;
&lt;br /&gt;
&amp;amp;{template:default} {{name=Roll 1d12: ?{For|}}} {{Result = [[1d12]]}}&lt;br /&gt;
&lt;br /&gt;
&amp;amp;{template:default} {{name=Roll 1d20: ?{For|}}} {{Result = [[1d20]]}}&lt;br /&gt;
&lt;br /&gt;
&amp;amp;{template:default} {{name=Roll 1d100: ?{For|}}} {{Result = [[1d100]]}}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Hard vs Extreme ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/roll 1d100 vs [[@{selected|accounting}]]/[[floor(@{selected|accounting}/2)]]/[[floor(@{selected|accounting}/5)]]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
https://i.imgur.com/lZhwomG.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/roll 1d100 vs [[@{str}]]/[[floor(@{str}/2)]]/[[floor(@{str}/5)]]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== General Dice Roller ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;amp;{template:callofcthulhu} {{roll_type=General Dice Roller}} {{title=?{Source|Something Strange}}} {{roll=[[?{Dice to Roll|2d6/1d3/3d10}]]}} {{text=Notes: ?{Notes|Put notes here for future reference.}}}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
https://i.imgur.com/28SfIDu.png&lt;br /&gt;
&lt;br /&gt;
Note: can skipp &amp;quot;roll_type&amp;quot;, but keep title.&lt;br /&gt;
&lt;br /&gt;
=== Firing Damage ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;amp;{template:callofcthulhu} {{roll_type=&amp;quot;Little&amp;quot; Jimmy Foster}} {{title=Wild Tommy Gun Fire}} {{roll=[[1d6]] Damage}} {{text=For more information, see ***[S&amp;amp;#8288;tarting The Action](http://journal.roll20.net/handout/-LyjjADrc7rY7Swfqdz_)***.}}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
https://i.imgur.com/1W1CDas.png&lt;br /&gt;
&lt;br /&gt;
=== Sanity Rewards ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;amp;{template:callofcthulhu} {{roll_type=Conclusion}} {{title=Sanity Rewards}} {{roll=[[?{Stopped Turner without killing him|Yes,2d6|No,0|Killed Turner,-1d6}+?{Stole or secured&lt;br /&gt;
the trumpet|Yes,1|No,0}+?{Turned in Boss Bonato|Yes,1d3|No,0}]] Sanity Points}} {{text=For more information, see ***[C&amp;amp;#8288;onclusion](http://journal.roll20.net/handout/-Lyji5w0exosX92Auwdb)***.}}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
https://i.imgur.com/k78uzNM.png&lt;br /&gt;
&lt;br /&gt;
===  Percentile Dice Roller ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;amp;{template:callofcthulhu} {{roll_type=Percentile Dice Roller}} {{title=?{Source|Something Strange}}} {{roll=[[1d100]] vs **?{Comparison|0}**}} {{text=Notes: ?{Notes|Put notes here for future reference.}}}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: can skipp &amp;quot;roll_type&amp;quot;, but keep title.&lt;br /&gt;
&lt;br /&gt;
https://i.imgur.com/EUw9cbY.png&lt;br /&gt;
&lt;br /&gt;
=== Armor ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;amp;{template:callofcthulhu} {{name=@{character_name}}} {{title=Armor + Shields + Death Bringer Cloak Absorbs}} {{roll=[[1d8+1d6+1d4]]}}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Delta Green Templates ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;amp;{template:rolls} {{header=bob}} {{subheader=50}} {{dice=[[1d2]]}}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;amp;{template:rolls} {{header=bob}} {{desc=hello}}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
https://github.com/Roll20/roll20-character-sheets/blob/master/Delta%20Green%202/src/pug/rolltemplate.pug&lt;br /&gt;
&lt;br /&gt;
== Script Examples ==&lt;br /&gt;
&lt;br /&gt;
=== Ray of Frost damage ===&lt;br /&gt;
&lt;br /&gt;
Ray of Frost damage 1d8 per 1st, 5th, 11th, 17th&lt;br /&gt;
 [[round((@{level} + 1) / 6 + 0.5)]]d8&lt;br /&gt;
&lt;br /&gt;
=== Magic Missile Damage ===&lt;br /&gt;
&lt;br /&gt;
 ?{MissleCount|3}d4+?{MissleCount}&lt;br /&gt;
&lt;br /&gt;
== Import DnD Beyond Characters ==&lt;br /&gt;
&lt;br /&gt;
 https://github.com/RobinKuiper/Roll20APIScripts&lt;br /&gt;
&lt;br /&gt;
Raw source of script:&lt;br /&gt;
 https://raw.githubusercontent.com/RobinKuiper/Roll20APIScripts/master/BeyondImporter_5eOGL/BeyondImporter.js&lt;br /&gt;
&lt;br /&gt;
DnD Beyond character add /json, copy and paste into chat:&lt;br /&gt;
 !beyond --import [JSON.....]&lt;br /&gt;
&lt;br /&gt;
== Initiative Roll Macro ==&lt;br /&gt;
&lt;br /&gt;
WARNING: None of these auto handle advantage initiative... although this can be forced with 2d20kh1&lt;br /&gt;
&lt;br /&gt;
Initative Template:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;amp;{template:simple} {{rname=INITIATIVE}} {{mod= @{selected|initiative_bonus} }} {{r1= [[ 1d20 + @{selected|initiative_bonus} &amp;amp;{tracker} ]] }} {{normal=1}}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Force Initiative Advantage:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;amp;{template:simple} {{rname=INITIATIVE ADV}} {{mod= @{selected|initiative_bonus} }} {{r1= [[ {1d20,1d20}kh1 + @{selected|initiative_bonus} &amp;amp;{tracker} ]] }} {{normal=1}}&lt;br /&gt;
&lt;br /&gt;
or  # not sure why the above was used, but there must have been a reason?&lt;br /&gt;
&lt;br /&gt;
&amp;amp;{template:simple} {{rname=INITIATIVE ADV}} {{mod= @{selected|initiative_bonus} }} {{r1= [[ 2d20kh1 + @{selected|initiative_bonus} &amp;amp;{tracker} ]] }} {{normal=1}}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ref: [https://app.roll20.net/forum/post/4681848/linking-monster-action-rat-bite-for-the-start-scenario-to-macro-bar]&lt;br /&gt;
 // @{selected|token_name} rolls [[ @{selected|dex_mod}+1d20 &amp;amp;{tracker} ]] for initiative.&lt;br /&gt;
 @{selected|token_name} rolls [[ 1d20 + @{selected|initiative_bonus} &amp;amp;{tracker} ]] for initiative.&lt;br /&gt;
&lt;br /&gt;
or&lt;br /&gt;
 Rolling Initiative for @{selected|token_name}: [[ 1d20+?{Initiative Bonus|0} &amp;amp;{tracker} ]]&lt;br /&gt;
&lt;br /&gt;
NPC Macro: (doesn&#039;t work with player characters)&lt;br /&gt;
 %{selected|npc_init}&lt;br /&gt;
&lt;br /&gt;
=== DnD Iniative ===&lt;br /&gt;
&lt;br /&gt;
Selected token:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
@{selected|wtype}&amp;amp;{template:simple} {{rname=^{init-u}}} {{mod=@{selected|initiative_bonus}}} {{r1=[[@{selected|initiative_style}+@{selected|initiative_bonus}@{selected|pbd_safe}[INIT] &amp;amp;{tracker}]]}} {{normal=1}} @{selected|charname_output}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If token&#039;s name is &amp;quot;Blarg&amp;quot;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
@{Blarg|wtype}&amp;amp;{template:simple} {{rname=^{init-u}}} {{mod=@{Blarg|initiative_bonus}}} {{r1=[[@{Blarg|initiative_style}+@{Blarg|initiative_bonus}@{Blarg|pbd_safe}[INIT] &amp;amp;{tracker}]]}} {{normal=1}} @{Blarg|charname_output}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Call of Cthulhu Iniative ===&lt;br /&gt;
&lt;br /&gt;
 @{selected|token_name} has [[ @{selected|dexterity} &amp;amp;{tracker} ]] for initiative.&lt;br /&gt;
&lt;br /&gt;
With readied weapon:&lt;br /&gt;
 @{selected|token_name} has [[ 50+@{selected|dexterity} &amp;amp;{tracker} ]] for initiative.&lt;br /&gt;
&lt;br /&gt;
Old one I used:&lt;br /&gt;
 /me rolls [[ @{selected|dexterity_mod}+1d20 &amp;amp;{tracker} ]] for initiative.&lt;br /&gt;
&lt;br /&gt;
=== Delta Green Initiative ===&lt;br /&gt;
&lt;br /&gt;
 @{selected|token_name} Initiative Roll [[@{selected|dexterity_score} [dexterity_score] &amp;amp;{tracker}]]&lt;br /&gt;
&lt;br /&gt;
=== What&#039;s My Luck ===&lt;br /&gt;
&lt;br /&gt;
 @{selected|token_name} has [[ @{selected|luck} ]] luck&lt;br /&gt;
&lt;br /&gt;
== Fog of War and Dynamic Lighting ==&lt;br /&gt;
&lt;br /&gt;
Fog of War - Forced Darkness layer by DM&lt;br /&gt;
&lt;br /&gt;
Advanced Fog of War - Gray Darkness layer&lt;br /&gt;
* Show Grid - Show grid through fog of war and shadows&lt;br /&gt;
* Dim Light Reveals - &lt;br /&gt;
* All Tokens Reveal (GM) -&lt;br /&gt;
&lt;br /&gt;
Dynamic Lighting&lt;br /&gt;
* Enforce Line of Sight - Players can only see light that they can directly see&lt;br /&gt;
* Only Update on Drop - Update areas only drop (good to keep players from sneaking around walls and back)&lt;br /&gt;
* Restrict Movement - Can&#039;t cross DL lines (must have sight)&lt;br /&gt;
* Global Illumination - No shadows (only when you only want restrict only)&lt;br /&gt;
&lt;br /&gt;
== Campaign Settings ==&lt;br /&gt;
&lt;br /&gt;
 Allow players to import their own Characters?  Yes&lt;br /&gt;
&lt;br /&gt;
 ROLL QUERIES:  Advantage Toggle&lt;br /&gt;
 WHISPER ROLLS TO GM:  Whisper Toggle&lt;br /&gt;
&lt;br /&gt;
My preferred for Compendium Monster drops:&lt;br /&gt;
 BAR 1 VALUE:  npc_challenge&lt;br /&gt;
 BAR 2 VALUE:  npc_ac&lt;br /&gt;
 BAR 3 VALUE:  hp_max&lt;br /&gt;
 BAR 3 MAX:  hp_max&lt;br /&gt;
 * all others are blank&lt;br /&gt;
&lt;br /&gt;
 Sanity Score:  On&lt;br /&gt;
&lt;br /&gt;
== 5e.tools ==&lt;br /&gt;
&lt;br /&gt;
Import Monster Manual&lt;br /&gt;
&lt;br /&gt;
 https://5e.tools/roll20.html&lt;br /&gt;
&lt;br /&gt;
 https://wiki.5e.tools/index.php/Better20_User_Guide&lt;br /&gt;
&lt;br /&gt;
* https://wiki.5e.tools/index.php/Feature:_Import&lt;br /&gt;
&lt;br /&gt;
== Advanced Keyboard Shortcuts ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
m	Switch to @ Map &amp;amp; Background Layer&lt;br /&gt;
o	Switch to b Object &amp;amp; Tokens Layer&lt;br /&gt;
k	Switch to E GM Info Layer&lt;br /&gt;
,	Switch to r Dynamic Lighting Layer&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
l m	Move selected object(s) to @ Map &amp;amp; Background Layer	&lt;br /&gt;
l o	Move selected object(s) to b Object &amp;amp; Tokens Layer&lt;br /&gt;
l k	Move selected object(s) to E GM Info Layer&lt;br /&gt;
l ,	Move selected object(s) to r Dynamic Lighting Layer&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ref: https://wiki.roll20.net/Advanced_Shortcuts&lt;br /&gt;
&lt;br /&gt;
== Tips and Tricks ==&lt;br /&gt;
&lt;br /&gt;
Community Forums: Stupid Roll20 Tricks (and some clever ones) | Roll20: Online virtual tabletop &amp;lt;br&amp;gt;&lt;br /&gt;
https://app.roll20.net/forum/post/5899495/stupid-roll20-tricks-and-some-clever-ones/&lt;br /&gt;
&lt;br /&gt;
== Auto Racking Ammunition ==&lt;br /&gt;
&lt;br /&gt;
# Add &amp;quot;5th Edition OGL by Roll20 Companion&amp;quot; API script (Pro only)&lt;br /&gt;
# Character sheet (or default in game settings) - set &amp;quot;Ammo Tracking&amp;quot; to &amp;quot;On&amp;quot;&lt;br /&gt;
# Edit equipment to &amp;quot;Use as a resource&amp;quot;&lt;br /&gt;
# Edit Weapon and set &amp;quot;Ammunition&amp;quot; to name of resource&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
D&amp;amp;D 5E by Roll20: How to setup Ammunition and Resource tracker - Roll20 Wiki&lt;br /&gt;
https://wiki.roll20.net/OGL_5e_DnD:_How_to_setup_Ammunition_and_Resource_tracker&lt;br /&gt;
&lt;br /&gt;
== Addons ==&lt;br /&gt;
&lt;br /&gt;
* [[Roll20/The Sunless Citadel (Tales from the Yawning Portal)]]&lt;br /&gt;
* [[Roll20/Rrakkma - Mordenkainen&#039;s Tome of Foes Introductory Adventure]]&lt;br /&gt;
* [[Roll20/Roll20 Pro Map Pack]]&lt;br /&gt;
* [[Roll20/Pathfinder Playtest Flip-Mat Multi-Pack]]&lt;br /&gt;
&lt;br /&gt;
== Bloodied and Dead Status Markers ==&lt;br /&gt;
&lt;br /&gt;
bloodied.js:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
on(&amp;quot;change:graphic&amp;quot;, function(obj) {&lt;br /&gt;
    // Settings:&lt;br /&gt;
    //var lifeBarNumber = 3;          // 3:red; 2:blue; 1:green&lt;br /&gt;
    var lifeBarNumber = 0;          // 3:red; 2:blue; 1:green&lt;br /&gt;
    var percentForRedmark = 50;     // Write for example 50 for 50%&lt;br /&gt;
    var totalKillThreshold = -10;   // As soon as a tokens life goes bellow this value&lt;br /&gt;
                                    // it gets an additional (killed) symbol.&lt;br /&gt;
    &lt;br /&gt;
    // Auto select bar1 or bar3&lt;br /&gt;
    // Is life bar set at all?&lt;br /&gt;
    // If not simply escape the function.&lt;br /&gt;
    if(obj.get(&amp;quot;bar1_max&amp;quot;) === &amp;quot;&amp;quot;) {&lt;br /&gt;
        if(obj.get(&amp;quot;bar3_max&amp;quot;) === &amp;quot;&amp;quot;) {&lt;br /&gt;
            return;&lt;br /&gt;
        } else {&lt;br /&gt;
            lifeBarNumber = 3;&lt;br /&gt;
        }&lt;br /&gt;
    } else {&lt;br /&gt;
        lifeBarNumber = 1;&lt;br /&gt;
    }&lt;br /&gt;
   &lt;br /&gt;
    // Back from the dead?&lt;br /&gt;
    if((obj.get(&amp;quot;status_dead&amp;quot;) == true || obj.status_skull == true) &amp;amp;&amp;amp; obj.get(&amp;quot;bar&amp;quot; + lifeBarNumber + &amp;quot;_value&amp;quot;) &amp;gt; 0){&lt;br /&gt;
        SetStatuSymbolById(obj,3,1);&lt;br /&gt;
    }&lt;br /&gt;
   &lt;br /&gt;
    // Total-kill&lt;br /&gt;
    if(obj.get(&amp;quot;bar&amp;quot; + lifeBarNumber + &amp;quot;_value&amp;quot;) &amp;lt;= totalKillThreshold){&lt;br /&gt;
        SetStatuSymbolById(obj,0,0);&lt;br /&gt;
        SetStatuSymbolById(obj,1,1);&lt;br /&gt;
        SetStatuSymbolById(obj,2,1);&lt;br /&gt;
        SetStatuSymbolById(obj,3,0);&lt;br /&gt;
    }&lt;br /&gt;
    // Dead&lt;br /&gt;
    else if(obj.get(&amp;quot;bar&amp;quot; + lifeBarNumber + &amp;quot;_value&amp;quot;) &amp;lt;= 0){&lt;br /&gt;
        SetStatuSymbolById(obj,0,0);&lt;br /&gt;
        SetStatuSymbolById(obj,1,1);&lt;br /&gt;
        SetStatuSymbolById(obj,2,0);&lt;br /&gt;
        SetStatuSymbolById(obj,3,0);&lt;br /&gt;
    }&lt;br /&gt;
    // Bellow x% life&lt;br /&gt;
    else if(obj.get(&amp;quot;bar&amp;quot; + lifeBarNumber + &amp;quot;_value&amp;quot;) &amp;lt;= obj.get(&amp;quot;bar&amp;quot; + lifeBarNumber + &amp;quot;_max&amp;quot;) / 100 * percentForRedmark) {&lt;br /&gt;
        SetStatuSymbolById(obj,0,1);&lt;br /&gt;
        SetStatuSymbolById(obj,1,0);&lt;br /&gt;
        SetStatuSymbolById(obj,2,0);&lt;br /&gt;
    }&lt;br /&gt;
    else{&lt;br /&gt;
        ResetDeathSymbols(obj);&lt;br /&gt;
        &lt;br /&gt;
        // Back from the dead but now again with full (or beyond that) health?&lt;br /&gt;
        // TODO: &amp;gt;= not working..?&lt;br /&gt;
        if(obj.get(&amp;quot;bar&amp;quot; + lifeBarNumber + &amp;quot;_value&amp;quot;) == obj.get(&amp;quot;bar&amp;quot; + lifeBarNumber + &amp;quot;_max&amp;quot;)){&lt;br /&gt;
            SetStatuSymbolById(obj,3,0);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
Reset the following symboles&lt;br /&gt;
    redmarker, dead &amp;amp; skull&lt;br /&gt;
*/&lt;br /&gt;
function ResetDeathSymbols(obj){&lt;br /&gt;
    SetStatuSymbolById(obj,0,0);&lt;br /&gt;
    SetStatuSymbolById(obj,1,0);&lt;br /&gt;
    SetStatuSymbolById(obj,2,0);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
Sets the value of a given tokens symbol by the symbols id&lt;br /&gt;
symbolid:&lt;br /&gt;
    0:redmarker&lt;br /&gt;
    1:dead&lt;br /&gt;
    2:skull&lt;br /&gt;
    3:death-zone&lt;br /&gt;
    x:y&lt;br /&gt;
    &lt;br /&gt;
value:&lt;br /&gt;
    true/1 or false/0&lt;br /&gt;
 */&lt;br /&gt;
function SetStatuSymbolById(obj, symbolid, value) {&lt;br /&gt;
    switch(symbolid){&lt;br /&gt;
        case 0:&lt;br /&gt;
            SetStatusSymbolByName(obj, &amp;quot;redmarker&amp;quot;, value);&lt;br /&gt;
            break;&lt;br /&gt;
        case 1:&lt;br /&gt;
            SetStatusSymbolByName(obj, &amp;quot;dead&amp;quot;, value);&lt;br /&gt;
            break;&lt;br /&gt;
        case 2:&lt;br /&gt;
            SetStatusSymbolByName(obj, &amp;quot;skull&amp;quot;, value);&lt;br /&gt;
            break;&lt;br /&gt;
        case 3:&lt;br /&gt;
            SetStatusSymbolByName(obj, &amp;quot;death-zone&amp;quot;, value);&lt;br /&gt;
            break;&lt;br /&gt;
        default:&lt;br /&gt;
            // Something is wrong so log it and exit.&lt;br /&gt;
            log(&amp;quot;Error: SetStatuSymbolById - There was no usable number for symbolid given!&amp;quot;);&lt;br /&gt;
            log(&amp;quot;       Object name: &amp;quot; + obj.get(&amp;quot;name&amp;quot;) + &amp;quot;; symbolid: &amp;quot; + symbolid + &amp;quot;; value: &amp;quot; + value);&lt;br /&gt;
            return;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
Sets the value of a given tokens symbol by the symbols name&lt;br /&gt;
value:&lt;br /&gt;
    true/1 or false/0&lt;br /&gt;
*/&lt;br /&gt;
function SetStatusSymbolByName(obj, symbolname, value){&lt;br /&gt;
    value = CheckForTrueOrFalse(value);&lt;br /&gt;
    &lt;br /&gt;
    // Set the symbols value.&lt;br /&gt;
    obj.set(&amp;quot;status_&amp;quot; + symbolname, value);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
Checks if a given value is true or false.&lt;br /&gt;
value:&lt;br /&gt;
    0:false&lt;br /&gt;
    1:true&lt;br /&gt;
    default:false&lt;br /&gt;
*/&lt;br /&gt;
function CheckForTrueOrFalse(value){&lt;br /&gt;
    if (value === 0){value = false;}&lt;br /&gt;
    else if (value === 1){value = true;}&lt;br /&gt;
    else if (value === true || value === false){&lt;br /&gt;
        // Nothing to do, these are valid values.&lt;br /&gt;
    }&lt;br /&gt;
    // The input for value is not known, therefore we set it to false.&lt;br /&gt;
    else{&lt;br /&gt;
        value = false;&lt;br /&gt;
        log(&amp;quot;Error: CheckForTrueOrFalse - An unhandled value has been used!&amp;quot;);&lt;br /&gt;
        log(&amp;quot;       value has been set to de default value &amp;quot; + value);&lt;br /&gt;
    }&lt;br /&gt;
    return value;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
Debug function&lt;br /&gt;
Place where ever you would like to see the actual values.&lt;br /&gt;
*/&lt;br /&gt;
function DebugMe(obj,msg){&lt;br /&gt;
    log(&amp;quot;--- DEBUG: &amp;quot; + msg + &amp;quot;---&amp;quot;);&lt;br /&gt;
    log(&amp;quot;obj name: &amp;quot; + obj.get(&amp;quot;name&amp;quot;));&lt;br /&gt;
    log(&amp;quot;status values:&amp;quot;);&lt;br /&gt;
    log(&amp;quot;redmarker:    &amp;quot; + obj.get(&amp;quot;status_redmarker&amp;quot;));&lt;br /&gt;
    log(&amp;quot;dead:    &amp;quot; + obj.get(&amp;quot;status_dead&amp;quot;));&lt;br /&gt;
    log(&amp;quot;skull:    &amp;quot; + obj.get(&amp;quot;status_skull&amp;quot;));&lt;br /&gt;
    log(&amp;quot;death:    &amp;quot; + obj.get(&amp;quot;status_death&amp;quot;));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Original:&lt;br /&gt;
* Community Forums: [Script] Bloodied and Dead Status Markers - Extended | Roll20: Online virtual tabletop - https://app.roll20.net/forum/permalink/725584/&lt;br /&gt;
&lt;br /&gt;
Modified: https://app.roll20.net/forum/post/8507481/script-bloodied-and-dead-status-markers-extended-auto-select-bar-1-or-3/?pageforid=8507481#post-8507481&lt;br /&gt;
&lt;br /&gt;
Cuerpo ref: https://app.roll20.net/users/389397/cuerpo&lt;br /&gt;
&lt;br /&gt;
ref: https://wiki.roll20.net/API:Cookboox&lt;br /&gt;
&lt;br /&gt;
=== :Bloodied_and_Dead_Status_Markers ===&lt;br /&gt;
&lt;br /&gt;
 https://wiki.roll20.net/Script:Bloodied_and_Dead_Status_Markers&lt;br /&gt;
&lt;br /&gt;
 Scripts moved to:&lt;br /&gt;
 https://github.com/Roll20/roll20-api-scripts/tree/44c583189173bd5cfb68031f6b1a6a869c0b24a4/Bloodied%20and%20Dead%20Status%20Markers&lt;br /&gt;
&lt;br /&gt;
bloodied.js&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
var barValue = &amp;quot;bar1&amp;quot;;&lt;br /&gt;
var acceptedValues = [&amp;quot;bar1&amp;quot;, &amp;quot;bar2&amp;quot;, &amp;quot;bar3&amp;quot;];&lt;br /&gt;
&lt;br /&gt;
on(&#039;chat:message&#039;, function (msg) {&lt;br /&gt;
 &lt;br /&gt;
    if (msg.type == &#039;api&#039; &amp;amp;&amp;amp; msg.content.indexOf(&#039;!ChangeBar&#039;) !== -1) {&lt;br /&gt;
        var message = msg.content.split(&amp;quot; &amp;quot;)[1];&lt;br /&gt;
        log(&amp;quot;Message: &amp;quot; + message);&lt;br /&gt;
        if (acceptedValues.includes(message)) {&lt;br /&gt;
            barValue = message;&lt;br /&gt;
            log(&amp;quot;Blood and Dead bar value changed to &amp;quot; + message);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
on(&amp;quot;change:graphic:bar1_value&amp;quot;, function(obj) {&lt;br /&gt;
    if(obj.get(&amp;quot;bar1_max&amp;quot;) === &amp;quot;&amp;quot;) return;&lt;br /&gt;
   &lt;br /&gt;
    if(obj.get(&amp;quot;bar1_value&amp;quot;) &amp;lt;= obj.get(&amp;quot;bar1_max&amp;quot;) / 2) {&lt;br /&gt;
        obj.set({&lt;br /&gt;
              status_redmarker: true&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
    else{&lt;br /&gt;
        obj.set({&lt;br /&gt;
            status_redmarker: false&lt;br /&gt;
        })&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if(obj.get(&amp;quot;bar1_value&amp;quot;) &amp;lt;= 0) {&lt;br /&gt;
      obj.set({&lt;br /&gt;
         status_dead: true&lt;br /&gt;
      });&lt;br /&gt;
    }&lt;br /&gt;
    else {&lt;br /&gt;
      obj.set({&lt;br /&gt;
        status_dead: false&lt;br /&gt;
      });&lt;br /&gt;
    }&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Roll20 Scripts Collection ==&lt;br /&gt;
&lt;br /&gt;
 https://github.com/Roll20/roll20-api-scripts/&lt;br /&gt;
&lt;br /&gt;
== Puzzle Packs ==&lt;br /&gt;
&lt;br /&gt;
 https://marketplace.roll20.net/browse/publisher/91/paul-camp&lt;br /&gt;
&lt;br /&gt;
 Escape the Room: Fantasy Edition | Roll20 Marketplace: Digital goods for online tabletop gaming&lt;br /&gt;
 https://marketplace.roll20.net/browse/gameaddon/359/escape-the-room-fantasy-edition&lt;br /&gt;
&lt;br /&gt;
== DnDBeyond Integration ==&lt;br /&gt;
&lt;br /&gt;
 Beyond 20 - Chrome Web Store&lt;br /&gt;
 https://chrome.google.com/webstore/detail/beyond-20/gnblbpbepfbfmoobegdogkglpbhcjofh?hl=en&lt;br /&gt;
&lt;br /&gt;
== Forums ==&lt;br /&gt;
&lt;br /&gt;
=== Colored Text ===&lt;br /&gt;
&lt;br /&gt;
&amp;quot;I do all of my editing in office [Word], then copy/paste into Roll20.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Community Forums: Colored text | Roll20: Online virtual tabletop&lt;br /&gt;
https://app.roll20.net/forum/post/2069398/colored-text&lt;br /&gt;
&lt;br /&gt;
== Status Page ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
503 Service Unavailable&lt;br /&gt;
&lt;br /&gt;
There was not a server available to handle your request. Most of the time this is a temporary error -- try reloading. If you are consistently seeing this error, then there may be an issue with the site. See the status page: http://status.roll20.net&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 http://status.roll20.net&lt;br /&gt;
&lt;br /&gt;
== Long Rest ==&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;5th Edition OGL by Roll20 Companion&amp;quot; includes a !longrest command.&lt;br /&gt;
&lt;br /&gt;
If you want to call a list of characters in a super macro:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
!longrest @{Bob|character_name}&lt;br /&gt;
!longrest @{Sue|character_name}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or by Character ID:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
!longrest @{Bob&#039;s character id|character_name}&lt;br /&gt;
!longrest @{Sue&#039;s character id|character_name}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you add in the ChatSetAttr you can also reset Resources too..&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
!longrest @{selected|character_name}&lt;br /&gt;
&lt;br /&gt;
!setattr --silent --sel --hp|@{selected|hp|max}&lt;br /&gt;
&lt;br /&gt;
!setattr --silent --sel --class_resource|@{selected|class_resource|max}&lt;br /&gt;
&lt;br /&gt;
!setattr --silent --sel --other_resource|@{selected|other_resource|max}&lt;br /&gt;
&lt;br /&gt;
&amp;amp;{template:npcaction} {{name=@{selected|character_name}}} {{rname=Long Rest}} {{description=Reset HP, Spell Slots, @{selected|class_resource_name}, @{selected|other_resource_name}}}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you have other resources:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;amp;{template:npcaction} {{name=@{selected|character_name}}} {{rname=Long Rest}} {{description=Reset HP, Spell Slots, @{selected|class_resource_name}, @{selected|other_resource_name}, @{selected|repeating_resource_$0_resource_left_name}, @{selected|repeating_resource_$0_resource_right_name}}}&lt;br /&gt;
&lt;br /&gt;
!setattr --silent --sel --repeating_resource_$0_resource_left|@{selected|repeating_resource_$0_resource_left|max}&lt;br /&gt;
&lt;br /&gt;
!setattr --silent --sel --repeating_resource_$0_resource_right|@{selected|repeating_resource_$0_resource_right|max}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you don&#039;t want HP to reset on Long Rest: (as the values are all calculated prior to the script running)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
!setattr --silent --sel --hp|@{selected|hp}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ref: [https://app.roll20.net/forum/post/7028634/how-to-long-rest] [https://app.roll20.net/forum/post/8872569/long-rest-macro] [https://app.roll20.net/forum/post/5338392/how-to-take-a-long-rest-w-slash-5e-ogl-by-roll20]&lt;br /&gt;
&lt;br /&gt;
== API Scripts ==&lt;br /&gt;
&lt;br /&gt;
Category:User API Scripts - Roll20 Wiki&lt;br /&gt;
https://wiki.roll20.net/Category:User_API_Scripts&lt;br /&gt;
&lt;br /&gt;
=== My Custom Favorites ===&lt;br /&gt;
&lt;br /&gt;
Bloodied and Dead Status Markers&lt;br /&gt;
* https://wiki.roll20.net/Script:Bloodied_and_Dead_Status_Markers&lt;br /&gt;
&lt;br /&gt;
World Map Discovery (I like my custom version better)&lt;br /&gt;
* https://github.com/Cazra/roll20-api-scripts/tree/master/WorldMapDiscovery&lt;br /&gt;
&lt;br /&gt;
=== My 1st Favorites ===&lt;br /&gt;
&lt;br /&gt;
* 5th Edition OGL by Roll20 Companion&lt;br /&gt;
&lt;br /&gt;
* Token Fate&lt;br /&gt;
&lt;br /&gt;
* True Page Copy&lt;br /&gt;
&lt;br /&gt;
=== My 2st Favorites ===&lt;br /&gt;
&lt;br /&gt;
* DeathTracker&lt;br /&gt;
&lt;br /&gt;
* DryErase&lt;br /&gt;
&lt;br /&gt;
* DLEllipseDrawer&lt;br /&gt;
&lt;br /&gt;
* Hourglass&lt;br /&gt;
&lt;br /&gt;
* It&#039;s a Trap!&lt;br /&gt;
&lt;br /&gt;
* Path Splitter&lt;br /&gt;
&lt;br /&gt;
* PublicSheet&lt;br /&gt;
&lt;br /&gt;
* Marking Conditions&lt;br /&gt;
** https://wiki.roll20.net/Script:Marking_Conditions&lt;br /&gt;
** https://github.com/Roll20/roll20-api-scripts/tree/master/Marking%20Conditions&lt;br /&gt;
&lt;br /&gt;
* One-Way Dynamic Lighting&lt;br /&gt;
&lt;br /&gt;
* StatusInfo&lt;br /&gt;
** https://github.com/RobinKuiper/Roll20APIScripts/tree/master/StatusInfo&lt;br /&gt;
&lt;br /&gt;
* TokenNameNumber&lt;br /&gt;
&lt;br /&gt;
* Torch&lt;br /&gt;
&lt;br /&gt;
* TurnClock&lt;br /&gt;
&lt;br /&gt;
* World Map Discovery (I like my custom version better)&lt;br /&gt;
** https://app.roll20.net/forum/post/2391505/slug%7D&lt;br /&gt;
** https://github.com/Cazra/roll20-api-scripts/tree/master/WorldMapDiscovery&lt;br /&gt;
&lt;br /&gt;
=== Dependencies ===&lt;br /&gt;
&lt;br /&gt;
* Character Sheet Utils&lt;br /&gt;
* HTML Builder&lt;br /&gt;
* MatrixMath&lt;br /&gt;
* Path Math&lt;br /&gt;
* splitArgs&lt;br /&gt;
* Token Collisions&lt;br /&gt;
* Vector Math&lt;br /&gt;
&lt;br /&gt;
== Call of Cthulhu Sheet ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;amp;{template:callofcthulhu} {{name=Some test...}}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Keywords ==&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=RustDesk&amp;diff=9858</id>
		<title>RustDesk</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=RustDesk&amp;diff=9858"/>
		<updated>2026-04-22T22:02:07Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: /* Installation Creator */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Rust Desk ==&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
&lt;br /&gt;
 Installation :: Documentation for RustDesk&lt;br /&gt;
 https://rustdesk.com/docs/en/self-host/rustdesk-server-oss/install/&lt;br /&gt;
&lt;br /&gt;
 ufw allow 22/tcp comment &amp;quot;SSH&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 ufw allow 21114:21119/tcp comment &amp;quot;RustDesk&amp;quot;&lt;br /&gt;
 ufw allow 8000/tcp comment &amp;quot;RustDesk Web&amp;quot;&lt;br /&gt;
 ufw allow 21116/udp comment &amp;quot;RustDesk&amp;quot;&lt;br /&gt;
 sudo ufw enable&lt;br /&gt;
&lt;br /&gt;
 wget https://raw.githubusercontent.com/techahold/rustdeskinstall/master/install.sh&lt;br /&gt;
 chmod +x install.sh&lt;br /&gt;
 ./install.sh&lt;br /&gt;
&lt;br /&gt;
=== Docker Option ===&lt;br /&gt;
&lt;br /&gt;
ref: https://rustdesk.com/docs/en/self-host/rustdesk-server-oss/docker/&lt;br /&gt;
&lt;br /&gt;
 sudo docker image pull rustdesk/rustdesk-server&lt;br /&gt;
 sudo docker run --name hbbs -v ./data:/root -td --net=host --restart unless-stopped rustdesk/rustdesk-server hbbs&lt;br /&gt;
 sudo docker run --name hbbr -v ./data:/root -td --net=host --restart unless-stopped rustdesk/rustdesk-server hbbr&lt;br /&gt;
&lt;br /&gt;
== Services ==&lt;br /&gt;
&lt;br /&gt;
hbbs - RustDesk ID/Rendezvous server&lt;br /&gt;
hbbr - RustDesk Relay server&lt;br /&gt;
&lt;br /&gt;
== Installation Creator ==&lt;br /&gt;
&lt;br /&gt;
 https://rdgen.crayoneater.org/&lt;br /&gt;
&lt;br /&gt;
== Web Client ==&lt;br /&gt;
&lt;br /&gt;
 https://rustdesk.com/web/&lt;br /&gt;
&lt;br /&gt;
== keywords ==&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=Winget&amp;diff=9857</id>
		<title>Winget</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=Winget&amp;diff=9857"/>
		<updated>2026-04-22T22:01:31Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: Redirected page to WinGet&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[WinGet]]&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=Proxmox&amp;diff=9856</id>
		<title>Proxmox</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=Proxmox&amp;diff=9856"/>
		<updated>2026-04-22T18:16:48Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: /* List Data Stores */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Subpages ==&lt;br /&gt;
&lt;br /&gt;
{{subpages}}&lt;br /&gt;
&lt;br /&gt;
== Get Version from Command Line ==&lt;br /&gt;
&lt;br /&gt;
 pveversion&lt;br /&gt;
&lt;br /&gt;
 pveversion --verbose&lt;br /&gt;
&lt;br /&gt;
== Sync Config Manually ==&lt;br /&gt;
&lt;br /&gt;
 corosync&lt;br /&gt;
&lt;br /&gt;
== Virtualization Management ==&lt;br /&gt;
&lt;br /&gt;
Virtual Machines vs Containers&lt;br /&gt;
&lt;br /&gt;
Proxmox can create and manage both fully-fledged Virtual Machines (VMs) and light-weight Linux Containers (LCX).&lt;br /&gt;
&lt;br /&gt;
=== VM Managemnet ===&lt;br /&gt;
&lt;br /&gt;
 qm - QEMU/KVM Virtual Machine Manager&lt;br /&gt;
&lt;br /&gt;
List VMs:&lt;br /&gt;
 qm list&lt;br /&gt;
&lt;br /&gt;
Stop VM:&lt;br /&gt;
 qm stop [VMID]&lt;br /&gt;
&lt;br /&gt;
Start VM:&lt;br /&gt;
 qm start [VMID]&lt;br /&gt;
&lt;br /&gt;
=== LCX Container Management ===&lt;br /&gt;
&lt;br /&gt;
 pct - Tool to manage Linux Containers (LXC) on Proxmox VE&lt;br /&gt;
&lt;br /&gt;
List Containers:&lt;br /&gt;
 pct list&lt;br /&gt;
&lt;br /&gt;
Stop Container:&lt;br /&gt;
 pct stop [VMID]&lt;br /&gt;
&lt;br /&gt;
Start Container:&lt;br /&gt;
 pct start [VMID]&lt;br /&gt;
&lt;br /&gt;
== NFS in Container ==&lt;br /&gt;
&lt;br /&gt;
Mark &amp;quot;NFS&amp;quot; in features, but first it will need to be a &amp;quot;Privileged&amp;quot; container.&lt;br /&gt;
&lt;br /&gt;
https://i.imgur.com/PDEvmuJ.png&lt;br /&gt;
&lt;br /&gt;
To convert to Priveleged, simply run a backup, then restore and mark the &amp;quot;priveleged&amp;quot; checkbox.  Pretty easy.&lt;br /&gt;
&lt;br /&gt;
https://i.imgur.com/4MQUFLm.png&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
NFS requires extra permissions to run in a Container (CT), which uses LXC.&lt;br /&gt;
&lt;br /&gt;
Deselect &amp;quot;Unprivileged container&amp;quot;, and add the Features &amp;quot;mount=nfs&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 # mount 192.168.108.30:/nfs/ken /mnt&lt;br /&gt;
 mount.nfs: access denied by server while mounting 192.168.108.30:/nfs/ken&lt;br /&gt;
&lt;br /&gt;
When trying to add the &amp;quot;mount=nfs&amp;quot; feature:&lt;br /&gt;
 Permission check failed (changing feature flags for privileged container is only allowed for root@pam) (403)&lt;br /&gt;
&lt;br /&gt;
Login as root and:&lt;br /&gt;
 pct set 112 -features mount=nfs&lt;br /&gt;
&lt;br /&gt;
 # pct set 112 -features mount=nfs --save  # is this needed?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ref [https://www.jamescoyle.net/how-to/689-mount-nfs-volume-in-a-proxmox-openvz-container] [https://theorangeone.net/posts/mount-nfs-inside-lxc/]&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
== List Data Stores ==&lt;br /&gt;
&lt;br /&gt;
List data stores and status:&lt;br /&gt;
 pvesm status&lt;br /&gt;
&lt;br /&gt;
== NTP ==&lt;br /&gt;
&lt;br /&gt;
 Time Synchronization - Proxmox VE&lt;br /&gt;
 https://pve.proxmox.com/wiki/Time_Synchronization&lt;br /&gt;
&lt;br /&gt;
Proxmox nodes usually act as standalone NTP clients, synchronizing with public pools (e.g., pool.ntp.org) by default.&lt;br /&gt;
&lt;br /&gt;
Check status:&lt;br /&gt;
 chronyc tracking&lt;br /&gt;
&lt;br /&gt;
Good if you see this:&lt;br /&gt;
 Leap status     : Normal&lt;br /&gt;
&lt;br /&gt;
Not good if you see this:&lt;br /&gt;
 # Leap status     : Not synchronised&lt;br /&gt;
&lt;br /&gt;
Check sources:&lt;br /&gt;
 chronyc sources -v&lt;br /&gt;
&lt;br /&gt;
Restart time sync:&lt;br /&gt;
 systemctl restart chronyd&lt;br /&gt;
&lt;br /&gt;
Check service status:&lt;br /&gt;
 journalctl --since -1h -u chrony&lt;br /&gt;
&lt;br /&gt;
Setting Custom Servers:&lt;br /&gt;
 /etc/chrony/chrony.conf&lt;br /&gt;
&lt;br /&gt;
 # or if this exists:&lt;br /&gt;
 /etc/chrony.conf&lt;br /&gt;
 # or you can create it with:&lt;br /&gt;
 ln -s /etc/chrony/chrony.conf /etc/chrony.conf&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
For systems using systemd-timesyncd:&lt;br /&gt;
&lt;br /&gt;
/etc/systemd/timesyncd.conf&lt;br /&gt;
 [Time]&lt;br /&gt;
 NTP=ntp1.example.com ntp2.example.com ntp3.example.com ntp4.example.com&lt;br /&gt;
&lt;br /&gt;
 systemctl status systemd-timesyncd&lt;br /&gt;
&lt;br /&gt;
 systemctl restart systemd-timesyncd&lt;br /&gt;
&lt;br /&gt;
 journalctl --since -1h -u systemd-timesyncd&lt;br /&gt;
&lt;br /&gt;
== HTTPS Redirect ==&lt;br /&gt;
&lt;br /&gt;
To have Proxmox respond on port 443 instead of just on 8006&lt;br /&gt;
&lt;br /&gt;
 /etc/network/interfaces&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
auto vmbr0&lt;br /&gt;
iface vmbr0 inet static&lt;br /&gt;
        address 10.0.0.100/24&lt;br /&gt;
        gateway 10.0.0.1&lt;br /&gt;
        bridge-ports enp3s0&lt;br /&gt;
        bridge-stp off&lt;br /&gt;
        bridge-fd 0&lt;br /&gt;
        mtu 9000&lt;br /&gt;
        post-up iptables -t nat -A PREROUTING -d 10.0.0.100 -p tcp --dport 443 -j REDIRECT --to-port 8006 || true&lt;br /&gt;
iface vmbr0 inet6 auto&lt;br /&gt;
#Public&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 systemctl restart networking&lt;br /&gt;
&lt;br /&gt;
Show:&lt;br /&gt;
 iptables -L -t nat&lt;br /&gt;
&lt;br /&gt;
== Free Subscription Repositories ==&lt;br /&gt;
&lt;br /&gt;
# Disable ceph Enterprise&lt;br /&gt;
# Disable pve-enterprise&lt;br /&gt;
# Add pve-no-subscription repo - &#039;&#039;deb http://download.proxmox.com/debian/pve bookworm pve-no-subscription&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
/etc/apt/sources.list :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
deb http://ftp.us.debian.org/debian bookworm main contrib&lt;br /&gt;
&lt;br /&gt;
deb http://ftp.us.debian.org/debian bookworm-updates main contrib&lt;br /&gt;
&lt;br /&gt;
# security updates&lt;br /&gt;
deb http://security.debian.org bookworm-security main contrib&lt;br /&gt;
&lt;br /&gt;
deb http://download.proxmox.com/debian/pve bookworm pve-no-subscription&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/etc/apt/sources.list.d/ceph.list :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# deb https://enterprise.proxmox.com/debian/ceph-quincy bookworm enterprise&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/etc/apt/sources.list.d/pve-enterprise.list :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# deb https://enterprise.proxmox.com/debian/pve bookworm pve-enterprise&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: this can be configured from the web interface too.&lt;br /&gt;
&lt;br /&gt;
https://i.imgur.com/5zaSWgz.png&lt;br /&gt;
&lt;br /&gt;
== Install sudo ==&lt;br /&gt;
&lt;br /&gt;
 apt update&lt;br /&gt;
 apt install sudo&lt;br /&gt;
&lt;br /&gt;
== LXC - Linux Containers ==&lt;br /&gt;
&lt;br /&gt;
To use the LC options you first need to download a LC template.&lt;br /&gt;
&lt;br /&gt;
First update the list:&lt;br /&gt;
 pveam update&lt;br /&gt;
&lt;br /&gt;
Note: The list of available templates is updated daily through the &#039;&#039;&#039;pve-daily-update&#039;&#039;&#039; timer&lt;br /&gt;
&lt;br /&gt;
To list images:&lt;br /&gt;
 pveam available&lt;br /&gt;
&lt;br /&gt;
To list only system images:&lt;br /&gt;
 pveam available --section system&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
root@proxmox1:~# pveam available --section system&lt;br /&gt;
system          almalinux-9-default_20221108_amd64.tar.xz&lt;br /&gt;
system          alpine-3.18-default_20230607_amd64.tar.xz&lt;br /&gt;
system          archlinux-base_20230608-1_amd64.tar.zst&lt;br /&gt;
system          centos-9-stream-default_20221109_amd64.tar.xz&lt;br /&gt;
system          debian-11-standard_11.7-1_amd64.tar.zst&lt;br /&gt;
system          debian-12-standard_12.2-1_amd64.tar.zst&lt;br /&gt;
system          devuan-4.0-standard_4.0_amd64.tar.gz&lt;br /&gt;
system          fedora-38-default_20230607_amd64.tar.xz&lt;br /&gt;
system          fedora-39-default_20231118_amd64.tar.xz&lt;br /&gt;
system          gentoo-current-openrc_20231009_amd64.tar.xz&lt;br /&gt;
system          opensuse-15.4-default_20221109_amd64.tar.xz&lt;br /&gt;
system          opensuse-15.5-default_20231118_amd64.tar.xz&lt;br /&gt;
system          rockylinux-9-default_20221109_amd64.tar.xz&lt;br /&gt;
system          ubuntu-20.04-standard_20.04-1_amd64.tar.gz&lt;br /&gt;
system          ubuntu-22.04-standard_22.04-1_amd64.tar.zst&lt;br /&gt;
system          ubuntu-23.04-standard_23.04-1_amd64.tar.zst&lt;br /&gt;
system          ubuntu-23.10-standard_23.10-1_amd64.tar.zst&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Download to data store:&lt;br /&gt;
 pveam download mydatastore ubuntu-22.04-standard_22.04-1_amd64.tar.zst&lt;br /&gt;
&lt;br /&gt;
List images on data store:&lt;br /&gt;
 pveam list mydatastore&lt;br /&gt;
&lt;br /&gt;
 # example&lt;br /&gt;
 NAME                                                                 SIZE&lt;br /&gt;
 mydatastore:vztmpl/ubuntu-22.04-standard_22.04-1_amd64.tar.zst       123.81MB&lt;br /&gt;
&lt;br /&gt;
To remove:&lt;br /&gt;
 pveam remove mydatastore:vztmpl/ubuntu-22.04-standard_22.04-1_amd64.tar.zst&lt;br /&gt;
&lt;br /&gt;
See https://pve.proxmox.com/wiki/Linux_Container&lt;br /&gt;
&lt;br /&gt;
== Upgrade Proxmox 7 to Proxmox 8 ==&lt;br /&gt;
&lt;br /&gt;
 Upgrade from 7 to 8 - Proxmox VE&lt;br /&gt;
 https://pve.proxmox.com/wiki/Upgrade_from_7_to_8&lt;br /&gt;
&lt;br /&gt;
Update to latest v7:&lt;br /&gt;
 apt update&lt;br /&gt;
 apt dist-upgrade&lt;br /&gt;
&lt;br /&gt;
Checks:&lt;br /&gt;
 pve7to8&lt;br /&gt;
&lt;br /&gt;
All checks:&lt;br /&gt;
 pve7to8 --full&lt;br /&gt;
&lt;br /&gt;
Switch to Bookworm:&lt;br /&gt;
 sed -i &#039;s/bullseye/bookworm/g&#039; /etc/apt/sources.list&lt;br /&gt;
&lt;br /&gt;
 sed -i &#039;s/bullseye/bookworm/g&#039; /etc/apt/sources.list.d/*&lt;br /&gt;
&lt;br /&gt;
Add VE 8:&lt;br /&gt;
 # echo &amp;quot;deb https://enterprise.proxmox.com/debian/pve bookworm pve-enterprise&amp;quot; &amp;gt; /etc/apt/sources.list.d/pve-enterprise.list&lt;br /&gt;
 sed -i -e &#039;s/bullseye/bookworm/g&#039; /etc/apt/sources.list.d/pve-install-repo.list &lt;br /&gt;
&lt;br /&gt;
Update system to v8:&lt;br /&gt;
 apt update&lt;br /&gt;
 apt dist-upgrade&lt;br /&gt;
&lt;br /&gt;
== Issues ==&lt;br /&gt;
&lt;br /&gt;
=== Suck Backup Job ===&lt;br /&gt;
&lt;br /&gt;
 ps awxf | grep vzdump&lt;br /&gt;
&lt;br /&gt;
Proper way to stop:&lt;br /&gt;
 vzdump -stop&lt;br /&gt;
&lt;br /&gt;
Usually related to mount points &amp;lt;ref&amp;gt;https://forum.proxmox.com/threads/backup-job-is-stuck-and-i-cannot-stop-it-or-even-kill-it.120835/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If that doesn&#039;t work, can kill.  Find process first.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
root@proxmox1:~# ps awxf | grep vzdump&lt;br /&gt;
1305267 pts/0    S+     0:00          \_ grep vzdump&lt;br /&gt;
 916782 ?        Ss     0:02 task UPID:proxmox2:000DFD2E:9A21B1C6:670B61EA:vzdump::root@pam:&lt;br /&gt;
 916789 ?        S      0:00  \_ rsync --stats -h --numeric-ids -aH --delete --no-whole-file --sparse --one-file-system --relative --exclude=/tmp/?* --exclude=/var/tmp/?* --exclude=/var/run/?*.pid /proc/262434/root//./ /mnt/pve/TrueNAS/dump/vzdump-lxc-108-2024_10_13-00_00_10.tmp&lt;br /&gt;
 916790 ?        S      0:00      \_ rsync --stats -h --numeric-ids -aH --delete --no-whole-file --sparse --one-file-system --relative --exclude=/tmp/?* --exclude=/var/tmp/?* --exclude=/var/run/?*.pid /proc/262434/root//./ /mnt/pve/TrueNAS/dump/vzdump-lxc-108-2024_10_13-00_00_10.tmp&lt;br /&gt;
 916791 ?        S      0:00          \_ rsync --stats -h --numeric-ids -aH --delete --no-whole-file --sparse --one-file-system --relative --exclude=/tmp/?* --exclude=/var/tmp/?* --exclude=/var/run/?*.pid /proc/262434/root//./ /mnt/pve/TrueNAS/dump/vzdump-lxc-108-2024_10_13-00_00_10.tmp&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Kill the process ID associated with the task, which should cause it to jump to the next task.&lt;br /&gt;
&lt;br /&gt;
But this seems to leave everything in a locked state for backup&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# kill 916782&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Unlock VM ===&lt;br /&gt;
&lt;br /&gt;
To unlock a VM that is stuck in a locked state:&lt;br /&gt;
 qm unlock 101&lt;br /&gt;
&lt;br /&gt;
see pct for LXCs&lt;br /&gt;
&lt;br /&gt;
=== Unlock LXC Container ===&lt;br /&gt;
&lt;br /&gt;
To unlock a LXC Container that is stuck in a locked state:&lt;br /&gt;
 pct unlock 101&lt;br /&gt;
&lt;br /&gt;
=== ping - Operation not permitted ===&lt;br /&gt;
&lt;br /&gt;
Fix with:&lt;br /&gt;
 setcap cap_net_raw+ep /bin/ping&lt;br /&gt;
&lt;br /&gt;
or:&lt;br /&gt;
 chmod u+s /sbin/ping&lt;br /&gt;
&lt;br /&gt;
&amp;quot;I suspect the setuid workaround would likely work and is how ping was shipped in distros for a very long time (and so not particularly risky).&amp;quot; &amp;lt;ref&amp;gt;https://discuss.linuxcontainers.org/t/ping-is-failing-in-containers-with-ping-socket-operation-not-permitted/14240/4&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ref &amp;lt;ref&amp;gt;Ping with unprivileged user in LXC container / Linux capabilities | Proxmox Support Forum - https://forum.proxmox.com/threads/ping-with-unprivileged-user-in-lxc-container-linux-capabilities.42308/&amp;lt;/ref&amp;gt; &amp;lt;ref&amp;gt;No ping from non root user in Debian Buster LXC | Proxmox Support Forum - https://forum.proxmox.com/threads/no-ping-from-non-root-user-in-debian-buster-lxc.72366/#post-387633&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== sudo - setrlimit(RLIMIT_CORE): Operation not permitted ===&lt;br /&gt;
&lt;br /&gt;
Inside of Ubuntu 20 LXC...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ sudo hello &amp;gt; /dev/null&lt;br /&gt;
sudo: setrlimit(RLIMIT_CORE): Operation not permitted&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bug in sudo version.  Just update sudo.&lt;br /&gt;
&lt;br /&gt;
 apt update&lt;br /&gt;
 apt upgrade sudo&lt;br /&gt;
&lt;br /&gt;
Alt workaround:&lt;br /&gt;
 echo &amp;quot;Set disable_coredump false&amp;quot; &amp;gt;&amp;gt; /etc/sudo.conf&lt;br /&gt;
&lt;br /&gt;
ref &amp;lt;ref&amp;gt;https://github.com/sudo-project/sudo/issues/42&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
{{ref}}&lt;br /&gt;
&lt;br /&gt;
== keywords ==&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=Proxmox&amp;diff=9855</id>
		<title>Proxmox</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=Proxmox&amp;diff=9855"/>
		<updated>2026-04-22T17:56:06Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: /* HTTPS Redirect */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Subpages ==&lt;br /&gt;
&lt;br /&gt;
{{subpages}}&lt;br /&gt;
&lt;br /&gt;
== Get Version from Command Line ==&lt;br /&gt;
&lt;br /&gt;
 pveversion&lt;br /&gt;
&lt;br /&gt;
 pveversion --verbose&lt;br /&gt;
&lt;br /&gt;
== Sync Config Manually ==&lt;br /&gt;
&lt;br /&gt;
 corosync&lt;br /&gt;
&lt;br /&gt;
== Virtualization Management ==&lt;br /&gt;
&lt;br /&gt;
Virtual Machines vs Containers&lt;br /&gt;
&lt;br /&gt;
Proxmox can create and manage both fully-fledged Virtual Machines (VMs) and light-weight Linux Containers (LCX).&lt;br /&gt;
&lt;br /&gt;
=== VM Managemnet ===&lt;br /&gt;
&lt;br /&gt;
 qm - QEMU/KVM Virtual Machine Manager&lt;br /&gt;
&lt;br /&gt;
List VMs:&lt;br /&gt;
 qm list&lt;br /&gt;
&lt;br /&gt;
Stop VM:&lt;br /&gt;
 qm stop [VMID]&lt;br /&gt;
&lt;br /&gt;
Start VM:&lt;br /&gt;
 qm start [VMID]&lt;br /&gt;
&lt;br /&gt;
=== LCX Container Management ===&lt;br /&gt;
&lt;br /&gt;
 pct - Tool to manage Linux Containers (LXC) on Proxmox VE&lt;br /&gt;
&lt;br /&gt;
List Containers:&lt;br /&gt;
 pct list&lt;br /&gt;
&lt;br /&gt;
Stop Container:&lt;br /&gt;
 pct stop [VMID]&lt;br /&gt;
&lt;br /&gt;
Start Container:&lt;br /&gt;
 pct start [VMID]&lt;br /&gt;
&lt;br /&gt;
== NFS in Container ==&lt;br /&gt;
&lt;br /&gt;
Mark &amp;quot;NFS&amp;quot; in features, but first it will need to be a &amp;quot;Privileged&amp;quot; container.&lt;br /&gt;
&lt;br /&gt;
https://i.imgur.com/PDEvmuJ.png&lt;br /&gt;
&lt;br /&gt;
To convert to Priveleged, simply run a backup, then restore and mark the &amp;quot;priveleged&amp;quot; checkbox.  Pretty easy.&lt;br /&gt;
&lt;br /&gt;
https://i.imgur.com/4MQUFLm.png&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
NFS requires extra permissions to run in a Container (CT), which uses LXC.&lt;br /&gt;
&lt;br /&gt;
Deselect &amp;quot;Unprivileged container&amp;quot;, and add the Features &amp;quot;mount=nfs&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 # mount 192.168.108.30:/nfs/ken /mnt&lt;br /&gt;
 mount.nfs: access denied by server while mounting 192.168.108.30:/nfs/ken&lt;br /&gt;
&lt;br /&gt;
When trying to add the &amp;quot;mount=nfs&amp;quot; feature:&lt;br /&gt;
 Permission check failed (changing feature flags for privileged container is only allowed for root@pam) (403)&lt;br /&gt;
&lt;br /&gt;
Login as root and:&lt;br /&gt;
 pct set 112 -features mount=nfs&lt;br /&gt;
&lt;br /&gt;
 # pct set 112 -features mount=nfs --save  # is this needed?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ref [https://www.jamescoyle.net/how-to/689-mount-nfs-volume-in-a-proxmox-openvz-container] [https://theorangeone.net/posts/mount-nfs-inside-lxc/]&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
== List Data Stores ==&lt;br /&gt;
&lt;br /&gt;
List data stores and status:&lt;br /&gt;
 pvesm status&lt;br /&gt;
&lt;br /&gt;
== HTTPS Redirect ==&lt;br /&gt;
&lt;br /&gt;
To have Proxmox respond on port 443 instead of just on 8006&lt;br /&gt;
&lt;br /&gt;
 /etc/network/interfaces&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
auto vmbr0&lt;br /&gt;
iface vmbr0 inet static&lt;br /&gt;
        address 10.0.0.100/24&lt;br /&gt;
        gateway 10.0.0.1&lt;br /&gt;
        bridge-ports enp3s0&lt;br /&gt;
        bridge-stp off&lt;br /&gt;
        bridge-fd 0&lt;br /&gt;
        mtu 9000&lt;br /&gt;
        post-up iptables -t nat -A PREROUTING -d 10.0.0.100 -p tcp --dport 443 -j REDIRECT --to-port 8006 || true&lt;br /&gt;
iface vmbr0 inet6 auto&lt;br /&gt;
#Public&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 systemctl restart networking&lt;br /&gt;
&lt;br /&gt;
Show:&lt;br /&gt;
 iptables -L -t nat&lt;br /&gt;
&lt;br /&gt;
== Free Subscription Repositories ==&lt;br /&gt;
&lt;br /&gt;
# Disable ceph Enterprise&lt;br /&gt;
# Disable pve-enterprise&lt;br /&gt;
# Add pve-no-subscription repo - &#039;&#039;deb http://download.proxmox.com/debian/pve bookworm pve-no-subscription&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
/etc/apt/sources.list :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
deb http://ftp.us.debian.org/debian bookworm main contrib&lt;br /&gt;
&lt;br /&gt;
deb http://ftp.us.debian.org/debian bookworm-updates main contrib&lt;br /&gt;
&lt;br /&gt;
# security updates&lt;br /&gt;
deb http://security.debian.org bookworm-security main contrib&lt;br /&gt;
&lt;br /&gt;
deb http://download.proxmox.com/debian/pve bookworm pve-no-subscription&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/etc/apt/sources.list.d/ceph.list :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# deb https://enterprise.proxmox.com/debian/ceph-quincy bookworm enterprise&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/etc/apt/sources.list.d/pve-enterprise.list :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# deb https://enterprise.proxmox.com/debian/pve bookworm pve-enterprise&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: this can be configured from the web interface too.&lt;br /&gt;
&lt;br /&gt;
https://i.imgur.com/5zaSWgz.png&lt;br /&gt;
&lt;br /&gt;
== Install sudo ==&lt;br /&gt;
&lt;br /&gt;
 apt update&lt;br /&gt;
 apt install sudo&lt;br /&gt;
&lt;br /&gt;
== LXC - Linux Containers ==&lt;br /&gt;
&lt;br /&gt;
To use the LC options you first need to download a LC template.&lt;br /&gt;
&lt;br /&gt;
First update the list:&lt;br /&gt;
 pveam update&lt;br /&gt;
&lt;br /&gt;
Note: The list of available templates is updated daily through the &#039;&#039;&#039;pve-daily-update&#039;&#039;&#039; timer&lt;br /&gt;
&lt;br /&gt;
To list images:&lt;br /&gt;
 pveam available&lt;br /&gt;
&lt;br /&gt;
To list only system images:&lt;br /&gt;
 pveam available --section system&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
root@proxmox1:~# pveam available --section system&lt;br /&gt;
system          almalinux-9-default_20221108_amd64.tar.xz&lt;br /&gt;
system          alpine-3.18-default_20230607_amd64.tar.xz&lt;br /&gt;
system          archlinux-base_20230608-1_amd64.tar.zst&lt;br /&gt;
system          centos-9-stream-default_20221109_amd64.tar.xz&lt;br /&gt;
system          debian-11-standard_11.7-1_amd64.tar.zst&lt;br /&gt;
system          debian-12-standard_12.2-1_amd64.tar.zst&lt;br /&gt;
system          devuan-4.0-standard_4.0_amd64.tar.gz&lt;br /&gt;
system          fedora-38-default_20230607_amd64.tar.xz&lt;br /&gt;
system          fedora-39-default_20231118_amd64.tar.xz&lt;br /&gt;
system          gentoo-current-openrc_20231009_amd64.tar.xz&lt;br /&gt;
system          opensuse-15.4-default_20221109_amd64.tar.xz&lt;br /&gt;
system          opensuse-15.5-default_20231118_amd64.tar.xz&lt;br /&gt;
system          rockylinux-9-default_20221109_amd64.tar.xz&lt;br /&gt;
system          ubuntu-20.04-standard_20.04-1_amd64.tar.gz&lt;br /&gt;
system          ubuntu-22.04-standard_22.04-1_amd64.tar.zst&lt;br /&gt;
system          ubuntu-23.04-standard_23.04-1_amd64.tar.zst&lt;br /&gt;
system          ubuntu-23.10-standard_23.10-1_amd64.tar.zst&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Download to data store:&lt;br /&gt;
 pveam download mydatastore ubuntu-22.04-standard_22.04-1_amd64.tar.zst&lt;br /&gt;
&lt;br /&gt;
List images on data store:&lt;br /&gt;
 pveam list mydatastore&lt;br /&gt;
&lt;br /&gt;
 # example&lt;br /&gt;
 NAME                                                                 SIZE&lt;br /&gt;
 mydatastore:vztmpl/ubuntu-22.04-standard_22.04-1_amd64.tar.zst       123.81MB&lt;br /&gt;
&lt;br /&gt;
To remove:&lt;br /&gt;
 pveam remove mydatastore:vztmpl/ubuntu-22.04-standard_22.04-1_amd64.tar.zst&lt;br /&gt;
&lt;br /&gt;
See https://pve.proxmox.com/wiki/Linux_Container&lt;br /&gt;
&lt;br /&gt;
== Upgrade Proxmox 7 to Proxmox 8 ==&lt;br /&gt;
&lt;br /&gt;
 Upgrade from 7 to 8 - Proxmox VE&lt;br /&gt;
 https://pve.proxmox.com/wiki/Upgrade_from_7_to_8&lt;br /&gt;
&lt;br /&gt;
Update to latest v7:&lt;br /&gt;
 apt update&lt;br /&gt;
 apt dist-upgrade&lt;br /&gt;
&lt;br /&gt;
Checks:&lt;br /&gt;
 pve7to8&lt;br /&gt;
&lt;br /&gt;
All checks:&lt;br /&gt;
 pve7to8 --full&lt;br /&gt;
&lt;br /&gt;
Switch to Bookworm:&lt;br /&gt;
 sed -i &#039;s/bullseye/bookworm/g&#039; /etc/apt/sources.list&lt;br /&gt;
&lt;br /&gt;
 sed -i &#039;s/bullseye/bookworm/g&#039; /etc/apt/sources.list.d/*&lt;br /&gt;
&lt;br /&gt;
Add VE 8:&lt;br /&gt;
 # echo &amp;quot;deb https://enterprise.proxmox.com/debian/pve bookworm pve-enterprise&amp;quot; &amp;gt; /etc/apt/sources.list.d/pve-enterprise.list&lt;br /&gt;
 sed -i -e &#039;s/bullseye/bookworm/g&#039; /etc/apt/sources.list.d/pve-install-repo.list &lt;br /&gt;
&lt;br /&gt;
Update system to v8:&lt;br /&gt;
 apt update&lt;br /&gt;
 apt dist-upgrade&lt;br /&gt;
&lt;br /&gt;
== Issues ==&lt;br /&gt;
&lt;br /&gt;
=== Suck Backup Job ===&lt;br /&gt;
&lt;br /&gt;
 ps awxf | grep vzdump&lt;br /&gt;
&lt;br /&gt;
Proper way to stop:&lt;br /&gt;
 vzdump -stop&lt;br /&gt;
&lt;br /&gt;
Usually related to mount points &amp;lt;ref&amp;gt;https://forum.proxmox.com/threads/backup-job-is-stuck-and-i-cannot-stop-it-or-even-kill-it.120835/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If that doesn&#039;t work, can kill.  Find process first.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
root@proxmox1:~# ps awxf | grep vzdump&lt;br /&gt;
1305267 pts/0    S+     0:00          \_ grep vzdump&lt;br /&gt;
 916782 ?        Ss     0:02 task UPID:proxmox2:000DFD2E:9A21B1C6:670B61EA:vzdump::root@pam:&lt;br /&gt;
 916789 ?        S      0:00  \_ rsync --stats -h --numeric-ids -aH --delete --no-whole-file --sparse --one-file-system --relative --exclude=/tmp/?* --exclude=/var/tmp/?* --exclude=/var/run/?*.pid /proc/262434/root//./ /mnt/pve/TrueNAS/dump/vzdump-lxc-108-2024_10_13-00_00_10.tmp&lt;br /&gt;
 916790 ?        S      0:00      \_ rsync --stats -h --numeric-ids -aH --delete --no-whole-file --sparse --one-file-system --relative --exclude=/tmp/?* --exclude=/var/tmp/?* --exclude=/var/run/?*.pid /proc/262434/root//./ /mnt/pve/TrueNAS/dump/vzdump-lxc-108-2024_10_13-00_00_10.tmp&lt;br /&gt;
 916791 ?        S      0:00          \_ rsync --stats -h --numeric-ids -aH --delete --no-whole-file --sparse --one-file-system --relative --exclude=/tmp/?* --exclude=/var/tmp/?* --exclude=/var/run/?*.pid /proc/262434/root//./ /mnt/pve/TrueNAS/dump/vzdump-lxc-108-2024_10_13-00_00_10.tmp&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Kill the process ID associated with the task, which should cause it to jump to the next task.&lt;br /&gt;
&lt;br /&gt;
But this seems to leave everything in a locked state for backup&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# kill 916782&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Unlock VM ===&lt;br /&gt;
&lt;br /&gt;
To unlock a VM that is stuck in a locked state:&lt;br /&gt;
 qm unlock 101&lt;br /&gt;
&lt;br /&gt;
see pct for LXCs&lt;br /&gt;
&lt;br /&gt;
=== Unlock LXC Container ===&lt;br /&gt;
&lt;br /&gt;
To unlock a LXC Container that is stuck in a locked state:&lt;br /&gt;
 pct unlock 101&lt;br /&gt;
&lt;br /&gt;
=== ping - Operation not permitted ===&lt;br /&gt;
&lt;br /&gt;
Fix with:&lt;br /&gt;
 setcap cap_net_raw+ep /bin/ping&lt;br /&gt;
&lt;br /&gt;
or:&lt;br /&gt;
 chmod u+s /sbin/ping&lt;br /&gt;
&lt;br /&gt;
&amp;quot;I suspect the setuid workaround would likely work and is how ping was shipped in distros for a very long time (and so not particularly risky).&amp;quot; &amp;lt;ref&amp;gt;https://discuss.linuxcontainers.org/t/ping-is-failing-in-containers-with-ping-socket-operation-not-permitted/14240/4&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ref &amp;lt;ref&amp;gt;Ping with unprivileged user in LXC container / Linux capabilities | Proxmox Support Forum - https://forum.proxmox.com/threads/ping-with-unprivileged-user-in-lxc-container-linux-capabilities.42308/&amp;lt;/ref&amp;gt; &amp;lt;ref&amp;gt;No ping from non root user in Debian Buster LXC | Proxmox Support Forum - https://forum.proxmox.com/threads/no-ping-from-non-root-user-in-debian-buster-lxc.72366/#post-387633&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== sudo - setrlimit(RLIMIT_CORE): Operation not permitted ===&lt;br /&gt;
&lt;br /&gt;
Inside of Ubuntu 20 LXC...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ sudo hello &amp;gt; /dev/null&lt;br /&gt;
sudo: setrlimit(RLIMIT_CORE): Operation not permitted&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bug in sudo version.  Just update sudo.&lt;br /&gt;
&lt;br /&gt;
 apt update&lt;br /&gt;
 apt upgrade sudo&lt;br /&gt;
&lt;br /&gt;
Alt workaround:&lt;br /&gt;
 echo &amp;quot;Set disable_coredump false&amp;quot; &amp;gt;&amp;gt; /etc/sudo.conf&lt;br /&gt;
&lt;br /&gt;
ref &amp;lt;ref&amp;gt;https://github.com/sudo-project/sudo/issues/42&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
{{ref}}&lt;br /&gt;
&lt;br /&gt;
== keywords ==&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=Proxmox&amp;diff=9854</id>
		<title>Proxmox</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=Proxmox&amp;diff=9854"/>
		<updated>2026-04-22T17:53:55Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: /* List Data Stores */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Subpages ==&lt;br /&gt;
&lt;br /&gt;
{{subpages}}&lt;br /&gt;
&lt;br /&gt;
== Get Version from Command Line ==&lt;br /&gt;
&lt;br /&gt;
 pveversion&lt;br /&gt;
&lt;br /&gt;
 pveversion --verbose&lt;br /&gt;
&lt;br /&gt;
== Sync Config Manually ==&lt;br /&gt;
&lt;br /&gt;
 corosync&lt;br /&gt;
&lt;br /&gt;
== Virtualization Management ==&lt;br /&gt;
&lt;br /&gt;
Virtual Machines vs Containers&lt;br /&gt;
&lt;br /&gt;
Proxmox can create and manage both fully-fledged Virtual Machines (VMs) and light-weight Linux Containers (LCX).&lt;br /&gt;
&lt;br /&gt;
=== VM Managemnet ===&lt;br /&gt;
&lt;br /&gt;
 qm - QEMU/KVM Virtual Machine Manager&lt;br /&gt;
&lt;br /&gt;
List VMs:&lt;br /&gt;
 qm list&lt;br /&gt;
&lt;br /&gt;
Stop VM:&lt;br /&gt;
 qm stop [VMID]&lt;br /&gt;
&lt;br /&gt;
Start VM:&lt;br /&gt;
 qm start [VMID]&lt;br /&gt;
&lt;br /&gt;
=== LCX Container Management ===&lt;br /&gt;
&lt;br /&gt;
 pct - Tool to manage Linux Containers (LXC) on Proxmox VE&lt;br /&gt;
&lt;br /&gt;
List Containers:&lt;br /&gt;
 pct list&lt;br /&gt;
&lt;br /&gt;
Stop Container:&lt;br /&gt;
 pct stop [VMID]&lt;br /&gt;
&lt;br /&gt;
Start Container:&lt;br /&gt;
 pct start [VMID]&lt;br /&gt;
&lt;br /&gt;
== NFS in Container ==&lt;br /&gt;
&lt;br /&gt;
Mark &amp;quot;NFS&amp;quot; in features, but first it will need to be a &amp;quot;Privileged&amp;quot; container.&lt;br /&gt;
&lt;br /&gt;
https://i.imgur.com/PDEvmuJ.png&lt;br /&gt;
&lt;br /&gt;
To convert to Priveleged, simply run a backup, then restore and mark the &amp;quot;priveleged&amp;quot; checkbox.  Pretty easy.&lt;br /&gt;
&lt;br /&gt;
https://i.imgur.com/4MQUFLm.png&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
NFS requires extra permissions to run in a Container (CT), which uses LXC.&lt;br /&gt;
&lt;br /&gt;
Deselect &amp;quot;Unprivileged container&amp;quot;, and add the Features &amp;quot;mount=nfs&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 # mount 192.168.108.30:/nfs/ken /mnt&lt;br /&gt;
 mount.nfs: access denied by server while mounting 192.168.108.30:/nfs/ken&lt;br /&gt;
&lt;br /&gt;
When trying to add the &amp;quot;mount=nfs&amp;quot; feature:&lt;br /&gt;
 Permission check failed (changing feature flags for privileged container is only allowed for root@pam) (403)&lt;br /&gt;
&lt;br /&gt;
Login as root and:&lt;br /&gt;
 pct set 112 -features mount=nfs&lt;br /&gt;
&lt;br /&gt;
 # pct set 112 -features mount=nfs --save  # is this needed?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ref [https://www.jamescoyle.net/how-to/689-mount-nfs-volume-in-a-proxmox-openvz-container] [https://theorangeone.net/posts/mount-nfs-inside-lxc/]&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
== List Data Stores ==&lt;br /&gt;
&lt;br /&gt;
List data stores and status:&lt;br /&gt;
 pvesm status&lt;br /&gt;
&lt;br /&gt;
== HTTPS Redirect ==&lt;br /&gt;
&lt;br /&gt;
To have Proxmox respond on port 443 instead of just on 8006&lt;br /&gt;
&lt;br /&gt;
 /etc/network/interfaces&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
auto vmbr0&lt;br /&gt;
iface vmbr0 inet static&lt;br /&gt;
        address 10.0.0.100/24&lt;br /&gt;
        gateway 10.0.0.1&lt;br /&gt;
        bridge-ports enp3s0&lt;br /&gt;
        bridge-stp off&lt;br /&gt;
        bridge-fd 0&lt;br /&gt;
        mtu 9000&lt;br /&gt;
        post-up iptables -t nat -A PREROUTING -d 10.0.0.100 -p tcp --dport 443 -j REDIRECT --to-port 8006 || true&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Show:&lt;br /&gt;
 iptables -L -t nat&lt;br /&gt;
&lt;br /&gt;
== Free Subscription Repositories ==&lt;br /&gt;
&lt;br /&gt;
# Disable ceph Enterprise&lt;br /&gt;
# Disable pve-enterprise&lt;br /&gt;
# Add pve-no-subscription repo - &#039;&#039;deb http://download.proxmox.com/debian/pve bookworm pve-no-subscription&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
/etc/apt/sources.list :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
deb http://ftp.us.debian.org/debian bookworm main contrib&lt;br /&gt;
&lt;br /&gt;
deb http://ftp.us.debian.org/debian bookworm-updates main contrib&lt;br /&gt;
&lt;br /&gt;
# security updates&lt;br /&gt;
deb http://security.debian.org bookworm-security main contrib&lt;br /&gt;
&lt;br /&gt;
deb http://download.proxmox.com/debian/pve bookworm pve-no-subscription&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/etc/apt/sources.list.d/ceph.list :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# deb https://enterprise.proxmox.com/debian/ceph-quincy bookworm enterprise&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/etc/apt/sources.list.d/pve-enterprise.list :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# deb https://enterprise.proxmox.com/debian/pve bookworm pve-enterprise&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: this can be configured from the web interface too.&lt;br /&gt;
&lt;br /&gt;
https://i.imgur.com/5zaSWgz.png&lt;br /&gt;
&lt;br /&gt;
== Install sudo ==&lt;br /&gt;
&lt;br /&gt;
 apt update&lt;br /&gt;
 apt install sudo&lt;br /&gt;
&lt;br /&gt;
== LXC - Linux Containers ==&lt;br /&gt;
&lt;br /&gt;
To use the LC options you first need to download a LC template.&lt;br /&gt;
&lt;br /&gt;
First update the list:&lt;br /&gt;
 pveam update&lt;br /&gt;
&lt;br /&gt;
Note: The list of available templates is updated daily through the &#039;&#039;&#039;pve-daily-update&#039;&#039;&#039; timer&lt;br /&gt;
&lt;br /&gt;
To list images:&lt;br /&gt;
 pveam available&lt;br /&gt;
&lt;br /&gt;
To list only system images:&lt;br /&gt;
 pveam available --section system&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
root@proxmox1:~# pveam available --section system&lt;br /&gt;
system          almalinux-9-default_20221108_amd64.tar.xz&lt;br /&gt;
system          alpine-3.18-default_20230607_amd64.tar.xz&lt;br /&gt;
system          archlinux-base_20230608-1_amd64.tar.zst&lt;br /&gt;
system          centos-9-stream-default_20221109_amd64.tar.xz&lt;br /&gt;
system          debian-11-standard_11.7-1_amd64.tar.zst&lt;br /&gt;
system          debian-12-standard_12.2-1_amd64.tar.zst&lt;br /&gt;
system          devuan-4.0-standard_4.0_amd64.tar.gz&lt;br /&gt;
system          fedora-38-default_20230607_amd64.tar.xz&lt;br /&gt;
system          fedora-39-default_20231118_amd64.tar.xz&lt;br /&gt;
system          gentoo-current-openrc_20231009_amd64.tar.xz&lt;br /&gt;
system          opensuse-15.4-default_20221109_amd64.tar.xz&lt;br /&gt;
system          opensuse-15.5-default_20231118_amd64.tar.xz&lt;br /&gt;
system          rockylinux-9-default_20221109_amd64.tar.xz&lt;br /&gt;
system          ubuntu-20.04-standard_20.04-1_amd64.tar.gz&lt;br /&gt;
system          ubuntu-22.04-standard_22.04-1_amd64.tar.zst&lt;br /&gt;
system          ubuntu-23.04-standard_23.04-1_amd64.tar.zst&lt;br /&gt;
system          ubuntu-23.10-standard_23.10-1_amd64.tar.zst&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Download to data store:&lt;br /&gt;
 pveam download mydatastore ubuntu-22.04-standard_22.04-1_amd64.tar.zst&lt;br /&gt;
&lt;br /&gt;
List images on data store:&lt;br /&gt;
 pveam list mydatastore&lt;br /&gt;
&lt;br /&gt;
 # example&lt;br /&gt;
 NAME                                                                 SIZE&lt;br /&gt;
 mydatastore:vztmpl/ubuntu-22.04-standard_22.04-1_amd64.tar.zst       123.81MB&lt;br /&gt;
&lt;br /&gt;
To remove:&lt;br /&gt;
 pveam remove mydatastore:vztmpl/ubuntu-22.04-standard_22.04-1_amd64.tar.zst&lt;br /&gt;
&lt;br /&gt;
See https://pve.proxmox.com/wiki/Linux_Container&lt;br /&gt;
&lt;br /&gt;
== Upgrade Proxmox 7 to Proxmox 8 ==&lt;br /&gt;
&lt;br /&gt;
 Upgrade from 7 to 8 - Proxmox VE&lt;br /&gt;
 https://pve.proxmox.com/wiki/Upgrade_from_7_to_8&lt;br /&gt;
&lt;br /&gt;
Update to latest v7:&lt;br /&gt;
 apt update&lt;br /&gt;
 apt dist-upgrade&lt;br /&gt;
&lt;br /&gt;
Checks:&lt;br /&gt;
 pve7to8&lt;br /&gt;
&lt;br /&gt;
All checks:&lt;br /&gt;
 pve7to8 --full&lt;br /&gt;
&lt;br /&gt;
Switch to Bookworm:&lt;br /&gt;
 sed -i &#039;s/bullseye/bookworm/g&#039; /etc/apt/sources.list&lt;br /&gt;
&lt;br /&gt;
 sed -i &#039;s/bullseye/bookworm/g&#039; /etc/apt/sources.list.d/*&lt;br /&gt;
&lt;br /&gt;
Add VE 8:&lt;br /&gt;
 # echo &amp;quot;deb https://enterprise.proxmox.com/debian/pve bookworm pve-enterprise&amp;quot; &amp;gt; /etc/apt/sources.list.d/pve-enterprise.list&lt;br /&gt;
 sed -i -e &#039;s/bullseye/bookworm/g&#039; /etc/apt/sources.list.d/pve-install-repo.list &lt;br /&gt;
&lt;br /&gt;
Update system to v8:&lt;br /&gt;
 apt update&lt;br /&gt;
 apt dist-upgrade&lt;br /&gt;
&lt;br /&gt;
== Issues ==&lt;br /&gt;
&lt;br /&gt;
=== Suck Backup Job ===&lt;br /&gt;
&lt;br /&gt;
 ps awxf | grep vzdump&lt;br /&gt;
&lt;br /&gt;
Proper way to stop:&lt;br /&gt;
 vzdump -stop&lt;br /&gt;
&lt;br /&gt;
Usually related to mount points &amp;lt;ref&amp;gt;https://forum.proxmox.com/threads/backup-job-is-stuck-and-i-cannot-stop-it-or-even-kill-it.120835/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If that doesn&#039;t work, can kill.  Find process first.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
root@proxmox1:~# ps awxf | grep vzdump&lt;br /&gt;
1305267 pts/0    S+     0:00          \_ grep vzdump&lt;br /&gt;
 916782 ?        Ss     0:02 task UPID:proxmox2:000DFD2E:9A21B1C6:670B61EA:vzdump::root@pam:&lt;br /&gt;
 916789 ?        S      0:00  \_ rsync --stats -h --numeric-ids -aH --delete --no-whole-file --sparse --one-file-system --relative --exclude=/tmp/?* --exclude=/var/tmp/?* --exclude=/var/run/?*.pid /proc/262434/root//./ /mnt/pve/TrueNAS/dump/vzdump-lxc-108-2024_10_13-00_00_10.tmp&lt;br /&gt;
 916790 ?        S      0:00      \_ rsync --stats -h --numeric-ids -aH --delete --no-whole-file --sparse --one-file-system --relative --exclude=/tmp/?* --exclude=/var/tmp/?* --exclude=/var/run/?*.pid /proc/262434/root//./ /mnt/pve/TrueNAS/dump/vzdump-lxc-108-2024_10_13-00_00_10.tmp&lt;br /&gt;
 916791 ?        S      0:00          \_ rsync --stats -h --numeric-ids -aH --delete --no-whole-file --sparse --one-file-system --relative --exclude=/tmp/?* --exclude=/var/tmp/?* --exclude=/var/run/?*.pid /proc/262434/root//./ /mnt/pve/TrueNAS/dump/vzdump-lxc-108-2024_10_13-00_00_10.tmp&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Kill the process ID associated with the task, which should cause it to jump to the next task.&lt;br /&gt;
&lt;br /&gt;
But this seems to leave everything in a locked state for backup&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# kill 916782&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Unlock VM ===&lt;br /&gt;
&lt;br /&gt;
To unlock a VM that is stuck in a locked state:&lt;br /&gt;
 qm unlock 101&lt;br /&gt;
&lt;br /&gt;
see pct for LXCs&lt;br /&gt;
&lt;br /&gt;
=== Unlock LXC Container ===&lt;br /&gt;
&lt;br /&gt;
To unlock a LXC Container that is stuck in a locked state:&lt;br /&gt;
 pct unlock 101&lt;br /&gt;
&lt;br /&gt;
=== ping - Operation not permitted ===&lt;br /&gt;
&lt;br /&gt;
Fix with:&lt;br /&gt;
 setcap cap_net_raw+ep /bin/ping&lt;br /&gt;
&lt;br /&gt;
or:&lt;br /&gt;
 chmod u+s /sbin/ping&lt;br /&gt;
&lt;br /&gt;
&amp;quot;I suspect the setuid workaround would likely work and is how ping was shipped in distros for a very long time (and so not particularly risky).&amp;quot; &amp;lt;ref&amp;gt;https://discuss.linuxcontainers.org/t/ping-is-failing-in-containers-with-ping-socket-operation-not-permitted/14240/4&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ref &amp;lt;ref&amp;gt;Ping with unprivileged user in LXC container / Linux capabilities | Proxmox Support Forum - https://forum.proxmox.com/threads/ping-with-unprivileged-user-in-lxc-container-linux-capabilities.42308/&amp;lt;/ref&amp;gt; &amp;lt;ref&amp;gt;No ping from non root user in Debian Buster LXC | Proxmox Support Forum - https://forum.proxmox.com/threads/no-ping-from-non-root-user-in-debian-buster-lxc.72366/#post-387633&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== sudo - setrlimit(RLIMIT_CORE): Operation not permitted ===&lt;br /&gt;
&lt;br /&gt;
Inside of Ubuntu 20 LXC...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ sudo hello &amp;gt; /dev/null&lt;br /&gt;
sudo: setrlimit(RLIMIT_CORE): Operation not permitted&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bug in sudo version.  Just update sudo.&lt;br /&gt;
&lt;br /&gt;
 apt update&lt;br /&gt;
 apt upgrade sudo&lt;br /&gt;
&lt;br /&gt;
Alt workaround:&lt;br /&gt;
 echo &amp;quot;Set disable_coredump false&amp;quot; &amp;gt;&amp;gt; /etc/sudo.conf&lt;br /&gt;
&lt;br /&gt;
ref &amp;lt;ref&amp;gt;https://github.com/sudo-project/sudo/issues/42&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
{{ref}}&lt;br /&gt;
&lt;br /&gt;
== keywords ==&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=Firefox&amp;diff=9853</id>
		<title>Firefox</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=Firefox&amp;diff=9853"/>
		<updated>2026-04-22T06:29:40Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: /* New Process */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{subpages}}&lt;br /&gt;
&lt;br /&gt;
== New Installation Configuration ==&lt;br /&gt;
&lt;br /&gt;
Options - Downloads&lt;br /&gt;
* [X] Show the Downloads window when downloading a file&lt;br /&gt;
** [X] Close it when all downloads are finished&lt;br /&gt;
* [*] Always ask me where to save files&lt;br /&gt;
&lt;br /&gt;
about:config&lt;br /&gt;
* layout.spellcheckDefault = 2   # spell check any field&lt;br /&gt;
* browser.tabs.insertRelatedAfterCurrent = false  # new tabs at end&lt;br /&gt;
&lt;br /&gt;
Extentions:&lt;br /&gt;
* [https://addons.mozilla.org/en-US/firefox/addon/1865 Adblock Plus]&lt;br /&gt;
* [https://addons.mozilla.org/en-US/firefox/addon/2324 Session Manager]&lt;br /&gt;
&lt;br /&gt;
== Show Bookmarks in New Tab Page ==&lt;br /&gt;
&lt;br /&gt;
To show bookmarks on new tab page&lt;br /&gt;
&lt;br /&gt;
1) Add Stylish addon:&lt;br /&gt;
&lt;br /&gt;
https://addons.mozilla.org/en-US/firefox/addon/stylish/?src=external-userstyleshome&lt;br /&gt;
&lt;br /&gt;
2) Add &amp;quot;Show BookMark bar only on new tab page addon:&lt;br /&gt;
&lt;br /&gt;
https://userstyles.org/styles/125737/show-bookmark-bar-only-on-new-tab-page&lt;br /&gt;
&lt;br /&gt;
Note: The new tab page doesn&#039;t have a URL, so the style won&#039;t work, so let&#039;s fix that:&lt;br /&gt;
&lt;br /&gt;
3) add New Tab Override addon:&lt;br /&gt;
&lt;br /&gt;
https://addons.mozilla.org/en-US/firefox/addon/new-tab-override/developers&lt;br /&gt;
&lt;br /&gt;
4) Set url to something:&lt;br /&gt;
&lt;br /&gt;
 http://www.google.com&lt;br /&gt;
&lt;br /&gt;
 about:blank&lt;br /&gt;
&lt;br /&gt;
https://support.mozilla.org/en-US/questions/971018&lt;br /&gt;
 chrome://browser/content/bookmarks/bookmarksPanel.xul&lt;br /&gt;
&lt;br /&gt;
5) Modify the style to include this new url: (from manage stylish styles)&lt;br /&gt;
&lt;br /&gt;
 :not([stylish-url=&amp;quot;https://www.google.com/&amp;quot;])&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
@namespace url(http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul);&lt;br /&gt;
&lt;br /&gt;
#main-window:not([stylish-url^=&amp;quot;about:&amp;quot;]):not([stylish-url^=&amp;quot;chrome:&amp;quot;]):not([stylish-url=&amp;quot;https://www.google.com/&amp;quot;]) #PersonalToolbar&lt;br /&gt;
{&lt;br /&gt;
  display : none !important;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== spell check any field ==&lt;br /&gt;
&lt;br /&gt;
Source: [http://joshhighland.com/blog/2007/07/17/firefox-spell-check-any-field/ Firefox: spell check any field | Josh Highland&#039;s Blog]&lt;br /&gt;
&lt;br /&gt;
1. type this in the browser address bar “about:config”&lt;br /&gt;
&lt;br /&gt;
2. look for “layout.spellcheckDefault”&lt;br /&gt;
&lt;br /&gt;
3. change the value to “2″&lt;br /&gt;
&lt;br /&gt;
4. restart firefox&lt;br /&gt;
&lt;br /&gt;
== Spell Check Dictionary ==&lt;br /&gt;
&lt;br /&gt;
Custom user dictionary:&lt;br /&gt;
 %APPDATA%\Mozilla\Firefox\Profiles\[PROFILE]\persdict.dat&lt;br /&gt;
&lt;br /&gt;
Remove misspelled words from your Firefox dictionary - http://lifehacker.com/244497/remove-misspelled-words-from-your-firefox-dictionary&lt;br /&gt;
&lt;br /&gt;
== New Tab Order ==&lt;br /&gt;
&lt;br /&gt;
 browser.tabs.insertRelatedAfterCurrent = false&lt;br /&gt;
&lt;br /&gt;
== Security on Opening Local File Links ==&lt;br /&gt;
&lt;br /&gt;
prefs.js\prefs.js:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
user_pref(&amp;quot;capability.policy.localfilelinks.checkloaduri.enabled&amp;quot;, &amp;quot;allAccess&amp;quot;);&lt;br /&gt;
user_pref(&amp;quot;capability.policy.localfilelinks.sites&amp;quot;, &amp;quot;http://tivo.t0e.org http://tivo&amp;quot;);&lt;br /&gt;
user_pref(&amp;quot;capability.policy.policynames&amp;quot;, &amp;quot;localfilelinks&amp;quot;);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[http://kb.mozillazine.org/Links_to_local_pages_don%27t_work Links to local pages do not work - MozillaZine Knowledge Base]:&lt;br /&gt;
* LocalLink&lt;br /&gt;
** &amp;quot;The LocalLink extension allows overriding the security check per click: links to local pages can be followed using the context menu for the link.&amp;quot;&lt;br /&gt;
* Firefox 1.5, SeaMonkey 1.0 and newer&lt;br /&gt;
** &amp;quot;In the most recent versions of these browsers, the old global preference has been removed. Instead, the checkloaduri preference has been combined with the CAPS interface so you can change the setting on a per-site basis with Security Policies. For example, to allow a certain domain to bypass the checkloaduri restriction, this could be  added to user.js or prefs.js:&amp;quot;&lt;br /&gt;
 user_pref(&amp;quot;capability.policy.policynames&amp;quot;, &amp;quot;localfilelinks&amp;quot;);&lt;br /&gt;
 user_pref(&amp;quot;capability.policy.localfilelinks.sites&amp;quot;, &amp;quot;http://www.example.com&amp;quot;);&lt;br /&gt;
 user_pref(&amp;quot;capability.policy.localfilelinks.checkloaduri.enabled&amp;quot;, &amp;quot;allAccess&amp;quot;);&lt;br /&gt;
* UNC Paths&lt;br /&gt;
** &amp;quot;If you&#039;re linking to a file in a UNC path (e.g., \\servername\share\file.ext), you will need to specify the path thusly:&amp;quot;&lt;br /&gt;
 file://///servername/share/file.ext&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[http://locallink.mozdev.org/ mozdev.org - locallink: index]&lt;br /&gt;
*[https://addons.mozilla.org/en-US/firefox/addon/281 LocalLink :: Firefox Add-ons]&lt;br /&gt;
&lt;br /&gt;
== Profiles ==&lt;br /&gt;
&lt;br /&gt;
 about:profiles&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== New Process ==&lt;br /&gt;
&lt;br /&gt;
Windows:&lt;br /&gt;
 set MOZ_NO_REMOTE=1&lt;br /&gt;
 firefox -ProfileManager&lt;br /&gt;
&lt;br /&gt;
Linux running bash:&lt;br /&gt;
 export MOZ_NO_REMOTE=1&lt;br /&gt;
 firefox -ProfileManager&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 MOZ_NO_REMOTE=1&lt;br /&gt;
 firefox -ProfileManager&lt;br /&gt;
&lt;br /&gt;
 firefox -ProfileManager -no-remote&lt;br /&gt;
&lt;br /&gt;
* Start Firefox in a separate process - http://www.bluishcoder.co.nz/articles/mozilla/firefox-no-remote.html&lt;br /&gt;
* Is there a way to force Firefox to launch in a new process? - Stack Overflow - http://stackoverflow.com/questions/345281/is-there-a-way-to-force-firefox-to-launch-in-a-new-process&lt;br /&gt;
* Firefox in separate processes - Ubuntu Forums - http://ubuntuforums.org/showthread.php?t=698090&lt;br /&gt;
&lt;br /&gt;
== DSOCKS ==&lt;br /&gt;
&lt;br /&gt;
See [[SSH#SSH-D Proxy]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Secure Firefox traffic (+DNS) through SOCKS proxy [http://superuser.com/questions/156916/how-to-secure-firefox-traffic-dns-through-socks-proxy-under-ubuntu-10-04]&lt;br /&gt;
 about:config&lt;br /&gt;
   network.proxy.socks_remote_dns;true&lt;br /&gt;
&lt;br /&gt;
==  SSL Exceptions ==&lt;br /&gt;
&lt;br /&gt;
Check the Servers tab in the Certificate Manager?&lt;br /&gt;
&lt;br /&gt;
    Edit &amp;gt; Preferences &amp;gt; Advanced &amp;gt; Certificates: View Certificates&lt;br /&gt;
&lt;br /&gt;
== SSO Trust ==&lt;br /&gt;
&lt;br /&gt;
 about:config&lt;br /&gt;
  network.negotiate-auth.trusted-uris&lt;br /&gt;
    example.com&lt;br /&gt;
  # maybe:&lt;br /&gt;
  network.automatic-ntlm-auth.trusted-uris&lt;br /&gt;
    example.com&lt;br /&gt;
&lt;br /&gt;
== keywords ==&lt;br /&gt;
&lt;br /&gt;
[[Category:Microsoft]]&lt;br /&gt;
[[Category:Network Admin]]&lt;br /&gt;
[[Category:Tools]]&lt;br /&gt;
[[Category:Linux]]&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=Firefox&amp;diff=9852</id>
		<title>Firefox</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=Firefox&amp;diff=9852"/>
		<updated>2026-04-21T17:46:37Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: /* SSL Exceptions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{subpages}}&lt;br /&gt;
&lt;br /&gt;
== New Installation Configuration ==&lt;br /&gt;
&lt;br /&gt;
Options - Downloads&lt;br /&gt;
* [X] Show the Downloads window when downloading a file&lt;br /&gt;
** [X] Close it when all downloads are finished&lt;br /&gt;
* [*] Always ask me where to save files&lt;br /&gt;
&lt;br /&gt;
about:config&lt;br /&gt;
* layout.spellcheckDefault = 2   # spell check any field&lt;br /&gt;
* browser.tabs.insertRelatedAfterCurrent = false  # new tabs at end&lt;br /&gt;
&lt;br /&gt;
Extentions:&lt;br /&gt;
* [https://addons.mozilla.org/en-US/firefox/addon/1865 Adblock Plus]&lt;br /&gt;
* [https://addons.mozilla.org/en-US/firefox/addon/2324 Session Manager]&lt;br /&gt;
&lt;br /&gt;
== Show Bookmarks in New Tab Page ==&lt;br /&gt;
&lt;br /&gt;
To show bookmarks on new tab page&lt;br /&gt;
&lt;br /&gt;
1) Add Stylish addon:&lt;br /&gt;
&lt;br /&gt;
https://addons.mozilla.org/en-US/firefox/addon/stylish/?src=external-userstyleshome&lt;br /&gt;
&lt;br /&gt;
2) Add &amp;quot;Show BookMark bar only on new tab page addon:&lt;br /&gt;
&lt;br /&gt;
https://userstyles.org/styles/125737/show-bookmark-bar-only-on-new-tab-page&lt;br /&gt;
&lt;br /&gt;
Note: The new tab page doesn&#039;t have a URL, so the style won&#039;t work, so let&#039;s fix that:&lt;br /&gt;
&lt;br /&gt;
3) add New Tab Override addon:&lt;br /&gt;
&lt;br /&gt;
https://addons.mozilla.org/en-US/firefox/addon/new-tab-override/developers&lt;br /&gt;
&lt;br /&gt;
4) Set url to something:&lt;br /&gt;
&lt;br /&gt;
 http://www.google.com&lt;br /&gt;
&lt;br /&gt;
 about:blank&lt;br /&gt;
&lt;br /&gt;
https://support.mozilla.org/en-US/questions/971018&lt;br /&gt;
 chrome://browser/content/bookmarks/bookmarksPanel.xul&lt;br /&gt;
&lt;br /&gt;
5) Modify the style to include this new url: (from manage stylish styles)&lt;br /&gt;
&lt;br /&gt;
 :not([stylish-url=&amp;quot;https://www.google.com/&amp;quot;])&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
@namespace url(http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul);&lt;br /&gt;
&lt;br /&gt;
#main-window:not([stylish-url^=&amp;quot;about:&amp;quot;]):not([stylish-url^=&amp;quot;chrome:&amp;quot;]):not([stylish-url=&amp;quot;https://www.google.com/&amp;quot;]) #PersonalToolbar&lt;br /&gt;
{&lt;br /&gt;
  display : none !important;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== spell check any field ==&lt;br /&gt;
&lt;br /&gt;
Source: [http://joshhighland.com/blog/2007/07/17/firefox-spell-check-any-field/ Firefox: spell check any field | Josh Highland&#039;s Blog]&lt;br /&gt;
&lt;br /&gt;
1. type this in the browser address bar “about:config”&lt;br /&gt;
&lt;br /&gt;
2. look for “layout.spellcheckDefault”&lt;br /&gt;
&lt;br /&gt;
3. change the value to “2″&lt;br /&gt;
&lt;br /&gt;
4. restart firefox&lt;br /&gt;
&lt;br /&gt;
== Spell Check Dictionary ==&lt;br /&gt;
&lt;br /&gt;
Custom user dictionary:&lt;br /&gt;
 %APPDATA%\Mozilla\Firefox\Profiles\[PROFILE]\persdict.dat&lt;br /&gt;
&lt;br /&gt;
Remove misspelled words from your Firefox dictionary - http://lifehacker.com/244497/remove-misspelled-words-from-your-firefox-dictionary&lt;br /&gt;
&lt;br /&gt;
== New Tab Order ==&lt;br /&gt;
&lt;br /&gt;
 browser.tabs.insertRelatedAfterCurrent = false&lt;br /&gt;
&lt;br /&gt;
== Security on Opening Local File Links ==&lt;br /&gt;
&lt;br /&gt;
prefs.js\prefs.js:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
user_pref(&amp;quot;capability.policy.localfilelinks.checkloaduri.enabled&amp;quot;, &amp;quot;allAccess&amp;quot;);&lt;br /&gt;
user_pref(&amp;quot;capability.policy.localfilelinks.sites&amp;quot;, &amp;quot;http://tivo.t0e.org http://tivo&amp;quot;);&lt;br /&gt;
user_pref(&amp;quot;capability.policy.policynames&amp;quot;, &amp;quot;localfilelinks&amp;quot;);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[http://kb.mozillazine.org/Links_to_local_pages_don%27t_work Links to local pages do not work - MozillaZine Knowledge Base]:&lt;br /&gt;
* LocalLink&lt;br /&gt;
** &amp;quot;The LocalLink extension allows overriding the security check per click: links to local pages can be followed using the context menu for the link.&amp;quot;&lt;br /&gt;
* Firefox 1.5, SeaMonkey 1.0 and newer&lt;br /&gt;
** &amp;quot;In the most recent versions of these browsers, the old global preference has been removed. Instead, the checkloaduri preference has been combined with the CAPS interface so you can change the setting on a per-site basis with Security Policies. For example, to allow a certain domain to bypass the checkloaduri restriction, this could be  added to user.js or prefs.js:&amp;quot;&lt;br /&gt;
 user_pref(&amp;quot;capability.policy.policynames&amp;quot;, &amp;quot;localfilelinks&amp;quot;);&lt;br /&gt;
 user_pref(&amp;quot;capability.policy.localfilelinks.sites&amp;quot;, &amp;quot;http://www.example.com&amp;quot;);&lt;br /&gt;
 user_pref(&amp;quot;capability.policy.localfilelinks.checkloaduri.enabled&amp;quot;, &amp;quot;allAccess&amp;quot;);&lt;br /&gt;
* UNC Paths&lt;br /&gt;
** &amp;quot;If you&#039;re linking to a file in a UNC path (e.g., \\servername\share\file.ext), you will need to specify the path thusly:&amp;quot;&lt;br /&gt;
 file://///servername/share/file.ext&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[http://locallink.mozdev.org/ mozdev.org - locallink: index]&lt;br /&gt;
*[https://addons.mozilla.org/en-US/firefox/addon/281 LocalLink :: Firefox Add-ons]&lt;br /&gt;
&lt;br /&gt;
== New Process ==&lt;br /&gt;
&lt;br /&gt;
Windows:&lt;br /&gt;
 set MOZ_NO_REMOTE=1&lt;br /&gt;
 firefox -ProfileManager&lt;br /&gt;
&lt;br /&gt;
Linux running bash:&lt;br /&gt;
 export MOZ_NO_REMOTE=1&lt;br /&gt;
 firefox -ProfileManager&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 MOZ_NO_REMOTE=1&lt;br /&gt;
 firefox -ProfileManager&lt;br /&gt;
&lt;br /&gt;
 firefox -ProfileManager -no-remote&lt;br /&gt;
&lt;br /&gt;
* Start Firefox in a separate process - http://www.bluishcoder.co.nz/articles/mozilla/firefox-no-remote.html&lt;br /&gt;
* Is there a way to force Firefox to launch in a new process? - Stack Overflow - http://stackoverflow.com/questions/345281/is-there-a-way-to-force-firefox-to-launch-in-a-new-process&lt;br /&gt;
* Firefox in separate processes - Ubuntu Forums - http://ubuntuforums.org/showthread.php?t=698090&lt;br /&gt;
&lt;br /&gt;
== DSOCKS ==&lt;br /&gt;
&lt;br /&gt;
See [[SSH#SSH-D Proxy]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Secure Firefox traffic (+DNS) through SOCKS proxy [http://superuser.com/questions/156916/how-to-secure-firefox-traffic-dns-through-socks-proxy-under-ubuntu-10-04]&lt;br /&gt;
 about:config&lt;br /&gt;
   network.proxy.socks_remote_dns;true&lt;br /&gt;
&lt;br /&gt;
==  SSL Exceptions ==&lt;br /&gt;
&lt;br /&gt;
Check the Servers tab in the Certificate Manager?&lt;br /&gt;
&lt;br /&gt;
    Edit &amp;gt; Preferences &amp;gt; Advanced &amp;gt; Certificates: View Certificates&lt;br /&gt;
&lt;br /&gt;
== SSO Trust ==&lt;br /&gt;
&lt;br /&gt;
 about:config&lt;br /&gt;
  network.negotiate-auth.trusted-uris&lt;br /&gt;
    example.com&lt;br /&gt;
  # maybe:&lt;br /&gt;
  network.automatic-ntlm-auth.trusted-uris&lt;br /&gt;
    example.com&lt;br /&gt;
&lt;br /&gt;
== keywords ==&lt;br /&gt;
&lt;br /&gt;
[[Category:Microsoft]]&lt;br /&gt;
[[Category:Network Admin]]&lt;br /&gt;
[[Category:Tools]]&lt;br /&gt;
[[Category:Linux]]&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=Linux/patch&amp;diff=9851</id>
		<title>Linux/patch</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=Linux/patch&amp;diff=9851"/>
		<updated>2026-04-21T16:34:16Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== patch and diff ==&lt;br /&gt;
&lt;br /&gt;
=== diff from another directory ===&lt;br /&gt;
&lt;br /&gt;
no built in method, so have to get tricky&lt;br /&gt;
&lt;br /&gt;
Files for test:&lt;br /&gt;
* test.original&lt;br /&gt;
* test.fixed&lt;br /&gt;
* test  # target file&lt;br /&gt;
&lt;br /&gt;
==== Option #1 - move to correct path manually ====&lt;br /&gt;
 cd ~/test ; cp test.fixed test&lt;br /&gt;
 cd .. ; diff -u test/test.original test/test | tee test.patch&lt;br /&gt;
 #  --- test/test.original  2026-04-21 09:20:42.864135487 -0700&lt;br /&gt;
 #  +++ test/test   2026-04-21 09:20:56.014023558 -0700&lt;br /&gt;
&lt;br /&gt;
 # Then if could be used like:&lt;br /&gt;
 cp test/test.original test/test&lt;br /&gt;
 cat test.patch | patch -d . -p0&lt;br /&gt;
 #  patching file test/test&lt;br /&gt;
&lt;br /&gt;
==== Option #2 - use the -pX to drop path components ====&lt;br /&gt;
 cd ~/test ; cp test.fixed test&lt;br /&gt;
 diff -u ../test/test.original ../test/test | tee test.patch&lt;br /&gt;
 #  --- ../test/test.original       2026-04-21 09:20:42.864135487 -0700&lt;br /&gt;
 #  +++ ../test/test        2026-04-21 09:25:49.926535912 -0700&lt;br /&gt;
&lt;br /&gt;
 # Then if could be used like:&lt;br /&gt;
 cp test.original test&lt;br /&gt;
 cat test.patch | patch -d .. -p1  # p1 drops first path component&lt;br /&gt;
 #  patching file test/test&lt;br /&gt;
 # Alternative would be to edit the patch file and remove the &amp;quot;../&amp;quot; from the header&lt;br /&gt;
&lt;br /&gt;
==== Option #3 - edit the header ====&lt;br /&gt;
 cd ~/test ; cp test.fixed test&lt;br /&gt;
 diff -u ~/test/test.original ~/test/test | tee test.patch&lt;br /&gt;
 #  --- /home/USER/test/test.original    2026-04-21 09:20:42.864135487 -0700&lt;br /&gt;
 #  +++ /home/USER/test/test     2026-04-21 09:31:31.177670259 -0700&lt;br /&gt;
&lt;br /&gt;
 # then edit the patch file and fix the header paths&lt;br /&gt;
 #  --- test/test.original    2026-04-21 09:20:42.864135487 -0700&lt;br /&gt;
 #  +++ test/test     2026-04-21 09:31:31.177670259 -0700&lt;br /&gt;
 cp test.original test&lt;br /&gt;
 cat test.patch | patch -d .. -p0&lt;br /&gt;
 #  patching file test/test&lt;br /&gt;
&lt;br /&gt;
== see also ==&lt;br /&gt;
&lt;br /&gt;
* [[patch]]&lt;br /&gt;
* [[diff]]&lt;br /&gt;
&lt;br /&gt;
== keywords ==&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=Linux/patch&amp;diff=9850</id>
		<title>Linux/patch</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=Linux/patch&amp;diff=9850"/>
		<updated>2026-04-21T16:33:38Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== patch and diff ==&lt;br /&gt;
&lt;br /&gt;
=== diff from another directory ===&lt;br /&gt;
&lt;br /&gt;
no built in method, so have to get tricky&lt;br /&gt;
&lt;br /&gt;
Files for test:&lt;br /&gt;
* test.original&lt;br /&gt;
* test.fixed&lt;br /&gt;
* test  # target file&lt;br /&gt;
&lt;br /&gt;
Option #1 - move to correct path manually&lt;br /&gt;
 cd ~/test ; cp test.fixed test&lt;br /&gt;
 cd .. ; diff -u test/test.original test/test | tee test.patch&lt;br /&gt;
 #  --- test/test.original  2026-04-21 09:20:42.864135487 -0700&lt;br /&gt;
 #  +++ test/test   2026-04-21 09:20:56.014023558 -0700&lt;br /&gt;
&lt;br /&gt;
 # Then if could be used like:&lt;br /&gt;
 cp test/test.original test/test&lt;br /&gt;
 cat test.patch | patch -d . -p0&lt;br /&gt;
 #  patching file test/test&lt;br /&gt;
&lt;br /&gt;
Option #2 - use the -pX to drop path components&lt;br /&gt;
 cd ~/test ; cp test.fixed test&lt;br /&gt;
 diff -u ../test/test.original ../test/test | tee test.patch&lt;br /&gt;
 #  --- ../test/test.original       2026-04-21 09:20:42.864135487 -0700&lt;br /&gt;
 #  +++ ../test/test        2026-04-21 09:25:49.926535912 -0700&lt;br /&gt;
&lt;br /&gt;
 # Then if could be used like:&lt;br /&gt;
 cp test.original test&lt;br /&gt;
 cat test.patch | patch -d .. -p1  # p1 drops first path component&lt;br /&gt;
 #  patching file test/test&lt;br /&gt;
 # Alternative would be to edit the patch file and remove the &amp;quot;../&amp;quot; from the header&lt;br /&gt;
&lt;br /&gt;
Option #3 - edit the header&lt;br /&gt;
 cd ~/test ; cp test.fixed test&lt;br /&gt;
 diff -u ~/test/test.original ~/test/test | tee test.patch&lt;br /&gt;
 #  --- /home/USER/test/test.original    2026-04-21 09:20:42.864135487 -0700&lt;br /&gt;
 #  +++ /home/USER/test/test     2026-04-21 09:31:31.177670259 -0700&lt;br /&gt;
&lt;br /&gt;
 # then edit the patch file and fix the header paths&lt;br /&gt;
 #  --- test/test.original    2026-04-21 09:20:42.864135487 -0700&lt;br /&gt;
 #  +++ test/test     2026-04-21 09:31:31.177670259 -0700&lt;br /&gt;
 cp test.original test&lt;br /&gt;
 cat test.patch | patch -d .. -p0&lt;br /&gt;
 #  patching file test/test&lt;br /&gt;
&lt;br /&gt;
== see also ==&lt;br /&gt;
&lt;br /&gt;
* [[patch]]&lt;br /&gt;
* [[diff]]&lt;br /&gt;
&lt;br /&gt;
== keywords ==&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=Linux/diff&amp;diff=9849</id>
		<title>Linux/diff</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=Linux/diff&amp;diff=9849"/>
		<updated>2026-04-21T16:33:18Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: /* patch and diff */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Color Diff ==&lt;br /&gt;
&lt;br /&gt;
=== Color Diff with Less ===&lt;br /&gt;
&lt;br /&gt;
 diff --color=always | less -r&lt;br /&gt;
 git diff --color=always | less -r&lt;br /&gt;
&lt;br /&gt;
ref: https://unix.stackexchange.com/questions/19317/can-less-retain-colored-output&lt;br /&gt;
&lt;br /&gt;
== patch and diff ==&lt;br /&gt;
&lt;br /&gt;
See [[Linux/patch]]&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=Linux/diff&amp;diff=9848</id>
		<title>Linux/diff</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=Linux/diff&amp;diff=9848"/>
		<updated>2026-04-21T16:32:57Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Color Diff ==&lt;br /&gt;
&lt;br /&gt;
=== Color Diff with Less ===&lt;br /&gt;
&lt;br /&gt;
 diff --color=always | less -r&lt;br /&gt;
 git diff --color=always | less -r&lt;br /&gt;
&lt;br /&gt;
ref: https://unix.stackexchange.com/questions/19317/can-less-retain-colored-output&lt;br /&gt;
&lt;br /&gt;
== patch and diff ==&lt;br /&gt;
&lt;br /&gt;
=== diff from another directory ===&lt;br /&gt;
&lt;br /&gt;
no built in method, so have to get tricky&lt;br /&gt;
&lt;br /&gt;
Files for test:&lt;br /&gt;
* test.original&lt;br /&gt;
* test.fixed&lt;br /&gt;
* test  # target file&lt;br /&gt;
&lt;br /&gt;
Option #1 - move to correct path manually&lt;br /&gt;
 cd ~/test ; cp test.fixed test&lt;br /&gt;
 cd .. ; diff -u test/test.original test/test | tee test.patch&lt;br /&gt;
 #  --- test/test.original  2026-04-21 09:20:42.864135487 -0700&lt;br /&gt;
 #  +++ test/test   2026-04-21 09:20:56.014023558 -0700&lt;br /&gt;
&lt;br /&gt;
 # Then if could be used like:&lt;br /&gt;
 cp test/test.original test/test&lt;br /&gt;
 cat test.patch | patch -d . -p0&lt;br /&gt;
 #  patching file test/test&lt;br /&gt;
&lt;br /&gt;
Option #2 - use the -pX to drop path components&lt;br /&gt;
 cd ~/test ; cp test.fixed test&lt;br /&gt;
 diff -u ../test/test.original ../test/test | tee test.patch&lt;br /&gt;
 #  --- ../test/test.original       2026-04-21 09:20:42.864135487 -0700&lt;br /&gt;
 #  +++ ../test/test        2026-04-21 09:25:49.926535912 -0700&lt;br /&gt;
&lt;br /&gt;
 # Then if could be used like:&lt;br /&gt;
 cp test.original test&lt;br /&gt;
 cat test.patch | patch -d .. -p1  # p1 drops first path component&lt;br /&gt;
 #  patching file test/test&lt;br /&gt;
 # Alternative would be to edit the patch file and remove the &amp;quot;../&amp;quot; from the header&lt;br /&gt;
&lt;br /&gt;
Option #3 - edit the header&lt;br /&gt;
 cd ~/test ; cp test.fixed test&lt;br /&gt;
 diff -u ~/test/test.original ~/test/test | tee test.patch&lt;br /&gt;
 #  --- /home/USER/test/test.original    2026-04-21 09:20:42.864135487 -0700&lt;br /&gt;
 #  +++ /home/USER/test/test     2026-04-21 09:31:31.177670259 -0700&lt;br /&gt;
&lt;br /&gt;
 # then edit the patch file and fix the header paths&lt;br /&gt;
 #  --- test/test.original    2026-04-21 09:20:42.864135487 -0700&lt;br /&gt;
 #  +++ test/test     2026-04-21 09:31:31.177670259 -0700&lt;br /&gt;
 cp test.original test&lt;br /&gt;
 cat test.patch | patch -d .. -p0&lt;br /&gt;
 #  patching file test/test&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=Linux/patch&amp;diff=9847</id>
		<title>Linux/patch</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=Linux/patch&amp;diff=9847"/>
		<updated>2026-04-21T16:15:34Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;See:&lt;br /&gt;
* [[patch]]&lt;br /&gt;
* [[diff]]&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=Patch&amp;diff=9846</id>
		<title>Patch</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=Patch&amp;diff=9846"/>
		<updated>2026-04-21T16:15:22Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: Redirected page to Linux/patch&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[Linux/patch]]&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=Patch&amp;diff=9845</id>
		<title>Patch</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=Patch&amp;diff=9845"/>
		<updated>2026-04-21T16:14:34Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: Created page with &amp;quot;== patch ==&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== patch ==&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=Linux/patch&amp;diff=9844</id>
		<title>Linux/patch</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=Linux/patch&amp;diff=9844"/>
		<updated>2026-04-21T16:14:24Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: Created page with &amp;quot;See: * Linux/diff * patch * diff&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;See:&lt;br /&gt;
* [[Linux/diff]]&lt;br /&gt;
* [[patch]]&lt;br /&gt;
* [[diff]]&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=Ubuntu/Sources/22&amp;diff=9843</id>
		<title>Ubuntu/Sources/22</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=Ubuntu/Sources/22&amp;diff=9843"/>
		<updated>2026-04-20T22:04:00Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: Created page with &amp;quot;== 22 - Jammy ==  &amp;lt;pre&amp;gt; $ cat /etc/os-release PRETTY_NAME=&amp;quot;Ubuntu 22.04.5 LTS&amp;quot; NAME=&amp;quot;Ubuntu&amp;quot; VERSION_ID=&amp;quot;22.04&amp;quot; VERSION=&amp;quot;22.04.5 LTS (Jammy Jellyfish)&amp;quot; VERSION_CODENAME=jammy ID=ubuntu ID_LIKE=debian HOME_URL=&amp;quot;https://www.ubuntu.com/&amp;quot; SUPPORT_URL=&amp;quot;https://help.ubuntu.com/&amp;quot; BUG_REPORT_URL=&amp;quot;https://bugs.launchpad.net/ubuntu/&amp;quot; PRIVACY_POLICY_URL=&amp;quot;https://www.ubuntu.com/legal/terms-and-policies/privacy-policy&amp;quot; &amp;lt;/pre&amp;gt;  &amp;lt;pre&amp;gt; $ cat /etc/apt/sources.list # deb cdrom:[Ubuntu 22....&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== 22 - Jammy ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ cat /etc/os-release&lt;br /&gt;
PRETTY_NAME=&amp;quot;Ubuntu 22.04.5 LTS&amp;quot;&lt;br /&gt;
NAME=&amp;quot;Ubuntu&amp;quot;&lt;br /&gt;
VERSION_ID=&amp;quot;22.04&amp;quot;&lt;br /&gt;
VERSION=&amp;quot;22.04.5 LTS (Jammy Jellyfish)&amp;quot;&lt;br /&gt;
VERSION_CODENAME=jammy&lt;br /&gt;
ID=ubuntu&lt;br /&gt;
ID_LIKE=debian&lt;br /&gt;
HOME_URL=&amp;quot;https://www.ubuntu.com/&amp;quot;&lt;br /&gt;
SUPPORT_URL=&amp;quot;https://help.ubuntu.com/&amp;quot;&lt;br /&gt;
BUG_REPORT_URL=&amp;quot;https://bugs.launchpad.net/ubuntu/&amp;quot;&lt;br /&gt;
PRIVACY_POLICY_URL=&amp;quot;https://www.ubuntu.com/legal/terms-and-policies/privacy-policy&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ cat /etc/apt/sources.list&lt;br /&gt;
# deb cdrom:[Ubuntu 22.04.2 LTS _Jammy Jellyfish_ - Release amd64 (20230223)]/ jammy main restricted&lt;br /&gt;
&lt;br /&gt;
# See http://help.ubuntu.com/community/UpgradeNotes for how to upgrade to&lt;br /&gt;
# newer versions of the distribution.&lt;br /&gt;
deb http://us.archive.ubuntu.com/ubuntu/ jammy main restricted&lt;br /&gt;
# deb-src http://us.archive.ubuntu.com/ubuntu/ jammy main restricted&lt;br /&gt;
&lt;br /&gt;
## Major bug fix updates produced after the final release of the&lt;br /&gt;
## distribution.&lt;br /&gt;
deb http://us.archive.ubuntu.com/ubuntu/ jammy-updates main restricted&lt;br /&gt;
# deb-src http://us.archive.ubuntu.com/ubuntu/ jammy-updates main restricted&lt;br /&gt;
&lt;br /&gt;
## N.B. software from this repository is ENTIRELY UNSUPPORTED by the Ubuntu&lt;br /&gt;
## team. Also, please note that software in universe WILL NOT receive any&lt;br /&gt;
## review or updates from the Ubuntu security team.&lt;br /&gt;
deb http://us.archive.ubuntu.com/ubuntu/ jammy universe&lt;br /&gt;
# deb-src http://us.archive.ubuntu.com/ubuntu/ jammy universe&lt;br /&gt;
deb http://us.archive.ubuntu.com/ubuntu/ jammy-updates universe&lt;br /&gt;
# deb-src http://us.archive.ubuntu.com/ubuntu/ jammy-updates universe&lt;br /&gt;
&lt;br /&gt;
## N.B. software from this repository is ENTIRELY UNSUPPORTED by the Ubuntu&lt;br /&gt;
## team, and may not be under a free licence. Please satisfy yourself as to&lt;br /&gt;
## your rights to use the software. Also, please note that software in&lt;br /&gt;
## multiverse WILL NOT receive any review or updates from the Ubuntu&lt;br /&gt;
## security team.&lt;br /&gt;
deb http://us.archive.ubuntu.com/ubuntu/ jammy multiverse&lt;br /&gt;
# deb-src http://us.archive.ubuntu.com/ubuntu/ jammy multiverse&lt;br /&gt;
deb http://us.archive.ubuntu.com/ubuntu/ jammy-updates multiverse&lt;br /&gt;
# deb-src http://us.archive.ubuntu.com/ubuntu/ jammy-updates multiverse&lt;br /&gt;
&lt;br /&gt;
## N.B. software from this repository may not have been tested as&lt;br /&gt;
## extensively as that contained in the main release, although it includes&lt;br /&gt;
## newer versions of some applications which may provide useful features.&lt;br /&gt;
## Also, please note that software in backports WILL NOT receive any review&lt;br /&gt;
## or updates from the Ubuntu security team.&lt;br /&gt;
deb http://us.archive.ubuntu.com/ubuntu/ jammy-backports main restricted universe multiverse&lt;br /&gt;
# deb-src http://us.archive.ubuntu.com/ubuntu/ jammy-backports main restricted universe multiverse&lt;br /&gt;
&lt;br /&gt;
deb http://security.ubuntu.com/ubuntu jammy-security main restricted&lt;br /&gt;
# deb-src http://security.ubuntu.com/ubuntu jammy-security main restricted&lt;br /&gt;
deb http://security.ubuntu.com/ubuntu jammy-security universe&lt;br /&gt;
# deb-src http://security.ubuntu.com/ubuntu jammy-security universe&lt;br /&gt;
deb http://security.ubuntu.com/ubuntu jammy-security multiverse&lt;br /&gt;
# deb-src http://security.ubuntu.com/ubuntu jammy-security multiverse&lt;br /&gt;
&lt;br /&gt;
# This system was installed using small removable media&lt;br /&gt;
# (e.g. netinst, live or single CD). The matching &amp;quot;deb cdrom&amp;quot;&lt;br /&gt;
# entries were disabled at the end of the installation process.&lt;br /&gt;
# For information about how to configure apt package sources,&lt;br /&gt;
# see the sources.list(5) manual.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== keywords ==&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=Ubuntu/Sources/Jammy&amp;diff=9842</id>
		<title>Ubuntu/Sources/Jammy</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=Ubuntu/Sources/Jammy&amp;diff=9842"/>
		<updated>2026-04-20T22:02:46Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: Created page with &amp;quot;See Ubuntu/Sources/22&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;See [[Ubuntu/Sources/22]]&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=Ubuntu/Sources&amp;diff=9841</id>
		<title>Ubuntu/Sources</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=Ubuntu/Sources&amp;diff=9841"/>
		<updated>2026-04-20T22:02:36Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: Created page with &amp;quot;== Sources ==  == 24 - Xenial ==  See Ubuntu/Sources/24  See Ubuntu/Sources/Xenial  == 22 - Jammy ==  See Ubuntu/Sources/22  See Ubuntu/Sources/Jammy  == 20 - Xenial ==  See Ubuntu/Sources/20  See Ubuntu/Sources/Xenial  == keywords ==&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Sources ==&lt;br /&gt;
&lt;br /&gt;
== 24 - Xenial ==&lt;br /&gt;
&lt;br /&gt;
See [[Ubuntu/Sources/24]]&lt;br /&gt;
&lt;br /&gt;
See [[Ubuntu/Sources/Xenial]]&lt;br /&gt;
&lt;br /&gt;
== 22 - Jammy ==&lt;br /&gt;
&lt;br /&gt;
See [[Ubuntu/Sources/22]]&lt;br /&gt;
&lt;br /&gt;
See [[Ubuntu/Sources/Jammy]]&lt;br /&gt;
&lt;br /&gt;
== 20 - Xenial ==&lt;br /&gt;
&lt;br /&gt;
See [[Ubuntu/Sources/20]]&lt;br /&gt;
&lt;br /&gt;
See [[Ubuntu/Sources/Xenial]]&lt;br /&gt;
&lt;br /&gt;
== keywords ==&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=Ruckus/ICX-7150&amp;diff=9840</id>
		<title>Ruckus/ICX-7150</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=Ruckus/ICX-7150&amp;diff=9840"/>
		<updated>2026-04-20T19:39:00Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: /* Ports */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== ICX-7150 ==&lt;br /&gt;
&lt;br /&gt;
== Ports ==&lt;br /&gt;
&lt;br /&gt;
Left Side of Switch:&lt;br /&gt;
* USB-C Console Port&lt;br /&gt;
* RJ-45 Console Port&lt;br /&gt;
* Out-of-band Management Port RJ-45&lt;br /&gt;
&lt;br /&gt;
ICX7150-24 - 24 port Middle Module: &amp;quot;UNIT 1: SL 1: ICX7150-24-2X10G_2X1G 24-port Management Module&amp;quot;&lt;br /&gt;
* 1, ..., 24: (Ethernet ports 1/1/1 to 1/1/24)&lt;br /&gt;
** Odds are on top, Evens are on bottom&lt;br /&gt;
&lt;br /&gt;
ICX7150-48 - 48 port Middle Module: &amp;quot;UNIT 1: SL 1: ICX7150-48PF-4X1G POE 48-port Management Module&amp;quot;&lt;br /&gt;
* 1, ..., 48: (Ethernet ports 1/1/1 to 1/1/48)&lt;br /&gt;
** Odds are on top, Evens are on bottom&lt;br /&gt;
&lt;br /&gt;
Right Module &amp;quot;UNIT 1: SL 2: ICX7150-2X1GC 2-port 2G Module&amp;quot;:&lt;br /&gt;
* C1, C2: RJ-45 Uplink Port (Ethernet ports 1/2/1 to 1/2/2)&lt;br /&gt;
** C1 is on top, C2 is on bottom&lt;br /&gt;
&lt;br /&gt;
Right Module &amp;quot;UNIT 1: SL 3: ICX7150-4X10GF 4-port 40G Module&amp;quot;&lt;br /&gt;
* X1, X2, X3, X4: SFP+ Uplink / Stacking ports (Ethernet ports 1/3/1 to 1/3/4)&lt;br /&gt;
** Odds are on top, Evens are on bottom&lt;br /&gt;
&lt;br /&gt;
== USB C Management Console Connection ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[ 1783.328741] usb 3-3: new full-speed USB device number 4 using xhci_hcd&lt;br /&gt;
[ 1783.470048] usb 3-3: New USB device found, idVendor=10c4, idProduct=ea60&lt;br /&gt;
[ 1783.470052] usb 3-3: New USB device strings: Mfr=1, Product=2, SerialNumber=3&lt;br /&gt;
[ 1783.470054] usb 3-3: Product: CP2104 USB to UART Bridge Controller&lt;br /&gt;
[ 1783.470055] usb 3-3: Manufacturer: Silicon Labs&lt;br /&gt;
[ 1783.470057] usb 3-3: SerialNumber: 017C6EED&lt;br /&gt;
[ 1783.534393] usbcore: registered new interface driver usbserial&lt;br /&gt;
[ 1783.534405] usbcore: registered new interface driver usbserial_generic&lt;br /&gt;
[ 1783.534416] usbserial: USB Serial support registered for generic&lt;br /&gt;
[ 1783.550518] usbcore: registered new interface driver cp210x&lt;br /&gt;
[ 1783.550531] usbserial: USB Serial support registered for cp210x&lt;br /&gt;
[ 1783.550559] cp210x 3-3:1.0: cp210x converter detected&lt;br /&gt;
[ 1783.551382] usb 3-3: cp210x converter now attached to ttyUSB0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# tio -b 9600 /dev/ttyUSB0&lt;br /&gt;
[tio 07:47:59] tio v1.32&lt;br /&gt;
[tio 07:47:59] Press ctrl-t q to quit&lt;br /&gt;
[tio 07:47:59] Connected&lt;br /&gt;
&lt;br /&gt;
ICX7150-48-Switch&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Parameter&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Value&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Baud Rate&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;9600&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Data Bits&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;8&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Parity&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;None&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Stop Bits&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Flow Control&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;None&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Initial View ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ICX7150-48-Switch&amp;gt;enable&lt;br /&gt;
No password has been assigned yet...&lt;br /&gt;
ICX7150-48-Switch#show config&lt;br /&gt;
INFO: empty config data in the primary area, try to read from backup&lt;br /&gt;
INFO: empty config data in the backup area also&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Show IP ==&lt;br /&gt;
&lt;br /&gt;
Initially the switch is configured for DHCP, with telnet access.  To see the address:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ICX7150-48-Switch#show ip&lt;br /&gt;
&lt;br /&gt;
     Switch IP address: 10.10.10.228&lt;br /&gt;
&lt;br /&gt;
           Subnet mask: 255.255.255.0&lt;br /&gt;
&lt;br /&gt;
Default router address: 10.10.10.1&lt;br /&gt;
   TFTP server address: 10.248.1.206&lt;br /&gt;
Configuration filename: None&lt;br /&gt;
        Image filename: None&lt;br /&gt;
            DNS Server: 10.10.10.1&lt;br /&gt;
                IP MTU: 1500&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Initial telnet: &amp;quot;The ICX7150-24F, ICX7150-C08P, and ICX7150-C10ZP switches ship from the factory with SSH enabled and Telnet disabled. All other switches have Telnet enabled only.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
ref: http://docs.ruckuswireless.com/fastiron/hardware/ruckus-icx-switch-qsg/GUID-A7D29C1A-2288-4121-A0B8-F7136EAF9291.html&lt;br /&gt;
&lt;br /&gt;
== Assign IP ==&lt;br /&gt;
&lt;br /&gt;
 (config)# ip address 172.31.0.1/24&lt;br /&gt;
or&lt;br /&gt;
 (config)# ip address 172.31.0.1 255.255.255.0&lt;br /&gt;
&lt;br /&gt;
== Privilege Levels ==&lt;br /&gt;
&lt;br /&gt;
3 privileged levels:&lt;br /&gt;
#  super-user-password           Super-user level password&lt;br /&gt;
#  port-config-password          Port level configuration password&lt;br /&gt;
#  read-only-password            Read-only level password&lt;br /&gt;
&lt;br /&gt;
* Super User level - Allows complete read-and-write access to the system. This is generally for system administrators and is the only management privilege level that allows you to configure passwords.&lt;br /&gt;
* Port Configuration level - Allows read-and-write access for specific ports but not for global (system-wide) parameters.&lt;br /&gt;
* Read-only level - Allows access to the Privileged EXEC mode and User EXEC mode of the CLI but only with read access.&lt;br /&gt;
&lt;br /&gt;
Set the password by (with enable using super-user&#039;s password) &lt;br /&gt;
 enable&lt;br /&gt;
 conf term&lt;br /&gt;
&lt;br /&gt;
1. Set Super User level password:&lt;br /&gt;
 enable super-user-password [PASSWORD]&lt;br /&gt;
&lt;br /&gt;
2. Set Port Configure password:&lt;br /&gt;
 enable port-config-password [PASSWORD]&lt;br /&gt;
&lt;br /&gt;
3. Set Read Only level password:&lt;br /&gt;
 enable read-only-password [PASSWORD]&lt;br /&gt;
&lt;br /&gt;
To see which mode you are logged in as, use &amp;quot;sh who&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
ref: https://docs.ruckuswireless.com/fastiron/08.0.60/fastiron-08060-securityguide/GUID-F35168E7-729D-46A2-ACE1-68148B01443D.html&lt;br /&gt;
&lt;br /&gt;
== Require Login ==&lt;br /&gt;
&lt;br /&gt;
 aaa authentication web-server default local&lt;br /&gt;
 aaa authentication login default local&lt;br /&gt;
&lt;br /&gt;
== User Logins ==&lt;br /&gt;
&lt;br /&gt;
 no username super&lt;br /&gt;
 username admin [password]&lt;br /&gt;
&lt;br /&gt;
== Recover from a Lost Password ==&lt;br /&gt;
&lt;br /&gt;
# Reboot the device.&lt;br /&gt;
# At the initial boot prompt at system startup, enter &#039;&#039;&#039;b&#039;&#039;&#039; to enter the boot monitor mode.&lt;br /&gt;
# Enter &#039;&#039;&#039;no password&#039;&#039;&#039; at the prompt. (You cannot abbreviate this command.) This command will cause the device to bypass the system password check.&lt;br /&gt;
# Enter &#039;&#039;&#039;boot system flash primary&#039;&#039;&#039; at the prompt.&lt;br /&gt;
&lt;br /&gt;
ref: https://docs.ruckuswireless.com/fastiron/08.0.60/fastiron-08060-securityguide/GUID-986D5DF0-BF7E-4327-9030-396433DFFD9D.html&lt;br /&gt;
&lt;br /&gt;
== Show Software Version and Hardware Model ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;sh ver&lt;br /&gt;
  Copyright (c) 2017 Ruckus Wireless, Inc. All rights reserved.&lt;br /&gt;
    UNIT 1: compiled on Apr 12 2019 at 11:46:50 labeled as SPS08070db&lt;br /&gt;
      (25717216 bytes) from Primary SPS08070db.bin&lt;br /&gt;
        SW: Version 08.0.70dbT211&lt;br /&gt;
      Compressed Boot-Monitor Image size = 786944, Version:10.1.14T225 (mnz10114)&lt;br /&gt;
       Compiled on Thu Nov 15 12:59:22 2018&lt;br /&gt;
&lt;br /&gt;
  HW: Stackable ICX7150-48-POEF&lt;br /&gt;
==========================================================================&lt;br /&gt;
UNIT 1: SL 1: ICX7150-48PF-4X1G POE 48-port Management Module&lt;br /&gt;
      Serial  #:XXXXXXXXXXX&lt;br /&gt;
      Current License: 4X1G&lt;br /&gt;
      P-ASIC  0: type B160, rev 11  Chip BCM56160_B0&lt;br /&gt;
==========================================================================&lt;br /&gt;
UNIT 1: SL 2: ICX7150-2X1GC 2-port 2G Module&lt;br /&gt;
==========================================================================&lt;br /&gt;
UNIT 1: SL 3: ICX7150-4X10GF 4-port 40G Module&lt;br /&gt;
==========================================================================&lt;br /&gt;
 1000 MHz ARM processor ARMv7 88 MHz bus&lt;br /&gt;
 8192 KB boot flash memory&lt;br /&gt;
 2048 MB code flash memory&lt;br /&gt;
 1024 MB DRAM&lt;br /&gt;
STACKID 1  system uptime is 336 day(s) 1 hour(s) 11 minute(s) 35 second(s)&lt;br /&gt;
The system started at 04:05:00 GMT+00 Sat Jan 01 2000&lt;br /&gt;
&lt;br /&gt;
The system : started=cold start&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Enable SSH ==&lt;br /&gt;
&lt;br /&gt;
(Note telnet is enabled by default, and doesn&#039;t require user)&lt;br /&gt;
&lt;br /&gt;
crypto key generate - http://docs.ruckuswireless.com/fastiron/08.0.50/fastiron-08050-commandref/GUID-74724EE0-E8FB-46A1-8FBA-9E2F342D5B93.html&lt;br /&gt;
:To enable SSH, you generate a DSA or RSA host key on the device. The SSH server on the Brocade device uses this host DSA or RSA key, along with a dynamically generated server DSA or RSA key pair, to negotiate a session key and encryption method with the client trying to connect to it. While the SSH listener exists at all times, sessions cannot be started from clients until a host key is generated. After a host key is generated, clients can start sessions. When a host key is generated, it is saved to the flash memory of all management modules. The time to initially generate SSH keys varies depending on the configuration, and can be from a under a minute to several minutes.&lt;br /&gt;
: To disable SSH, you delete all of the host keys from the device. When a host key is deleted, it is deleted from the flash memory of all management modules.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Enable SSH: [https://www.shanekillen.com/2014/03/brocade-switch-how-to-configure-ssh-and.html]&lt;br /&gt;
 ## Generate keys&lt;br /&gt;
 crypto key generate dsa&lt;br /&gt;
 # Add admin user:&lt;br /&gt;
 username admin pri 0 password passphrase&lt;br /&gt;
 # enable &lt;br /&gt;
 aaa authentication login default local&lt;br /&gt;
&lt;br /&gt;
then wait... takes about 5 minutes, and you will eventually see:&lt;br /&gt;
 DSA Key pair is successfully created&lt;br /&gt;
&lt;br /&gt;
..&lt;br /&gt;
..&lt;br /&gt;
&lt;br /&gt;
 root@server:~# ssh admin@10.10.10.100&lt;br /&gt;
 Unable to negotiate with 10.10.10.100 port 22: no matching key exchange method found. Their offer: diffie-hellman-group1-sha1&lt;br /&gt;
&lt;br /&gt;
fix with: (from switch)&lt;br /&gt;
 ip ssh key-exchange-method dh-group14-sha1&lt;br /&gt;
&lt;br /&gt;
or from SSH:&lt;br /&gt;
  ssh -v -oKexAlgorithms=+diffie-hellman-group1-sha1 -oHostKeyAlgorithms=+ssh-dss -caes256-cbc 10.10.10.100&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Generate keys:&lt;br /&gt;
 (config)#crypto key generate rsa modulus 2048&lt;br /&gt;
 (config)#ip ssh key-exchange-method dh-group14-sha1&lt;br /&gt;
 Warning: This operation would close all existing SSH connection.&lt;br /&gt;
 (config)#username admin privilege 0 password [PASSWORD]&lt;br /&gt;
    DECIMAL   &amp;lt;0 READ-WRITE, 4 PORT-CONFIG, 5 READ-ONLY&amp;gt; User privilege level&lt;br /&gt;
 (config)#aaa authentication login default local&lt;br /&gt;
&lt;br /&gt;
To require the enable login locally as well:&lt;br /&gt;
 (config)#aaa authentication enable default local&lt;br /&gt;
&lt;br /&gt;
To auto go to privileged mode after login (use in labs only, not production):&lt;br /&gt;
 (config)#aaa authentication login privilege-mode &lt;br /&gt;
&lt;br /&gt;
To change password:&lt;br /&gt;
 (config)#username admin password [PASSWORD]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ref: https://robrobstation.com/2017/07/17/ruckus-icx7150-c12p-initial-configuration/&lt;br /&gt;
&lt;br /&gt;
Sample config:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ICX7150-48-Switch(config)#write terminal&lt;br /&gt;
Current configuration:&lt;br /&gt;
!&lt;br /&gt;
ver 08.0.61aT211&lt;br /&gt;
!&lt;br /&gt;
stack unit 1&lt;br /&gt;
  module 1 icx7150-48-port-management-module&lt;br /&gt;
  module 2 icx7150-2-copper-port-2g-module&lt;br /&gt;
  module 3 icx7150-4-sfp-plus-port-40g-module&lt;br /&gt;
!&lt;br /&gt;
!&lt;br /&gt;
!&lt;br /&gt;
!&lt;br /&gt;
!&lt;br /&gt;
!&lt;br /&gt;
!&lt;br /&gt;
!&lt;br /&gt;
!&lt;br /&gt;
!&lt;br /&gt;
aaa authentication enable default local&lt;br /&gt;
aaa authentication login default local&lt;br /&gt;
ip address 10.10.10.228 255.255.255.0 dynamic&lt;br /&gt;
ip default-gateway 10.10.10.1 dynamic&lt;br /&gt;
!&lt;br /&gt;
username admin password .....&lt;br /&gt;
!&lt;br /&gt;
!&lt;br /&gt;
interface ethernet 1/3/1&lt;br /&gt;
 speed-duplex 1000-full&lt;br /&gt;
!&lt;br /&gt;
interface ethernet 1/3/2&lt;br /&gt;
 speed-duplex 1000-full&lt;br /&gt;
!&lt;br /&gt;
interface ethernet 1/3/3&lt;br /&gt;
 speed-duplex 1000-full&lt;br /&gt;
!&lt;br /&gt;
interface ethernet 1/3/4&lt;br /&gt;
 speed-duplex 1000-full&lt;br /&gt;
!&lt;br /&gt;
!&lt;br /&gt;
!&lt;br /&gt;
!&lt;br /&gt;
!&lt;br /&gt;
!&lt;br /&gt;
ip ssh  key-exchange-method dh-group14-sha1&lt;br /&gt;
!&lt;br /&gt;
!&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Disable SSH ===&lt;br /&gt;
&lt;br /&gt;
Delete the host keys&lt;br /&gt;
&lt;br /&gt;
 crypto key zeroize&lt;br /&gt;
&lt;br /&gt;
 crypto key zeroize dsa&lt;br /&gt;
&lt;br /&gt;
crypto key generate - http://docs.ruckuswireless.com/fastiron/08.0.50/fastiron-08050-commandref/GUID-74724EE0-E8FB-46A1-8FBA-9E2F342D5B93.html&lt;br /&gt;
: To disable SSH, you delete all of the host keys from the device. When a host key is deleted, it is deleted from the flash memory of all management modules.&lt;br /&gt;
&lt;br /&gt;
== Disable Telnet ==&lt;br /&gt;
&lt;br /&gt;
Once SSH is enabled, telnet is best disabled.&lt;br /&gt;
&lt;br /&gt;
 (config)#no telnet server&lt;br /&gt;
&lt;br /&gt;
== Clock ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Daylight Saving (Summer Time) [https://docs.commscope.com/bundle/fastiron-08091-managementguide/page/GUID-E670EE11-FBD6-4D1E-9099-6E231887D245.html]&lt;br /&gt;
 clock summer-time zone us pacific start 02-28-21 02:00:00 end 10-30-21 02:00:00 offset 60&lt;br /&gt;
&lt;br /&gt;
Note: Will have to be updated each year.&lt;br /&gt;
&lt;br /&gt;
== Enable POE ==&lt;br /&gt;
&lt;br /&gt;
See [[Ruckus/ICX-6450-48#Enable POE]]&lt;br /&gt;
&lt;br /&gt;
== Firmware ==&lt;br /&gt;
&lt;br /&gt;
=== Firmware Versions ===&lt;br /&gt;
&lt;br /&gt;
ICX FastIron Stable series:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
08.0.95p	2024-06-27&lt;br /&gt;
08.0.95n	2024-01-31  *** recommended stable ***&lt;br /&gt;
08.0.95m	2023-08-24&lt;br /&gt;
08.0.95k	2023-06-16&lt;br /&gt;
08.0.95j	2023-06-16&lt;br /&gt;
08.0.95h	2022-09-02&lt;br /&gt;
...&lt;br /&gt;
08.0.95 	2020-09-14&lt;br /&gt;
...&lt;br /&gt;
08.0.90d	2019-09-27 *** used as jump to ufi ***&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 https://support.ruckuswireless.com/software/1186-ruckus-icx-7xxx-icx-6xxxx-campus-switch-firmware-download&lt;br /&gt;
&lt;br /&gt;
 https://support.ruckuswireless.com/products/108-ruckus-icx-7150-campus-switches?open=document#firmwares&lt;br /&gt;
&lt;br /&gt;
 https://support.ruckuswireless.com/products/108-ruckus-icx-7150-campus-switches&lt;br /&gt;
 Recommended Software: (as of 2024.07.08)&lt;br /&gt;
  Stability Release: RUCKUS ICX FastIron 08.0.95n (GA) Software Release (.zip)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
&amp;quot;Ruckus ICX software currently has two recommended release types; Stability and Technology.&lt;br /&gt;
&lt;br /&gt;
Stability Release: This is for customers where stability is of utmost importance. This release may not contain every feature available for your product.&lt;br /&gt;
&lt;br /&gt;
Technology Release: This is for customers looking to utilize the maximum feature set available for your product.&lt;br /&gt;
&lt;br /&gt;
We recommend most customers utilize the Stability Release if it contains all needed features for your network. A Technology Release is recommended if your network requires newer features not available in the Stability Release.&amp;quot;&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 08.0.95n ===&lt;br /&gt;
&lt;br /&gt;
 RUCKUS ICX FastIron 08.0.95n (GA) Software Release (.zip)&lt;br /&gt;
 https://support.ruckuswireless.com/software/3958-ruckus-icx-fastiron-08-0-95n-ga-software-release-zip&lt;br /&gt;
&lt;br /&gt;
 Applies to: ICX7150, ICX7250, ICX7450, ICX7550, ICX7650, ICX7750, ICX7850&lt;br /&gt;
&lt;br /&gt;
=== 08.0.95m ===&lt;br /&gt;
&lt;br /&gt;
 RUCKUS ICX FastIron 08.0.95m (GA) Software Release (.zip)&lt;br /&gt;
 https://support.ruckuswireless.com/software/3749-ruckus-icx-fastiron-08-0-95m-ga-software-release-zip&lt;br /&gt;
&lt;br /&gt;
 Applies to: ICX7150, ICX7250, ICX7450, ICX7550, ICX7650, ICX7750, ICX7850&lt;br /&gt;
&lt;br /&gt;
=== Firmware Notes ===&lt;br /&gt;
&lt;br /&gt;
Newer firmware combines the bootrom and firmware images into a single file, called the &#039;&#039;&#039;Unified FastIron Image (UFI)&#039;&#039;&#039; [https://docs.commscope.com/bundle/fastiron-08091-upgradeguide/page/GUID-C1E90D8F-E1CB-48CE-9369-6605EB035602.html]&lt;br /&gt;
&lt;br /&gt;
 &amp;quot;Ruckus recommends that you always use the manifest file for any image upgrade or downgrade.&amp;quot; [https://docs.commscope.com/bundle/fastiron-08091-upgradeguide/page/GUID-B8B3B6B1-0453-4713-B894-0EFAB084B1D6.html]&lt;br /&gt;
&lt;br /&gt;
 &amp;quot;If you are upgrading from FastIron release 08.0.80 to release 08.0.90, Ruckus recommends using SCP to transfer files.&amp;quot; [https://docs.commscope.com/bundle/fastiron-08091-upgradeguide/page/GUID-B8B3B6B1-0453-4713-B894-0EFAB084B1D6.html]&lt;br /&gt;
&lt;br /&gt;
 &amp;quot;Software images for all RUCKUS ICX devices can be uploaded and downloaded between flash modules on the device and a &#039;&#039;&#039;TFTP, SCP, HTTPS, or USB&#039;&#039;&#039; module on the network.&amp;quot; [https://docs.commscope.com/bundle/fastiron-08091-upgradeguide/page/GUID-C8148B03-D98C-4F4D-939C-9111CECB0601.html]&lt;br /&gt;
&lt;br /&gt;
 Ruckus FastIron Software Upgrade Guide, 08.0.90 PDF [https://support.alcadis.nl/Support_files/Ruckus/ICX//Software%20Manuals/Ruckus%20ICX%20FastIron%20v08.0.90/Ruckus%20FastIron%2008.0.90%20Software%20Upgrade%20Guide.pdf]&lt;br /&gt;
&lt;br /&gt;
 username: super&lt;br /&gt;
 default password: sp-admin&lt;br /&gt;
&lt;br /&gt;
 copy tftp system-manifest 10.0.0.10 FI08090j_Manifest.txt all-images-primary&lt;br /&gt;
&lt;br /&gt;
 copy tftp flash 10.0.0.10 ICX7150/Images/SPS08090j.bin primary&lt;br /&gt;
&lt;br /&gt;
 copy tftp system-manifest 10.0.0.10 FI08090_Manifest.txt all_images_primary&lt;br /&gt;
 copy tftp system-manifest 10.0.0.10 FI08090_Manifest.txt primary&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 ! Doesn&#039;t work, due to TFTP issues&lt;br /&gt;
 copy tftp system-manifest 10.0.0.10 08080f/FI08080f_Manifest.txt all-images-primary&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 copy tftp flash 10.0.0.10 08080f/ICX7150/Boot/mnz10114.bin bootrom&lt;br /&gt;
 ! wait for this command to complete!&lt;br /&gt;
 ! wait for this command to complete!&lt;br /&gt;
 ! wait for this command to complete!&lt;br /&gt;
&lt;br /&gt;
 erase flash primary&lt;br /&gt;
&lt;br /&gt;
 copy tftp flash 10.0.0.10 08080f/ICX7150/Images/SPS08080f.bin primary&lt;br /&gt;
 ! wait for this command to complete!&lt;br /&gt;
 ! wait for this command to complete!&lt;br /&gt;
 ! wait for this command to complete!&lt;br /&gt;
&lt;br /&gt;
 erase flash secondary&lt;br /&gt;
&lt;br /&gt;
 copy tftp flash 10.0.0.10 08080f/ICX7150/Images/SPR08080f.bin secondary&lt;br /&gt;
 ! wait for this command to complete!&lt;br /&gt;
 ! wait for this command to complete!&lt;br /&gt;
 ! wait for this command to complete!&lt;br /&gt;
&lt;br /&gt;
 show flash&lt;br /&gt;
&lt;br /&gt;
 config t&lt;br /&gt;
 boot sys flash prim&lt;br /&gt;
 exit&lt;br /&gt;
 wr mem&lt;br /&gt;
 reload&lt;br /&gt;
&lt;br /&gt;
 copy tftp system-manifest 10.0.0.10 08090j/FI08090j_Manifest.txt all-images-primary&lt;br /&gt;
 copy tftp system-manifest 10.0.0.10 08090j/FI08090j_Manifest.txt primary&lt;br /&gt;
 copy tftp system-manifest 10.0.0.10 08090j/FI08090j_Manifest.txt secondary&lt;br /&gt;
&lt;br /&gt;
 copy scp system-manifest 10.0.0.10 /tftp/08090j/FI08090j_Manifest.txt primary&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 copy tftp system-manifest 10.0.0.10 08090d/FI08090d_Manifest.txt all-images-primary&lt;br /&gt;
 copy tftp system-manifest 10.0.0.10 08090d/FI08090d_Manifest.txt primary&lt;br /&gt;
 copy tftp system-manifest 10.0.0.10 08090d/FI08090d_Manifest.txt secondary&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 erase flash primary&lt;br /&gt;
 erase flash secondary&lt;br /&gt;
&lt;br /&gt;
 copy tftp flash 10.0.0.10 08090d/ICX7150/Boot/mnz10115.bin bootrom&lt;br /&gt;
 copy tftp flash 10.0.0.10 08090d/ICX7150/Images/SPS08090d.bin primary&lt;br /&gt;
 copy tftp flash 10.0.0.10 08090d/ICX7150/Images/SPR08090d.bin secondary&lt;br /&gt;
&lt;br /&gt;
 copy tftp flash 10.0.0.10 08090d/ICX7150/Images/SPS08090dufi.bin primary&lt;br /&gt;
 copy tftp flash 10.0.0.10 08090d/ICX7150/Images/SPS08090dufi.bin secondary&lt;br /&gt;
 copy tftp flash 10.0.0.10 08090d/ICX7150/Images/SPR08090dufi.bin secondary&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 erase flash primary&lt;br /&gt;
&lt;br /&gt;
 copy tftp flash 10.0.0.10 08090j/ICX7150/Images/SPS08090jufi.bin primary&lt;br /&gt;
&lt;br /&gt;
 erase flash secondary&lt;br /&gt;
&lt;br /&gt;
 copy tftp flash 10.0.0.10 08090j/ICX7150/Images/SPR08090jufi.bin secondary&lt;br /&gt;
&lt;br /&gt;
 ! Enable SSH&lt;br /&gt;
 crypto key generate dsa&lt;br /&gt;
&lt;br /&gt;
 conf t&lt;br /&gt;
 crypto key generate dsa&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 copy scp flash 10.0.0.10 /tftp/08090d/ICX7150/Boot/mnz10115.bin bootrom&lt;br /&gt;
 copy scp flash 10.0.0.10 /tftp/08090d/ICX7150/Images/SPS08090d.bin primary&lt;br /&gt;
&lt;br /&gt;
 show flash&lt;br /&gt;
 config t&lt;br /&gt;
 boot sys flash prim&lt;br /&gt;
 exit&lt;br /&gt;
 wr mem&lt;br /&gt;
 reload&lt;br /&gt;
&lt;br /&gt;
 copy scp flash 10.0.0.10 /tftp/08090j/ICX7150/Images/SPS08090jufi.bin primary&lt;br /&gt;
&lt;br /&gt;
 copy scp flash 10.0.0.10 /tftp/08090j/ICX7150/Images/SPS08090jufi.bin secondary&lt;br /&gt;
&lt;br /&gt;
 ! Copy primary to secondary&lt;br /&gt;
 copy flash flash secondary&lt;br /&gt;
&lt;br /&gt;
 show flash&lt;br /&gt;
 config t&lt;br /&gt;
 boot sys flash prim&lt;br /&gt;
 exit&lt;br /&gt;
 wr mem&lt;br /&gt;
 reload&lt;br /&gt;
&lt;br /&gt;
 ! Write POE Flash&lt;br /&gt;
 inline power install-firmware stack-unit 1 scp 10.0.0.10 /tftp/08090j/ICX7150/Firmware/icx7xxx_poe_02.1.1.b002.fw&lt;br /&gt;
&lt;br /&gt;
 Error: No Unit in the system has PoE module&lt;br /&gt;
&lt;br /&gt;
 poe fw ref: https://docs.commscope.com/bundle/fastiron-08030-adminguide/page/GUID-2E378DEB-4CD3-41F8-90E4-28EA47BCAD28.html&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sh inl pow det&lt;br /&gt;
&lt;br /&gt;
Firmware&lt;br /&gt;
Version&lt;br /&gt;
----------------&lt;br /&gt;
02.1.1 Build 002&lt;br /&gt;
&lt;br /&gt;
Hardware&lt;br /&gt;
Version&lt;br /&gt;
----------------&lt;br /&gt;
V2R4&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 boot system flash secondary&lt;br /&gt;
&lt;br /&gt;
 # permanent&lt;br /&gt;
 boot system flash primary yes&lt;br /&gt;
&lt;br /&gt;
 ref: http://docs.ruckuswireless.com/fastiron/08.0.50/fastiron-08050-commandref/GUID-9B008914-403A-4FE1-8445-5DCD63F9A1A2.html&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 sh boot-preference&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 Configure SSH on a Ruckus Switch | me@luiscachog.io - &lt;br /&gt;
 https://luiscachog.io/configure-ruckus-switch/&lt;br /&gt;
&lt;br /&gt;
 device(config)# crypto-ssl certificate generate&lt;br /&gt;
 device(config)# username USERNAME password PASSWORD&lt;br /&gt;
 device(config)# aaa authentication login default local&lt;br /&gt;
 device(config)# aaa authentication web-server default local&lt;br /&gt;
&lt;br /&gt;
== TFTP session timed out - on boot ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Summary: TFTP session timed out messages on console after boot up&lt;br /&gt;
&lt;br /&gt;
Question: Why did TFTP session time out messages on console after boot up?&lt;br /&gt;
&lt;br /&gt;
Customer Environment: FI 07.1.00&lt;br /&gt;
&lt;br /&gt;
-- Root Cause --&lt;br /&gt;
&lt;br /&gt;
In the FastIron series, starting from FI 07.1.00, DHCP Client-Based Auto-Configuration is supported and enabled by default. DHCP&lt;br /&gt;
Client-Based Auto-Configuration allows Layer 2 and Layer 3 devices to automatically obtain leased IP addresses through a DHCP server,&lt;br /&gt;
negotiate an address lease renewal, and obtain the flash image and configuration files. For the details, please refer to FastIron&lt;br /&gt;
configuration guide.&lt;br /&gt;
&lt;br /&gt;
The above messages mean FastIron switch got an IP address from the DHCP server and is trying to get a configuration file from the&lt;br /&gt;
TFTP server but there is no resposne from the TFTP server. The messages can be ignored if the user is not trying to download a&lt;br /&gt;
configuration file from TFTP server.&lt;br /&gt;
&lt;br /&gt;
-- Troubleshooting Steps --&lt;br /&gt;
&lt;br /&gt;
In FastIron 7.1.00 and later, when booting up the FastIron switch, the user is seeing the following messages on console and an&lt;br /&gt;
output in show log:&lt;br /&gt;
&lt;br /&gt;
##console&lt;br /&gt;
FWS648G Switch#TFTP session timed out&lt;br /&gt;
FWS648G Switch#TFTP session timed out&lt;br /&gt;
&lt;br /&gt;
##show log&lt;br /&gt;
0d00h03m30s:D:DHCPC: TFTP unable to download running-configuration&lt;br /&gt;
0d00h03m13s:D:DHCPC: sending TFTP request for bootfile name fws-switch.cfg&lt;br /&gt;
0d00h02m56s:D:DHCPC: sending TFTP request for bootfile name brocade.cfg&lt;br /&gt;
0d00h02m39s:D:DHCPC: sending TFTP request for bootfile name foundry.cfg&lt;br /&gt;
0d00h02m22s:D:DHCPC: sending TFTP request for bootfile name FWS648G-Switch0024.38fb.9000.cfg&lt;br /&gt;
0d00h02m05s:D:DHCPC: sending TFTP request for bootfile name FWS648G-Switch0024.38fb.9000-config.cfg&lt;br /&gt;
0d00h01m49s:D:DHCPC: sending TFTP request for bootfile name FWS648G-Switch0024.38fb.9000-config.cfg&lt;br /&gt;
0d00h01m33s:D:DHCPC: sending TFTP request for bootfile name FWS648G-Switch0024.38fb.9000-config.cfg&lt;br /&gt;
0d00h01m17s:D:DHCPC: sending TFTP request for bootfile name FWS648G-Switch0024.38fb.9000-config.cfg&lt;br /&gt;
0d00h01m01s:D:DHCPC: sending TFTP request for bootfile name FWS648G-Switch0024.38fb.9000-config.cfg &lt;br /&gt;
&lt;br /&gt;
-- Resolution --&lt;br /&gt;
&lt;br /&gt;
If the user does not want to see such a message, users can do the following: &lt;br /&gt;
&lt;br /&gt;
1. Configure the IP address on the switch statically&lt;br /&gt;
2. Configure no ip dhcp-client enable command.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ref: [https://support.ruckuswireless.com/articles/000006567]&lt;br /&gt;
&lt;br /&gt;
== SFP ==&lt;br /&gt;
&lt;br /&gt;
GBIC&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# show media&lt;br /&gt;
...&lt;br /&gt;
Port 1/3/1:  Type  : EMPTY&lt;br /&gt;
Port 1/3/2:  Type  : EMPTY&lt;br /&gt;
Port 1/3/3:  Type  : 1G M-TX(SFP)&lt;br /&gt;
Port 1/3/4:  Type  : EMPTY&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# sh media et 1/3/3&lt;br /&gt;
Port   1/3/3: Type  : 1G M-TX(SFP)&lt;br /&gt;
             Vendor: XXX    Version: D1&lt;br /&gt;
             Part# : SFP-1000BASE-TX    Serial#: XXX&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 # sh int bri&lt;br /&gt;
 ..&lt;br /&gt;
 1/3/3      Up      Forward Full 1G    None  No  1    0   xxxx.xxxx.xxxx&lt;br /&gt;
&lt;br /&gt;
 #sh int et 1/3/3&lt;br /&gt;
 10GigabitEthernet1/3/3 is up, line protocol is up&lt;br /&gt;
&lt;br /&gt;
Note: If a 1-Gbps optic transceiver is inserted, you must configure the port using the &#039;&#039;speed-duplex 1000-full-master&#039;&#039; command at the interface level. &amp;lt;ref&amp;gt;https://docs.commscope.com/bundle/icx7150-installguide/page/GUID-B346251F-DFCC-4441-B047-6E3A3E88839C.html&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Enable port: &amp;lt;ref&amp;gt;https://docs.commscope.com/bundle/icx7150-installguide/page/GUID-B346251F-DFCC-4441-B047-6E3A3E88839C.html&amp;lt;/ref&amp;gt;&lt;br /&gt;
 # conf term&lt;br /&gt;
 # int ethernet 1/3/3&lt;br /&gt;
 # speed-duplex 1000-full-master&lt;br /&gt;
&lt;br /&gt;
or short form: &amp;lt;ref&amp;gt;https://community.ruckuswireless.com/t5/ICX-Switches/Configuring-SFP-port-on-7150-C08p/td-p/27124&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
config t&lt;br /&gt;
int e 1/2/1&lt;br /&gt;
speed 1000-full&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# sh run&lt;br /&gt;
...&lt;br /&gt;
stack unit 1&lt;br /&gt;
  module 1 icx7150-48pf-poe-port-management-module&lt;br /&gt;
  module 2 icx7150-2-copper-port-2g-module&lt;br /&gt;
  module 3 icx7150-4-sfp-plus-port-40g-module&lt;br /&gt;
  stack-port 1/3/1&lt;br /&gt;
  stack-port 1/3/3&lt;br /&gt;
!&lt;br /&gt;
interface ethernet 1/3/3&lt;br /&gt;
 speed-duplex 1000-full&lt;br /&gt;
!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Long-Reach Multimode Adapter Module ==&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Ruckus ICX 7150, ICX 7250, and ICX 7750 Ethernet switches require a Long-Reach Multimode (LRM) adapter module to support LRM optics connections.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Ref: https://docs.commscope.com/bundle/icx7150-installguide/page/GUID-99B65237-56EC-456E-8DEB-07903584DBDD.html&lt;br /&gt;
&lt;br /&gt;
== License Upgrades ==&lt;br /&gt;
&lt;br /&gt;
=== ICX 7150-48 10G Upgrade ===&lt;br /&gt;
&lt;br /&gt;
Sample:&lt;br /&gt;
 CoE certificate license to upgrade any ICX 7150 24-port or 48-port model from 4x 1G SFP to 2x 1G SFP &amp;amp; 2x 10G SFP+ uplink ports.&lt;br /&gt;
 https://www.ispsupplies.com/Brocade-BR-ICX-7150-41U210-P-01&lt;br /&gt;
 SKU: BR-ICX-7150-41U210-P-01&lt;br /&gt;
 $750&lt;br /&gt;
&lt;br /&gt;
 CoE certificate license to upgrade any ICX 7150 24-port or 48-port model from 2x 1G SFP &amp;amp; 2x 10G SFP+ to 4x 10G SFP+ uplink ports. Also includes L3 features (OSPF, VRRP, PIM, PBR)&lt;br /&gt;
 https://www.ispsupplies.com/Brocade-BR-ICX-7150-210U410R-P-01&lt;br /&gt;
 SKU: BR-ICX-7150-210U410R-P-01&lt;br /&gt;
 $750.00&lt;br /&gt;
&lt;br /&gt;
 CoE certificate license to upgrade any ICX 7150 24-port or 48-port model from 4x 1G SFP to 4x 10G SFP+ uplink ports. Also includes L3 features (OSPF, VRRP, PIM, PBR)&lt;br /&gt;
 https://www.ispsupplies.com/Brocade-BR-ICX-7150-41U410R-P-01&lt;br /&gt;
 SKU: BR-ICX-7150-41U410R-P-01&lt;br /&gt;
 $1,500.00&lt;br /&gt;
&lt;br /&gt;
So license progression is: 4x1G -&amp;gt; 2x1G &amp;amp; 2x10G -&amp;gt; 4x10G&lt;br /&gt;
&lt;br /&gt;
== keywords ==&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=Ruckus/ICX-7150&amp;diff=9839</id>
		<title>Ruckus/ICX-7150</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=Ruckus/ICX-7150&amp;diff=9839"/>
		<updated>2026-04-20T19:38:45Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: /* USB C Management Console Connection */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Ports ==&lt;br /&gt;
&lt;br /&gt;
Left Side of Switch:&lt;br /&gt;
* USB-C Console Port&lt;br /&gt;
* RJ-45 Console Port&lt;br /&gt;
* Out-of-band Management Port RJ-45&lt;br /&gt;
&lt;br /&gt;
ICX7150-24 - 24 port Middle Module: &amp;quot;UNIT 1: SL 1: ICX7150-24-2X10G_2X1G 24-port Management Module&amp;quot;&lt;br /&gt;
* 1, ..., 24: (Ethernet ports 1/1/1 to 1/1/24)&lt;br /&gt;
** Odds are on top, Evens are on bottom&lt;br /&gt;
&lt;br /&gt;
ICX7150-48 - 48 port Middle Module: &amp;quot;UNIT 1: SL 1: ICX7150-48PF-4X1G POE 48-port Management Module&amp;quot;&lt;br /&gt;
* 1, ..., 48: (Ethernet ports 1/1/1 to 1/1/48)&lt;br /&gt;
** Odds are on top, Evens are on bottom&lt;br /&gt;
&lt;br /&gt;
Right Module &amp;quot;UNIT 1: SL 2: ICX7150-2X1GC 2-port 2G Module&amp;quot;:&lt;br /&gt;
* C1, C2: RJ-45 Uplink Port (Ethernet ports 1/2/1 to 1/2/2)&lt;br /&gt;
** C1 is on top, C2 is on bottom&lt;br /&gt;
&lt;br /&gt;
Right Module &amp;quot;UNIT 1: SL 3: ICX7150-4X10GF 4-port 40G Module&amp;quot;&lt;br /&gt;
* X1, X2, X3, X4: SFP+ Uplink / Stacking ports (Ethernet ports 1/3/1 to 1/3/4)&lt;br /&gt;
** Odds are on top, Evens are on bottom&lt;br /&gt;
&lt;br /&gt;
== USB C Management Console Connection ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[ 1783.328741] usb 3-3: new full-speed USB device number 4 using xhci_hcd&lt;br /&gt;
[ 1783.470048] usb 3-3: New USB device found, idVendor=10c4, idProduct=ea60&lt;br /&gt;
[ 1783.470052] usb 3-3: New USB device strings: Mfr=1, Product=2, SerialNumber=3&lt;br /&gt;
[ 1783.470054] usb 3-3: Product: CP2104 USB to UART Bridge Controller&lt;br /&gt;
[ 1783.470055] usb 3-3: Manufacturer: Silicon Labs&lt;br /&gt;
[ 1783.470057] usb 3-3: SerialNumber: 017C6EED&lt;br /&gt;
[ 1783.534393] usbcore: registered new interface driver usbserial&lt;br /&gt;
[ 1783.534405] usbcore: registered new interface driver usbserial_generic&lt;br /&gt;
[ 1783.534416] usbserial: USB Serial support registered for generic&lt;br /&gt;
[ 1783.550518] usbcore: registered new interface driver cp210x&lt;br /&gt;
[ 1783.550531] usbserial: USB Serial support registered for cp210x&lt;br /&gt;
[ 1783.550559] cp210x 3-3:1.0: cp210x converter detected&lt;br /&gt;
[ 1783.551382] usb 3-3: cp210x converter now attached to ttyUSB0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# tio -b 9600 /dev/ttyUSB0&lt;br /&gt;
[tio 07:47:59] tio v1.32&lt;br /&gt;
[tio 07:47:59] Press ctrl-t q to quit&lt;br /&gt;
[tio 07:47:59] Connected&lt;br /&gt;
&lt;br /&gt;
ICX7150-48-Switch&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Parameter&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Value&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Baud Rate&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;9600&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Data Bits&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;8&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Parity&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;None&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Stop Bits&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Flow Control&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;None&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Initial View ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ICX7150-48-Switch&amp;gt;enable&lt;br /&gt;
No password has been assigned yet...&lt;br /&gt;
ICX7150-48-Switch#show config&lt;br /&gt;
INFO: empty config data in the primary area, try to read from backup&lt;br /&gt;
INFO: empty config data in the backup area also&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Show IP ==&lt;br /&gt;
&lt;br /&gt;
Initially the switch is configured for DHCP, with telnet access.  To see the address:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ICX7150-48-Switch#show ip&lt;br /&gt;
&lt;br /&gt;
     Switch IP address: 10.10.10.228&lt;br /&gt;
&lt;br /&gt;
           Subnet mask: 255.255.255.0&lt;br /&gt;
&lt;br /&gt;
Default router address: 10.10.10.1&lt;br /&gt;
   TFTP server address: 10.248.1.206&lt;br /&gt;
Configuration filename: None&lt;br /&gt;
        Image filename: None&lt;br /&gt;
            DNS Server: 10.10.10.1&lt;br /&gt;
                IP MTU: 1500&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Initial telnet: &amp;quot;The ICX7150-24F, ICX7150-C08P, and ICX7150-C10ZP switches ship from the factory with SSH enabled and Telnet disabled. All other switches have Telnet enabled only.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
ref: http://docs.ruckuswireless.com/fastiron/hardware/ruckus-icx-switch-qsg/GUID-A7D29C1A-2288-4121-A0B8-F7136EAF9291.html&lt;br /&gt;
&lt;br /&gt;
== Assign IP ==&lt;br /&gt;
&lt;br /&gt;
 (config)# ip address 172.31.0.1/24&lt;br /&gt;
or&lt;br /&gt;
 (config)# ip address 172.31.0.1 255.255.255.0&lt;br /&gt;
&lt;br /&gt;
== Privilege Levels ==&lt;br /&gt;
&lt;br /&gt;
3 privileged levels:&lt;br /&gt;
#  super-user-password           Super-user level password&lt;br /&gt;
#  port-config-password          Port level configuration password&lt;br /&gt;
#  read-only-password            Read-only level password&lt;br /&gt;
&lt;br /&gt;
* Super User level - Allows complete read-and-write access to the system. This is generally for system administrators and is the only management privilege level that allows you to configure passwords.&lt;br /&gt;
* Port Configuration level - Allows read-and-write access for specific ports but not for global (system-wide) parameters.&lt;br /&gt;
* Read-only level - Allows access to the Privileged EXEC mode and User EXEC mode of the CLI but only with read access.&lt;br /&gt;
&lt;br /&gt;
Set the password by (with enable using super-user&#039;s password) &lt;br /&gt;
 enable&lt;br /&gt;
 conf term&lt;br /&gt;
&lt;br /&gt;
1. Set Super User level password:&lt;br /&gt;
 enable super-user-password [PASSWORD]&lt;br /&gt;
&lt;br /&gt;
2. Set Port Configure password:&lt;br /&gt;
 enable port-config-password [PASSWORD]&lt;br /&gt;
&lt;br /&gt;
3. Set Read Only level password:&lt;br /&gt;
 enable read-only-password [PASSWORD]&lt;br /&gt;
&lt;br /&gt;
To see which mode you are logged in as, use &amp;quot;sh who&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
ref: https://docs.ruckuswireless.com/fastiron/08.0.60/fastiron-08060-securityguide/GUID-F35168E7-729D-46A2-ACE1-68148B01443D.html&lt;br /&gt;
&lt;br /&gt;
== Require Login ==&lt;br /&gt;
&lt;br /&gt;
 aaa authentication web-server default local&lt;br /&gt;
 aaa authentication login default local&lt;br /&gt;
&lt;br /&gt;
== User Logins ==&lt;br /&gt;
&lt;br /&gt;
 no username super&lt;br /&gt;
 username admin [password]&lt;br /&gt;
&lt;br /&gt;
== Recover from a Lost Password ==&lt;br /&gt;
&lt;br /&gt;
# Reboot the device.&lt;br /&gt;
# At the initial boot prompt at system startup, enter &#039;&#039;&#039;b&#039;&#039;&#039; to enter the boot monitor mode.&lt;br /&gt;
# Enter &#039;&#039;&#039;no password&#039;&#039;&#039; at the prompt. (You cannot abbreviate this command.) This command will cause the device to bypass the system password check.&lt;br /&gt;
# Enter &#039;&#039;&#039;boot system flash primary&#039;&#039;&#039; at the prompt.&lt;br /&gt;
&lt;br /&gt;
ref: https://docs.ruckuswireless.com/fastiron/08.0.60/fastiron-08060-securityguide/GUID-986D5DF0-BF7E-4327-9030-396433DFFD9D.html&lt;br /&gt;
&lt;br /&gt;
== Show Software Version and Hardware Model ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;sh ver&lt;br /&gt;
  Copyright (c) 2017 Ruckus Wireless, Inc. All rights reserved.&lt;br /&gt;
    UNIT 1: compiled on Apr 12 2019 at 11:46:50 labeled as SPS08070db&lt;br /&gt;
      (25717216 bytes) from Primary SPS08070db.bin&lt;br /&gt;
        SW: Version 08.0.70dbT211&lt;br /&gt;
      Compressed Boot-Monitor Image size = 786944, Version:10.1.14T225 (mnz10114)&lt;br /&gt;
       Compiled on Thu Nov 15 12:59:22 2018&lt;br /&gt;
&lt;br /&gt;
  HW: Stackable ICX7150-48-POEF&lt;br /&gt;
==========================================================================&lt;br /&gt;
UNIT 1: SL 1: ICX7150-48PF-4X1G POE 48-port Management Module&lt;br /&gt;
      Serial  #:XXXXXXXXXXX&lt;br /&gt;
      Current License: 4X1G&lt;br /&gt;
      P-ASIC  0: type B160, rev 11  Chip BCM56160_B0&lt;br /&gt;
==========================================================================&lt;br /&gt;
UNIT 1: SL 2: ICX7150-2X1GC 2-port 2G Module&lt;br /&gt;
==========================================================================&lt;br /&gt;
UNIT 1: SL 3: ICX7150-4X10GF 4-port 40G Module&lt;br /&gt;
==========================================================================&lt;br /&gt;
 1000 MHz ARM processor ARMv7 88 MHz bus&lt;br /&gt;
 8192 KB boot flash memory&lt;br /&gt;
 2048 MB code flash memory&lt;br /&gt;
 1024 MB DRAM&lt;br /&gt;
STACKID 1  system uptime is 336 day(s) 1 hour(s) 11 minute(s) 35 second(s)&lt;br /&gt;
The system started at 04:05:00 GMT+00 Sat Jan 01 2000&lt;br /&gt;
&lt;br /&gt;
The system : started=cold start&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Enable SSH ==&lt;br /&gt;
&lt;br /&gt;
(Note telnet is enabled by default, and doesn&#039;t require user)&lt;br /&gt;
&lt;br /&gt;
crypto key generate - http://docs.ruckuswireless.com/fastiron/08.0.50/fastiron-08050-commandref/GUID-74724EE0-E8FB-46A1-8FBA-9E2F342D5B93.html&lt;br /&gt;
:To enable SSH, you generate a DSA or RSA host key on the device. The SSH server on the Brocade device uses this host DSA or RSA key, along with a dynamically generated server DSA or RSA key pair, to negotiate a session key and encryption method with the client trying to connect to it. While the SSH listener exists at all times, sessions cannot be started from clients until a host key is generated. After a host key is generated, clients can start sessions. When a host key is generated, it is saved to the flash memory of all management modules. The time to initially generate SSH keys varies depending on the configuration, and can be from a under a minute to several minutes.&lt;br /&gt;
: To disable SSH, you delete all of the host keys from the device. When a host key is deleted, it is deleted from the flash memory of all management modules.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Enable SSH: [https://www.shanekillen.com/2014/03/brocade-switch-how-to-configure-ssh-and.html]&lt;br /&gt;
 ## Generate keys&lt;br /&gt;
 crypto key generate dsa&lt;br /&gt;
 # Add admin user:&lt;br /&gt;
 username admin pri 0 password passphrase&lt;br /&gt;
 # enable &lt;br /&gt;
 aaa authentication login default local&lt;br /&gt;
&lt;br /&gt;
then wait... takes about 5 minutes, and you will eventually see:&lt;br /&gt;
 DSA Key pair is successfully created&lt;br /&gt;
&lt;br /&gt;
..&lt;br /&gt;
..&lt;br /&gt;
&lt;br /&gt;
 root@server:~# ssh admin@10.10.10.100&lt;br /&gt;
 Unable to negotiate with 10.10.10.100 port 22: no matching key exchange method found. Their offer: diffie-hellman-group1-sha1&lt;br /&gt;
&lt;br /&gt;
fix with: (from switch)&lt;br /&gt;
 ip ssh key-exchange-method dh-group14-sha1&lt;br /&gt;
&lt;br /&gt;
or from SSH:&lt;br /&gt;
  ssh -v -oKexAlgorithms=+diffie-hellman-group1-sha1 -oHostKeyAlgorithms=+ssh-dss -caes256-cbc 10.10.10.100&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Generate keys:&lt;br /&gt;
 (config)#crypto key generate rsa modulus 2048&lt;br /&gt;
 (config)#ip ssh key-exchange-method dh-group14-sha1&lt;br /&gt;
 Warning: This operation would close all existing SSH connection.&lt;br /&gt;
 (config)#username admin privilege 0 password [PASSWORD]&lt;br /&gt;
    DECIMAL   &amp;lt;0 READ-WRITE, 4 PORT-CONFIG, 5 READ-ONLY&amp;gt; User privilege level&lt;br /&gt;
 (config)#aaa authentication login default local&lt;br /&gt;
&lt;br /&gt;
To require the enable login locally as well:&lt;br /&gt;
 (config)#aaa authentication enable default local&lt;br /&gt;
&lt;br /&gt;
To auto go to privileged mode after login (use in labs only, not production):&lt;br /&gt;
 (config)#aaa authentication login privilege-mode &lt;br /&gt;
&lt;br /&gt;
To change password:&lt;br /&gt;
 (config)#username admin password [PASSWORD]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ref: https://robrobstation.com/2017/07/17/ruckus-icx7150-c12p-initial-configuration/&lt;br /&gt;
&lt;br /&gt;
Sample config:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ICX7150-48-Switch(config)#write terminal&lt;br /&gt;
Current configuration:&lt;br /&gt;
!&lt;br /&gt;
ver 08.0.61aT211&lt;br /&gt;
!&lt;br /&gt;
stack unit 1&lt;br /&gt;
  module 1 icx7150-48-port-management-module&lt;br /&gt;
  module 2 icx7150-2-copper-port-2g-module&lt;br /&gt;
  module 3 icx7150-4-sfp-plus-port-40g-module&lt;br /&gt;
!&lt;br /&gt;
!&lt;br /&gt;
!&lt;br /&gt;
!&lt;br /&gt;
!&lt;br /&gt;
!&lt;br /&gt;
!&lt;br /&gt;
!&lt;br /&gt;
!&lt;br /&gt;
!&lt;br /&gt;
aaa authentication enable default local&lt;br /&gt;
aaa authentication login default local&lt;br /&gt;
ip address 10.10.10.228 255.255.255.0 dynamic&lt;br /&gt;
ip default-gateway 10.10.10.1 dynamic&lt;br /&gt;
!&lt;br /&gt;
username admin password .....&lt;br /&gt;
!&lt;br /&gt;
!&lt;br /&gt;
interface ethernet 1/3/1&lt;br /&gt;
 speed-duplex 1000-full&lt;br /&gt;
!&lt;br /&gt;
interface ethernet 1/3/2&lt;br /&gt;
 speed-duplex 1000-full&lt;br /&gt;
!&lt;br /&gt;
interface ethernet 1/3/3&lt;br /&gt;
 speed-duplex 1000-full&lt;br /&gt;
!&lt;br /&gt;
interface ethernet 1/3/4&lt;br /&gt;
 speed-duplex 1000-full&lt;br /&gt;
!&lt;br /&gt;
!&lt;br /&gt;
!&lt;br /&gt;
!&lt;br /&gt;
!&lt;br /&gt;
!&lt;br /&gt;
ip ssh  key-exchange-method dh-group14-sha1&lt;br /&gt;
!&lt;br /&gt;
!&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Disable SSH ===&lt;br /&gt;
&lt;br /&gt;
Delete the host keys&lt;br /&gt;
&lt;br /&gt;
 crypto key zeroize&lt;br /&gt;
&lt;br /&gt;
 crypto key zeroize dsa&lt;br /&gt;
&lt;br /&gt;
crypto key generate - http://docs.ruckuswireless.com/fastiron/08.0.50/fastiron-08050-commandref/GUID-74724EE0-E8FB-46A1-8FBA-9E2F342D5B93.html&lt;br /&gt;
: To disable SSH, you delete all of the host keys from the device. When a host key is deleted, it is deleted from the flash memory of all management modules.&lt;br /&gt;
&lt;br /&gt;
== Disable Telnet ==&lt;br /&gt;
&lt;br /&gt;
Once SSH is enabled, telnet is best disabled.&lt;br /&gt;
&lt;br /&gt;
 (config)#no telnet server&lt;br /&gt;
&lt;br /&gt;
== Clock ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Daylight Saving (Summer Time) [https://docs.commscope.com/bundle/fastiron-08091-managementguide/page/GUID-E670EE11-FBD6-4D1E-9099-6E231887D245.html]&lt;br /&gt;
 clock summer-time zone us pacific start 02-28-21 02:00:00 end 10-30-21 02:00:00 offset 60&lt;br /&gt;
&lt;br /&gt;
Note: Will have to be updated each year.&lt;br /&gt;
&lt;br /&gt;
== Enable POE ==&lt;br /&gt;
&lt;br /&gt;
See [[Ruckus/ICX-6450-48#Enable POE]]&lt;br /&gt;
&lt;br /&gt;
== Firmware ==&lt;br /&gt;
&lt;br /&gt;
=== Firmware Versions ===&lt;br /&gt;
&lt;br /&gt;
ICX FastIron Stable series:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
08.0.95p	2024-06-27&lt;br /&gt;
08.0.95n	2024-01-31  *** recommended stable ***&lt;br /&gt;
08.0.95m	2023-08-24&lt;br /&gt;
08.0.95k	2023-06-16&lt;br /&gt;
08.0.95j	2023-06-16&lt;br /&gt;
08.0.95h	2022-09-02&lt;br /&gt;
...&lt;br /&gt;
08.0.95 	2020-09-14&lt;br /&gt;
...&lt;br /&gt;
08.0.90d	2019-09-27 *** used as jump to ufi ***&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 https://support.ruckuswireless.com/software/1186-ruckus-icx-7xxx-icx-6xxxx-campus-switch-firmware-download&lt;br /&gt;
&lt;br /&gt;
 https://support.ruckuswireless.com/products/108-ruckus-icx-7150-campus-switches?open=document#firmwares&lt;br /&gt;
&lt;br /&gt;
 https://support.ruckuswireless.com/products/108-ruckus-icx-7150-campus-switches&lt;br /&gt;
 Recommended Software: (as of 2024.07.08)&lt;br /&gt;
  Stability Release: RUCKUS ICX FastIron 08.0.95n (GA) Software Release (.zip)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
&amp;quot;Ruckus ICX software currently has two recommended release types; Stability and Technology.&lt;br /&gt;
&lt;br /&gt;
Stability Release: This is for customers where stability is of utmost importance. This release may not contain every feature available for your product.&lt;br /&gt;
&lt;br /&gt;
Technology Release: This is for customers looking to utilize the maximum feature set available for your product.&lt;br /&gt;
&lt;br /&gt;
We recommend most customers utilize the Stability Release if it contains all needed features for your network. A Technology Release is recommended if your network requires newer features not available in the Stability Release.&amp;quot;&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 08.0.95n ===&lt;br /&gt;
&lt;br /&gt;
 RUCKUS ICX FastIron 08.0.95n (GA) Software Release (.zip)&lt;br /&gt;
 https://support.ruckuswireless.com/software/3958-ruckus-icx-fastiron-08-0-95n-ga-software-release-zip&lt;br /&gt;
&lt;br /&gt;
 Applies to: ICX7150, ICX7250, ICX7450, ICX7550, ICX7650, ICX7750, ICX7850&lt;br /&gt;
&lt;br /&gt;
=== 08.0.95m ===&lt;br /&gt;
&lt;br /&gt;
 RUCKUS ICX FastIron 08.0.95m (GA) Software Release (.zip)&lt;br /&gt;
 https://support.ruckuswireless.com/software/3749-ruckus-icx-fastiron-08-0-95m-ga-software-release-zip&lt;br /&gt;
&lt;br /&gt;
 Applies to: ICX7150, ICX7250, ICX7450, ICX7550, ICX7650, ICX7750, ICX7850&lt;br /&gt;
&lt;br /&gt;
=== Firmware Notes ===&lt;br /&gt;
&lt;br /&gt;
Newer firmware combines the bootrom and firmware images into a single file, called the &#039;&#039;&#039;Unified FastIron Image (UFI)&#039;&#039;&#039; [https://docs.commscope.com/bundle/fastiron-08091-upgradeguide/page/GUID-C1E90D8F-E1CB-48CE-9369-6605EB035602.html]&lt;br /&gt;
&lt;br /&gt;
 &amp;quot;Ruckus recommends that you always use the manifest file for any image upgrade or downgrade.&amp;quot; [https://docs.commscope.com/bundle/fastiron-08091-upgradeguide/page/GUID-B8B3B6B1-0453-4713-B894-0EFAB084B1D6.html]&lt;br /&gt;
&lt;br /&gt;
 &amp;quot;If you are upgrading from FastIron release 08.0.80 to release 08.0.90, Ruckus recommends using SCP to transfer files.&amp;quot; [https://docs.commscope.com/bundle/fastiron-08091-upgradeguide/page/GUID-B8B3B6B1-0453-4713-B894-0EFAB084B1D6.html]&lt;br /&gt;
&lt;br /&gt;
 &amp;quot;Software images for all RUCKUS ICX devices can be uploaded and downloaded between flash modules on the device and a &#039;&#039;&#039;TFTP, SCP, HTTPS, or USB&#039;&#039;&#039; module on the network.&amp;quot; [https://docs.commscope.com/bundle/fastiron-08091-upgradeguide/page/GUID-C8148B03-D98C-4F4D-939C-9111CECB0601.html]&lt;br /&gt;
&lt;br /&gt;
 Ruckus FastIron Software Upgrade Guide, 08.0.90 PDF [https://support.alcadis.nl/Support_files/Ruckus/ICX//Software%20Manuals/Ruckus%20ICX%20FastIron%20v08.0.90/Ruckus%20FastIron%2008.0.90%20Software%20Upgrade%20Guide.pdf]&lt;br /&gt;
&lt;br /&gt;
 username: super&lt;br /&gt;
 default password: sp-admin&lt;br /&gt;
&lt;br /&gt;
 copy tftp system-manifest 10.0.0.10 FI08090j_Manifest.txt all-images-primary&lt;br /&gt;
&lt;br /&gt;
 copy tftp flash 10.0.0.10 ICX7150/Images/SPS08090j.bin primary&lt;br /&gt;
&lt;br /&gt;
 copy tftp system-manifest 10.0.0.10 FI08090_Manifest.txt all_images_primary&lt;br /&gt;
 copy tftp system-manifest 10.0.0.10 FI08090_Manifest.txt primary&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 ! Doesn&#039;t work, due to TFTP issues&lt;br /&gt;
 copy tftp system-manifest 10.0.0.10 08080f/FI08080f_Manifest.txt all-images-primary&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 copy tftp flash 10.0.0.10 08080f/ICX7150/Boot/mnz10114.bin bootrom&lt;br /&gt;
 ! wait for this command to complete!&lt;br /&gt;
 ! wait for this command to complete!&lt;br /&gt;
 ! wait for this command to complete!&lt;br /&gt;
&lt;br /&gt;
 erase flash primary&lt;br /&gt;
&lt;br /&gt;
 copy tftp flash 10.0.0.10 08080f/ICX7150/Images/SPS08080f.bin primary&lt;br /&gt;
 ! wait for this command to complete!&lt;br /&gt;
 ! wait for this command to complete!&lt;br /&gt;
 ! wait for this command to complete!&lt;br /&gt;
&lt;br /&gt;
 erase flash secondary&lt;br /&gt;
&lt;br /&gt;
 copy tftp flash 10.0.0.10 08080f/ICX7150/Images/SPR08080f.bin secondary&lt;br /&gt;
 ! wait for this command to complete!&lt;br /&gt;
 ! wait for this command to complete!&lt;br /&gt;
 ! wait for this command to complete!&lt;br /&gt;
&lt;br /&gt;
 show flash&lt;br /&gt;
&lt;br /&gt;
 config t&lt;br /&gt;
 boot sys flash prim&lt;br /&gt;
 exit&lt;br /&gt;
 wr mem&lt;br /&gt;
 reload&lt;br /&gt;
&lt;br /&gt;
 copy tftp system-manifest 10.0.0.10 08090j/FI08090j_Manifest.txt all-images-primary&lt;br /&gt;
 copy tftp system-manifest 10.0.0.10 08090j/FI08090j_Manifest.txt primary&lt;br /&gt;
 copy tftp system-manifest 10.0.0.10 08090j/FI08090j_Manifest.txt secondary&lt;br /&gt;
&lt;br /&gt;
 copy scp system-manifest 10.0.0.10 /tftp/08090j/FI08090j_Manifest.txt primary&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 copy tftp system-manifest 10.0.0.10 08090d/FI08090d_Manifest.txt all-images-primary&lt;br /&gt;
 copy tftp system-manifest 10.0.0.10 08090d/FI08090d_Manifest.txt primary&lt;br /&gt;
 copy tftp system-manifest 10.0.0.10 08090d/FI08090d_Manifest.txt secondary&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 erase flash primary&lt;br /&gt;
 erase flash secondary&lt;br /&gt;
&lt;br /&gt;
 copy tftp flash 10.0.0.10 08090d/ICX7150/Boot/mnz10115.bin bootrom&lt;br /&gt;
 copy tftp flash 10.0.0.10 08090d/ICX7150/Images/SPS08090d.bin primary&lt;br /&gt;
 copy tftp flash 10.0.0.10 08090d/ICX7150/Images/SPR08090d.bin secondary&lt;br /&gt;
&lt;br /&gt;
 copy tftp flash 10.0.0.10 08090d/ICX7150/Images/SPS08090dufi.bin primary&lt;br /&gt;
 copy tftp flash 10.0.0.10 08090d/ICX7150/Images/SPS08090dufi.bin secondary&lt;br /&gt;
 copy tftp flash 10.0.0.10 08090d/ICX7150/Images/SPR08090dufi.bin secondary&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 erase flash primary&lt;br /&gt;
&lt;br /&gt;
 copy tftp flash 10.0.0.10 08090j/ICX7150/Images/SPS08090jufi.bin primary&lt;br /&gt;
&lt;br /&gt;
 erase flash secondary&lt;br /&gt;
&lt;br /&gt;
 copy tftp flash 10.0.0.10 08090j/ICX7150/Images/SPR08090jufi.bin secondary&lt;br /&gt;
&lt;br /&gt;
 ! Enable SSH&lt;br /&gt;
 crypto key generate dsa&lt;br /&gt;
&lt;br /&gt;
 conf t&lt;br /&gt;
 crypto key generate dsa&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 copy scp flash 10.0.0.10 /tftp/08090d/ICX7150/Boot/mnz10115.bin bootrom&lt;br /&gt;
 copy scp flash 10.0.0.10 /tftp/08090d/ICX7150/Images/SPS08090d.bin primary&lt;br /&gt;
&lt;br /&gt;
 show flash&lt;br /&gt;
 config t&lt;br /&gt;
 boot sys flash prim&lt;br /&gt;
 exit&lt;br /&gt;
 wr mem&lt;br /&gt;
 reload&lt;br /&gt;
&lt;br /&gt;
 copy scp flash 10.0.0.10 /tftp/08090j/ICX7150/Images/SPS08090jufi.bin primary&lt;br /&gt;
&lt;br /&gt;
 copy scp flash 10.0.0.10 /tftp/08090j/ICX7150/Images/SPS08090jufi.bin secondary&lt;br /&gt;
&lt;br /&gt;
 ! Copy primary to secondary&lt;br /&gt;
 copy flash flash secondary&lt;br /&gt;
&lt;br /&gt;
 show flash&lt;br /&gt;
 config t&lt;br /&gt;
 boot sys flash prim&lt;br /&gt;
 exit&lt;br /&gt;
 wr mem&lt;br /&gt;
 reload&lt;br /&gt;
&lt;br /&gt;
 ! Write POE Flash&lt;br /&gt;
 inline power install-firmware stack-unit 1 scp 10.0.0.10 /tftp/08090j/ICX7150/Firmware/icx7xxx_poe_02.1.1.b002.fw&lt;br /&gt;
&lt;br /&gt;
 Error: No Unit in the system has PoE module&lt;br /&gt;
&lt;br /&gt;
 poe fw ref: https://docs.commscope.com/bundle/fastiron-08030-adminguide/page/GUID-2E378DEB-4CD3-41F8-90E4-28EA47BCAD28.html&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sh inl pow det&lt;br /&gt;
&lt;br /&gt;
Firmware&lt;br /&gt;
Version&lt;br /&gt;
----------------&lt;br /&gt;
02.1.1 Build 002&lt;br /&gt;
&lt;br /&gt;
Hardware&lt;br /&gt;
Version&lt;br /&gt;
----------------&lt;br /&gt;
V2R4&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 boot system flash secondary&lt;br /&gt;
&lt;br /&gt;
 # permanent&lt;br /&gt;
 boot system flash primary yes&lt;br /&gt;
&lt;br /&gt;
 ref: http://docs.ruckuswireless.com/fastiron/08.0.50/fastiron-08050-commandref/GUID-9B008914-403A-4FE1-8445-5DCD63F9A1A2.html&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 sh boot-preference&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 Configure SSH on a Ruckus Switch | me@luiscachog.io - &lt;br /&gt;
 https://luiscachog.io/configure-ruckus-switch/&lt;br /&gt;
&lt;br /&gt;
 device(config)# crypto-ssl certificate generate&lt;br /&gt;
 device(config)# username USERNAME password PASSWORD&lt;br /&gt;
 device(config)# aaa authentication login default local&lt;br /&gt;
 device(config)# aaa authentication web-server default local&lt;br /&gt;
&lt;br /&gt;
== TFTP session timed out - on boot ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Summary: TFTP session timed out messages on console after boot up&lt;br /&gt;
&lt;br /&gt;
Question: Why did TFTP session time out messages on console after boot up?&lt;br /&gt;
&lt;br /&gt;
Customer Environment: FI 07.1.00&lt;br /&gt;
&lt;br /&gt;
-- Root Cause --&lt;br /&gt;
&lt;br /&gt;
In the FastIron series, starting from FI 07.1.00, DHCP Client-Based Auto-Configuration is supported and enabled by default. DHCP&lt;br /&gt;
Client-Based Auto-Configuration allows Layer 2 and Layer 3 devices to automatically obtain leased IP addresses through a DHCP server,&lt;br /&gt;
negotiate an address lease renewal, and obtain the flash image and configuration files. For the details, please refer to FastIron&lt;br /&gt;
configuration guide.&lt;br /&gt;
&lt;br /&gt;
The above messages mean FastIron switch got an IP address from the DHCP server and is trying to get a configuration file from the&lt;br /&gt;
TFTP server but there is no resposne from the TFTP server. The messages can be ignored if the user is not trying to download a&lt;br /&gt;
configuration file from TFTP server.&lt;br /&gt;
&lt;br /&gt;
-- Troubleshooting Steps --&lt;br /&gt;
&lt;br /&gt;
In FastIron 7.1.00 and later, when booting up the FastIron switch, the user is seeing the following messages on console and an&lt;br /&gt;
output in show log:&lt;br /&gt;
&lt;br /&gt;
##console&lt;br /&gt;
FWS648G Switch#TFTP session timed out&lt;br /&gt;
FWS648G Switch#TFTP session timed out&lt;br /&gt;
&lt;br /&gt;
##show log&lt;br /&gt;
0d00h03m30s:D:DHCPC: TFTP unable to download running-configuration&lt;br /&gt;
0d00h03m13s:D:DHCPC: sending TFTP request for bootfile name fws-switch.cfg&lt;br /&gt;
0d00h02m56s:D:DHCPC: sending TFTP request for bootfile name brocade.cfg&lt;br /&gt;
0d00h02m39s:D:DHCPC: sending TFTP request for bootfile name foundry.cfg&lt;br /&gt;
0d00h02m22s:D:DHCPC: sending TFTP request for bootfile name FWS648G-Switch0024.38fb.9000.cfg&lt;br /&gt;
0d00h02m05s:D:DHCPC: sending TFTP request for bootfile name FWS648G-Switch0024.38fb.9000-config.cfg&lt;br /&gt;
0d00h01m49s:D:DHCPC: sending TFTP request for bootfile name FWS648G-Switch0024.38fb.9000-config.cfg&lt;br /&gt;
0d00h01m33s:D:DHCPC: sending TFTP request for bootfile name FWS648G-Switch0024.38fb.9000-config.cfg&lt;br /&gt;
0d00h01m17s:D:DHCPC: sending TFTP request for bootfile name FWS648G-Switch0024.38fb.9000-config.cfg&lt;br /&gt;
0d00h01m01s:D:DHCPC: sending TFTP request for bootfile name FWS648G-Switch0024.38fb.9000-config.cfg &lt;br /&gt;
&lt;br /&gt;
-- Resolution --&lt;br /&gt;
&lt;br /&gt;
If the user does not want to see such a message, users can do the following: &lt;br /&gt;
&lt;br /&gt;
1. Configure the IP address on the switch statically&lt;br /&gt;
2. Configure no ip dhcp-client enable command.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ref: [https://support.ruckuswireless.com/articles/000006567]&lt;br /&gt;
&lt;br /&gt;
== SFP ==&lt;br /&gt;
&lt;br /&gt;
GBIC&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# show media&lt;br /&gt;
...&lt;br /&gt;
Port 1/3/1:  Type  : EMPTY&lt;br /&gt;
Port 1/3/2:  Type  : EMPTY&lt;br /&gt;
Port 1/3/3:  Type  : 1G M-TX(SFP)&lt;br /&gt;
Port 1/3/4:  Type  : EMPTY&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# sh media et 1/3/3&lt;br /&gt;
Port   1/3/3: Type  : 1G M-TX(SFP)&lt;br /&gt;
             Vendor: XXX    Version: D1&lt;br /&gt;
             Part# : SFP-1000BASE-TX    Serial#: XXX&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 # sh int bri&lt;br /&gt;
 ..&lt;br /&gt;
 1/3/3      Up      Forward Full 1G    None  No  1    0   xxxx.xxxx.xxxx&lt;br /&gt;
&lt;br /&gt;
 #sh int et 1/3/3&lt;br /&gt;
 10GigabitEthernet1/3/3 is up, line protocol is up&lt;br /&gt;
&lt;br /&gt;
Note: If a 1-Gbps optic transceiver is inserted, you must configure the port using the &#039;&#039;speed-duplex 1000-full-master&#039;&#039; command at the interface level. &amp;lt;ref&amp;gt;https://docs.commscope.com/bundle/icx7150-installguide/page/GUID-B346251F-DFCC-4441-B047-6E3A3E88839C.html&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Enable port: &amp;lt;ref&amp;gt;https://docs.commscope.com/bundle/icx7150-installguide/page/GUID-B346251F-DFCC-4441-B047-6E3A3E88839C.html&amp;lt;/ref&amp;gt;&lt;br /&gt;
 # conf term&lt;br /&gt;
 # int ethernet 1/3/3&lt;br /&gt;
 # speed-duplex 1000-full-master&lt;br /&gt;
&lt;br /&gt;
or short form: &amp;lt;ref&amp;gt;https://community.ruckuswireless.com/t5/ICX-Switches/Configuring-SFP-port-on-7150-C08p/td-p/27124&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
config t&lt;br /&gt;
int e 1/2/1&lt;br /&gt;
speed 1000-full&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# sh run&lt;br /&gt;
...&lt;br /&gt;
stack unit 1&lt;br /&gt;
  module 1 icx7150-48pf-poe-port-management-module&lt;br /&gt;
  module 2 icx7150-2-copper-port-2g-module&lt;br /&gt;
  module 3 icx7150-4-sfp-plus-port-40g-module&lt;br /&gt;
  stack-port 1/3/1&lt;br /&gt;
  stack-port 1/3/3&lt;br /&gt;
!&lt;br /&gt;
interface ethernet 1/3/3&lt;br /&gt;
 speed-duplex 1000-full&lt;br /&gt;
!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Long-Reach Multimode Adapter Module ==&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Ruckus ICX 7150, ICX 7250, and ICX 7750 Ethernet switches require a Long-Reach Multimode (LRM) adapter module to support LRM optics connections.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Ref: https://docs.commscope.com/bundle/icx7150-installguide/page/GUID-99B65237-56EC-456E-8DEB-07903584DBDD.html&lt;br /&gt;
&lt;br /&gt;
== License Upgrades ==&lt;br /&gt;
&lt;br /&gt;
=== ICX 7150-48 10G Upgrade ===&lt;br /&gt;
&lt;br /&gt;
Sample:&lt;br /&gt;
 CoE certificate license to upgrade any ICX 7150 24-port or 48-port model from 4x 1G SFP to 2x 1G SFP &amp;amp; 2x 10G SFP+ uplink ports.&lt;br /&gt;
 https://www.ispsupplies.com/Brocade-BR-ICX-7150-41U210-P-01&lt;br /&gt;
 SKU: BR-ICX-7150-41U210-P-01&lt;br /&gt;
 $750&lt;br /&gt;
&lt;br /&gt;
 CoE certificate license to upgrade any ICX 7150 24-port or 48-port model from 2x 1G SFP &amp;amp; 2x 10G SFP+ to 4x 10G SFP+ uplink ports. Also includes L3 features (OSPF, VRRP, PIM, PBR)&lt;br /&gt;
 https://www.ispsupplies.com/Brocade-BR-ICX-7150-210U410R-P-01&lt;br /&gt;
 SKU: BR-ICX-7150-210U410R-P-01&lt;br /&gt;
 $750.00&lt;br /&gt;
&lt;br /&gt;
 CoE certificate license to upgrade any ICX 7150 24-port or 48-port model from 4x 1G SFP to 4x 10G SFP+ uplink ports. Also includes L3 features (OSPF, VRRP, PIM, PBR)&lt;br /&gt;
 https://www.ispsupplies.com/Brocade-BR-ICX-7150-41U410R-P-01&lt;br /&gt;
 SKU: BR-ICX-7150-41U410R-P-01&lt;br /&gt;
 $1,500.00&lt;br /&gt;
&lt;br /&gt;
So license progression is: 4x1G -&amp;gt; 2x1G &amp;amp; 2x10G -&amp;gt; 4x10G&lt;br /&gt;
&lt;br /&gt;
== keywords ==&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=ICX&amp;diff=9838</id>
		<title>ICX</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=ICX&amp;diff=9838"/>
		<updated>2026-04-20T18:05:02Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: /* Authentication, Authorization, and Accounting */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Ruckus / Brocade Switches =&lt;br /&gt;
&lt;br /&gt;
See [[Ruckus]]&lt;br /&gt;
&lt;br /&gt;
= ICX Switch Consolidation =&lt;br /&gt;
&lt;br /&gt;
In an effort to Consolidate Products, Rucks is focusing on the ICX 7850, 7550 series of switches for core and aggregation layers, as well as the ICX 7150, especially if already in place.  The 7250, 7450, 7650 and 7750 are being discontinued.  For next generation, wireless-first Ruckus is focusing on the ICX 8200 series, with backing of the ICX 7850, 7550.&lt;br /&gt;
&lt;br /&gt;
End of Sale:&lt;br /&gt;
* 7150 - Mar 2025 (end of support Mar 2030)&lt;br /&gt;
* 7250 - Feb 2022 (end of support Dec 2027)&lt;br /&gt;
* 7450 - Nov 2024 (end of support Nov 2029)&lt;br /&gt;
* 7550 - No date posted yet - currently core focus for Ruckus Aggregation Switching&lt;br /&gt;
* 7650 - Dec 2023 (end of support Dec 2028)&lt;br /&gt;
* 7750 - Dec 2023 (end of support Dec 2028)&lt;br /&gt;
* 7850 - No date posted yet - currently core focus for Ruckus Core Switching&lt;br /&gt;
* 8200 - No date posted yet - currently core focus for Ruckus Access Switching&lt;br /&gt;
&lt;br /&gt;
Reference:&lt;br /&gt;
 RUCKUS End of Sale / End of Life Product Datelines &lt;br /&gt;
 https://support.ruckuswireless.com/documents/3631-end-of-sale-and-end-of-life-product-datelines&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ICX         End of Sale         End of Support&lt;br /&gt;
ICX 6450    November 2, 2018    November 2, 2023   EOL DEAD!!!&lt;br /&gt;
ICX 7150    March 10, 2025      March 10, 2030&lt;br /&gt;
ICX 7250    February 7, 2022    December 31, 2027&lt;br /&gt;
ICX 7450    November 14, 2024   November 14, 2029&lt;br /&gt;
ICX 7750    December 31, 2023   December 31, 2028&lt;br /&gt;
ICX 7850    No date posted yet&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== ICX Focus ==&lt;br /&gt;
&lt;br /&gt;
=== Core Switches ===&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;ICX 7850&#039;&#039;&#039;&lt;br /&gt;
* ICX 7750 &amp;lt;EOL 2028&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Aggregation Switches ===&lt;br /&gt;
&lt;br /&gt;
* ICX 7850 (core ^)&lt;br /&gt;
* ICX 7750 (core ^) &amp;lt;EOL 2028&amp;gt;&lt;br /&gt;
* ICX 7650 &amp;lt;EOL 2028&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;ICX 7550&#039;&#039;&#039;&lt;br /&gt;
* ICX 7450 &amp;lt;EOL 2029&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Access Sitches ===&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;ICX 8200&#039;&#039;&#039;&lt;br /&gt;
* ICX 7650 (aggregation ^) &amp;lt;EOL 2028&amp;gt;&lt;br /&gt;
* ICX 7550 (aggregation ^)&lt;br /&gt;
* ICX 7450 (aggregation ^) &amp;lt;EOL 2029&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;ICX 7150&#039;&#039;&#039; &amp;lt;long-term-eol 2030&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Console Cables =&lt;br /&gt;
&lt;br /&gt;
 Baud Bits per second -- 9600&lt;br /&gt;
 Data bits -- 8&lt;br /&gt;
 Parity -- None&lt;br /&gt;
 Stop bits -- 1&lt;br /&gt;
 Flow control -- None&lt;br /&gt;
&lt;br /&gt;
ref &amp;lt;ref&amp;gt;https://docs.commscope.com/bundle/icx7150-installguide/page/GUID-9FB7FB94-16E9-4FB8-8BBB-8B1BDD9B7E79.html&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 6450 Console Cable ==&lt;br /&gt;
&lt;br /&gt;
Brocade Rollover Cable (RJ45):&lt;br /&gt;
 USB Console Cable,USB to RJ45 Console Cable for Cisco Routers/AP Router/Switch Windows, Mac, Linux(1.8m,Blue)&lt;br /&gt;
 https://www.amazon.com/OIKWAN-Compatible-Opengear-Aruba%EF%BC%8CJuniper-Switches/dp/B075V1RGQK&lt;br /&gt;
&lt;br /&gt;
&amp;lt;img src=&amp;quot;https://m.media-amazon.com/images/I/61LZ6srk-+L._SL1000_.jpg&amp;quot; width=&amp;quot;200&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 7150 Console Cable ==&lt;br /&gt;
&lt;br /&gt;
Standard USB C Cable, with a backup of a Brocade Rollover Cable&lt;br /&gt;
&lt;br /&gt;
USB C Cable&lt;br /&gt;
&amp;lt;img src=&amp;quot;https://m.media-amazon.com/images/I/71cPa3L9RoL._AC_SL1500_.jpg&amp;quot; width=&amp;quot;200&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Brocade Rollover Cable (RJ45):&lt;br /&gt;
 USB Console Cable,USB to RJ45 Console Cable for Cisco Routers/AP Router/Switch Windows, Mac, Linux(1.8m,Blue)&lt;br /&gt;
 https://www.amazon.com/OIKWAN-Compatible-Opengear-Aruba%EF%BC%8CJuniper-Switches/dp/B075V1RGQK&lt;br /&gt;
&lt;br /&gt;
&amp;lt;img src=&amp;quot;https://m.media-amazon.com/images/I/61LZ6srk-+L._SL1000_.jpg&amp;quot; width=&amp;quot;200&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 7250, 7450, 7750 Console Cable ==&lt;br /&gt;
&lt;br /&gt;
USB Mini to Serial DB9 type cable:&lt;br /&gt;
 USB to RS232 Serial Adapter, Mini USB 5 Pin Male to DB9 9 Pin Female Serial Converter Cable 1.8M/6Feet&lt;br /&gt;
 https://www.amazon.com/MTUERANC-Serial-Adapter-Female-Converter/dp/B0CL2BPDNK&lt;br /&gt;
&lt;br /&gt;
&amp;lt;img src=&amp;quot;https://m.media-amazon.com/images/I/71giGlbkvZL._SL1500_.jpg&amp;quot; width=&amp;quot;200&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Connect =&lt;br /&gt;
&lt;br /&gt;
== Connect on Linux ==&lt;br /&gt;
&lt;br /&gt;
 # apt install tio&lt;br /&gt;
 tio -b 9600 /dev/ttyS0&lt;br /&gt;
 tio -b 9600 /dev/ttyUSB0&lt;br /&gt;
&lt;br /&gt;
 # apt install minicom&lt;br /&gt;
 minicom -b 9600 -D /dev/ttyS0&lt;br /&gt;
 minicom -b 9600 -D /dev/ttyUSB0&lt;br /&gt;
&lt;br /&gt;
== Connect on Windows ==&lt;br /&gt;
&lt;br /&gt;
Use Tera Term or Putty and connect to COMX with Baud 9600&lt;br /&gt;
&lt;br /&gt;
= CLI =&lt;br /&gt;
&lt;br /&gt;
Show Config&lt;br /&gt;
 sh run&lt;br /&gt;
&lt;br /&gt;
All but &amp;quot;show config&amp;quot; will need &amp;quot;enable&amp;quot;&lt;br /&gt;
 &amp;gt;enable&lt;br /&gt;
&lt;br /&gt;
== Show Running Configuration ==&lt;br /&gt;
&lt;br /&gt;
 ! show  running-config           Current running-config&lt;br /&gt;
&lt;br /&gt;
 sh run&lt;br /&gt;
 sh ru&lt;br /&gt;
&lt;br /&gt;
== Show Startup Configuration ==&lt;br /&gt;
&lt;br /&gt;
 ! show configuration            Configuration data in startup config file&lt;br /&gt;
&lt;br /&gt;
 sh conf&lt;br /&gt;
 sh con&lt;br /&gt;
 sh co&lt;br /&gt;
&lt;br /&gt;
== Interface Show ==&lt;br /&gt;
&lt;br /&gt;
Show Interfaces&lt;br /&gt;
 sh int bri&lt;br /&gt;
&lt;br /&gt;
Show specific port:&lt;br /&gt;
 show int eth 1/1/1&lt;br /&gt;
&lt;br /&gt;
Show management port:&lt;br /&gt;
 sh int bri | begin mgmt&lt;br /&gt;
&lt;br /&gt;
== License ==&lt;br /&gt;
&lt;br /&gt;
Show licenses:&lt;br /&gt;
 sh license&lt;br /&gt;
&lt;br /&gt;
=== L3 Premium Features ===&lt;br /&gt;
&lt;br /&gt;
 Layer 3 Premium Features and Platform Support&lt;br /&gt;
 https://docs.commscope.com/bundle/fastiron-08095-licenseguide/page/GUID-B01E798A-B196-4544-86C2-DC90AB21CD6A.html&lt;br /&gt;
&lt;br /&gt;
The Layer 3 Premium license supports the following features on an ICX 7450.&lt;br /&gt;
&lt;br /&gt;
    OSPFv2&lt;br /&gt;
    OSPFv3 (IPv6)&lt;br /&gt;
    VRRP&lt;br /&gt;
    VRRPv3 (IPv6)&lt;br /&gt;
    VRRP-E&lt;br /&gt;
    GRE&lt;br /&gt;
    PBR&lt;br /&gt;
    PIM-SM, PIM-SSM, PIM-DM&lt;br /&gt;
    PIM Passive&lt;br /&gt;
    BGP, BGP4+ (IPv6)&lt;br /&gt;
    VRF (IPv4 and IPv6)&lt;br /&gt;
    IPv6 over IPv4 Tunnels&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#sh license&lt;br /&gt;
Unit  License Name    L3 Premium Port Speed Upgrade   Speed    Ports    MACsec&lt;br /&gt;
1     l3-prem         Yes        NA                   NA       NA       No&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== License Upgrade ==&lt;br /&gt;
&lt;br /&gt;
ICX license is enabled honor-based licensing.&lt;br /&gt;
&lt;br /&gt;
Show existing license:&lt;br /&gt;
 show license installed&lt;br /&gt;
&lt;br /&gt;
To upgrade configure with:&lt;br /&gt;
 license install perpetual &amp;lt;unit number&amp;gt; &amp;lt;type of license&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 license install perpetual 1 4x10GR&lt;br /&gt;
 license install perpetual 1 2x10G&lt;br /&gt;
&lt;br /&gt;
 # Example &amp;quot;Layer 3 Premium&amp;quot; license activates advanced routing protocols (OSPF, BGP, PIM, VRRP, PBR, GRE, VRF)&lt;br /&gt;
 license install perpetual 1 l3-prem&lt;br /&gt;
&lt;br /&gt;
 # Example ICX 8200 25G:&lt;br /&gt;
 license install perpetual 1 4x25gr&lt;br /&gt;
&lt;br /&gt;
Delete license with:&lt;br /&gt;
 license delete perpetual 1 4x10gr&lt;br /&gt;
&lt;br /&gt;
references:&lt;br /&gt;
* https://support.ruckuswireless.com/articles/000007612&lt;br /&gt;
* https://docs.commscope.com/bundle/icx7150-installguide/page/GUID-C2FE86C9-46A1-4FCB-AA34-C60220DDE89A.html&lt;br /&gt;
&lt;br /&gt;
Part Number:&lt;br /&gt;
* BR-ICX-7150-41U210-P-01 - 2X10G&lt;br /&gt;
* BR-ICX-7150-210U410R-P-01 - 4X10GR&lt;br /&gt;
* BR-ICX-7150-41U410R-P-01 - 4X10GR&lt;br /&gt;
&lt;br /&gt;
=== Complete License Examples ===&lt;br /&gt;
&lt;br /&gt;
Reference: https://fohdeesha.com/docs/7xxx.html&lt;br /&gt;
&lt;br /&gt;
==== License ICX7850 ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== License ICX7450 ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
enable&lt;br /&gt;
license install perpetual 1 l3-prem&lt;br /&gt;
license install perpetual 1 macsec&lt;br /&gt;
write mem&lt;br /&gt;
reload&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== License ICX7250 ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
enable&lt;br /&gt;
license install perpetual 1 8x10g&lt;br /&gt;
license install perpetual 1 l3-prem&lt;br /&gt;
conf t&lt;br /&gt;
interface ethernet 1/2/1 to 1/2/8&lt;br /&gt;
no speed-duplex 1000-full&lt;br /&gt;
exit&lt;br /&gt;
write mem&lt;br /&gt;
exit&lt;br /&gt;
reload&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== License ICX7150 ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
enable&lt;br /&gt;
license install perpetual 1 2x10gr&lt;br /&gt;
conf t&lt;br /&gt;
int e 1/3/1 to 1/3/2&lt;br /&gt;
no speed-duplex 1000-full&lt;br /&gt;
exit&lt;br /&gt;
write mem&lt;br /&gt;
exit&lt;br /&gt;
reload&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== License Names ===&lt;br /&gt;
&lt;br /&gt;
* Part Number for Upgrades	License Name	Description&lt;br /&gt;
* BR-ICX-7150C-21U210R-P-01	2X10GR	CoE license to upgrade the ICX 7150-C12P switch from 2x1G SFP to a 2x10G SFP+ uplink or stacking ports. Layer 3 Premium license features (OSPF, VRRP, PIM, PBR) are also included.&lt;br /&gt;
* ICX 7150-C12P-ES	12X1GR	ICX 7150-C12P-ES supports only 1-Gbps speed on fiber ports. It does not support the licensing commands. ICX 7150 models with an &amp;quot;ES&amp;quot; suffix identifier are not supported for stacking.&lt;br /&gt;
* BR-ICX-7150-41U210-P-01	2X10G	CoE license to upgrade any ICX 7150 24-port or 48-port model from 4x1G SFP to a 2x1G SFP and 2x10G SFP+ uplink or stacking ports.&lt;br /&gt;
* BR-ICX-7150-210U410R-P-01	4X10GR	CoE license to upgrade any ICX 7150 24-port or 48-port model from 2x1G SFP and 2x10G SFP+ to a 4x10G SFP+ uplink or stacking ports. Two default ports are available for stacking. Layer 3 Premium license features (OSPF, VRRP, PIM, PBR) are also included.&lt;br /&gt;
* BR-ICX-7150-41U410R-P-01	4X10GR	CoE license to upgrade any ICX 7150 24-port or 48-port model from 4x1G SFP to a 4x10G SFP+ uplink or stacking ports. Two default ports are available for stacking. Layer 3 Premium license features (OSPF, VRRP, PIM, PBR) are also included.&lt;br /&gt;
* ICX 7150-24P-ES	24X1GR	ICX 7150-24P-ES support only 1-Gbps speed on fiber ports. It does not support the licensing commands. ICX 7150 models with an &amp;quot;ES&amp;quot; suffix identifier are not supported for stacking.&lt;br /&gt;
* BR-ICX-7150Z210U810R-P-01	8X10GR	CoE license to upgrade an ICX 7150-48ZP Z-Series switch from 6x1G SFP &amp;amp; 2x10G SFP+ to 8x10G SFP+ uplink or stacking ports. Layer 3 Premium license features (OSPF, VRRP, PIM, PBR) are also included.&lt;br /&gt;
* ICX 7150-48P-ES	48X1GR	&lt;br /&gt;
* ICX 7150-48P-ES support only 1-Gbps speed on fiber ports. It does not support the licensing commands. ICX 7150 models with an &amp;quot;ES&amp;quot; suffix identifier are not supported for stacking.&lt;br /&gt;
&lt;br /&gt;
List of license names: https://docs.commscope.com/bundle/icx7150-installguide/page/GUID-C2FE86C9-46A1-4FCB-AA34-C60220DDE89A.html&lt;br /&gt;
&lt;br /&gt;
== Logs ==&lt;br /&gt;
&lt;br /&gt;
Show logs:&lt;br /&gt;
 sh log&lt;br /&gt;
&lt;br /&gt;
Clear logs:&lt;br /&gt;
 clear log&lt;br /&gt;
&lt;br /&gt;
Sample:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Syslog logging: enabled ( 0 messages dropped, 1 flushes, 0 overruns)&lt;br /&gt;
    Buffer logging: level ACDMEINW, 0 messages logged&lt;br /&gt;
    level code: A=alert C=critical D=debugging M=emergency E=error&lt;br /&gt;
                I=informational N=notification W=warning&lt;br /&gt;
&lt;br /&gt;
Dynamic Log Buffer (50 lines):&lt;br /&gt;
Jan  1 12:19:30:I:Security: SSH login by myuser from src IP 10.10.10.10 from src MAC xxxx.xxxx.xxxx to USER EXEC mode using RSA as Server Host Key.&lt;br /&gt;
Jan  1 00:00:57:I:STP: VLAN 1 Port 1/1/30 STP State -&amp;gt; FORWARDING (FwdDlyExpiry)&lt;br /&gt;
Jan  1 00:00:55:I:STP: VLAN 1 Port 1/1/48 STP State -&amp;gt; LEARNING (FwdDlyExpiry)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== MAC Addresses ==&lt;br /&gt;
&lt;br /&gt;
Show collected MACs:&lt;br /&gt;
 sh mac-addresses&lt;br /&gt;
&lt;br /&gt;
Show just those local to interfaces on 1/1/*&lt;br /&gt;
 sh mac-addresses | inc 1/1&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# sh mac-a | inc 1/1/&lt;br /&gt;
98xx.xx.xxxx  1/1/13               Dynamic      228&lt;br /&gt;
98xx.xx.xxxx  1/1/13               Dynamic      228&lt;br /&gt;
f4xx.xx.xxxx  1/1/13               Dynamic      228&lt;br /&gt;
98xx.xx.xxxx  1/1/13               Dynamic      228&lt;br /&gt;
f4xx.xx.xxxx  1/1/14               Dynamic      300&lt;br /&gt;
0cxx.xx.xxxx  1/1/14               Dynamic      300&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== ARP Table ===&lt;br /&gt;
&lt;br /&gt;
Show Arp Table:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# sh arp&lt;br /&gt;
Total number of ARP entries: 1&lt;br /&gt;
Entries in default routing instance:&lt;br /&gt;
No.   IP Address       MAC Address    Type     Age Port               Status&lt;br /&gt;
1     10.10.10.1     b4xx.xxxx.xxxx Dynamic  1    lg01              Valid&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Management IP Show ==&lt;br /&gt;
&lt;br /&gt;
Show IP:&lt;br /&gt;
 show ip&lt;br /&gt;
&lt;br /&gt;
If using router firmware:&lt;br /&gt;
 show ip address  # or &#039;sh ip addr&#039;&lt;br /&gt;
&lt;br /&gt;
== Pagination ==&lt;br /&gt;
&lt;br /&gt;
 &amp;gt;enable&lt;br /&gt;
&lt;br /&gt;
to skip pagination:&lt;br /&gt;
 skip&lt;br /&gt;
 # or skip-page-display&lt;br /&gt;
   Disable page display mode&lt;br /&gt;
&lt;br /&gt;
to page:&lt;br /&gt;
 page&lt;br /&gt;
   Enable page display mode&lt;br /&gt;
&lt;br /&gt;
== Ping ==&lt;br /&gt;
&lt;br /&gt;
 ping [IP]&lt;br /&gt;
&lt;br /&gt;
== POE ==&lt;br /&gt;
&lt;br /&gt;
Enable POE:&lt;br /&gt;
 conf t&lt;br /&gt;
  interface eth 1/1/1&lt;br /&gt;
   inline power&lt;br /&gt;
&lt;br /&gt;
Disable POE:&lt;br /&gt;
 conf t&lt;br /&gt;
  interface eth 1/1/1&lt;br /&gt;
   no inline power&lt;br /&gt;
&lt;br /&gt;
Show Interface POE:&lt;br /&gt;
 show inline power&lt;br /&gt;
&lt;br /&gt;
Show Interface POE details: (and firmware version)&lt;br /&gt;
 show inline power details&lt;br /&gt;
&lt;br /&gt;
Limit POE on interface:&lt;br /&gt;
 int ent ethernet 1/1/1 to 1/1/48&lt;br /&gt;
   inline power&lt;br /&gt;
   inline power power-limit 25000&lt;br /&gt;
&lt;br /&gt;
== Reboot Switch ==&lt;br /&gt;
&lt;br /&gt;
 reload&lt;br /&gt;
&lt;br /&gt;
== Version ==&lt;br /&gt;
&lt;br /&gt;
Show switch version and model and serial:&lt;br /&gt;
 show version&lt;br /&gt;
 sh ver&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;sh ver&lt;br /&gt;
...&lt;br /&gt;
    UNIT 1: compiled on Mar  2 2012 at 12:38:17 labeled as ICX64S07400&lt;br /&gt;
                (10360844 bytes) from Primary ICX64S07400.bin&lt;br /&gt;
        SW: Version 07.4.00T311&lt;br /&gt;
  Boot-Monitor Image size = 512, Version:07.4.00T310 (kxz07400)&lt;br /&gt;
  HW: Stackable ICX6450-48-HPOE&lt;br /&gt;
==========================================================================&lt;br /&gt;
UNIT 1: SL 1: ICX6450-48p POE 48-port Management Module&lt;br /&gt;
         Serial  #: BZTXXXXXXXX&lt;br /&gt;
         License: BASE_SOFT_PACKAGE   (LID: dbvHKIFjFox)&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== VLAN Show ==&lt;br /&gt;
&lt;br /&gt;
Show VLANs:&lt;br /&gt;
 show vlan&lt;br /&gt;
&lt;br /&gt;
= Config =&lt;br /&gt;
&lt;br /&gt;
Configure:&lt;br /&gt;
 enable&lt;br /&gt;
 configure terminal&lt;br /&gt;
 # or conf t&lt;br /&gt;
&lt;br /&gt;
Show Config:&lt;br /&gt;
 show config&lt;br /&gt;
 sh run&lt;br /&gt;
&lt;br /&gt;
Write Config:&lt;br /&gt;
 write mem&lt;br /&gt;
&lt;br /&gt;
Clear Config:&lt;br /&gt;
 erase startup-config&lt;br /&gt;
&lt;br /&gt;
== Hostname ==&lt;br /&gt;
&lt;br /&gt;
 hostname [name]&lt;br /&gt;
&lt;br /&gt;
== Banner ==&lt;br /&gt;
&lt;br /&gt;
Display banner at login: &amp;lt;ref&amp;gt;https://docs.commscope.com/bundle/fastiron-08095-managementguide/page/GUID-5A14B1C5-DD1A-40E3-A371-6C7A0407D796.html&amp;lt;/ref&amp;gt;&lt;br /&gt;
 banner motd $&lt;br /&gt;
   Enter TEXT message, End with the character &#039;$&#039;.&lt;br /&gt;
   Welcome!!! $&lt;br /&gt;
&lt;br /&gt;
== Interface ==&lt;br /&gt;
&lt;br /&gt;
 sh int bri&lt;br /&gt;
&lt;br /&gt;
Show specific port:&lt;br /&gt;
 show int eth 1/1/1&lt;br /&gt;
&lt;br /&gt;
Show management port:&lt;br /&gt;
 sh int bri | begin mgmt&lt;br /&gt;
&lt;br /&gt;
Disable Interface&lt;br /&gt;
 int eth 1/1/48&lt;br /&gt;
   disable&lt;br /&gt;
   enable&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== IP ==&lt;br /&gt;
&lt;br /&gt;
Management Interface DHCP Client&lt;br /&gt;
&lt;br /&gt;
=== dhcp ip ===&lt;br /&gt;
&lt;br /&gt;
Enable DHCP&lt;br /&gt;
 ip dhcp-client enable&lt;br /&gt;
 ip dhcp-client auto-update enable&lt;br /&gt;
&lt;br /&gt;
Disable DHCP&lt;br /&gt;
 no ip dhcp-client enable&lt;br /&gt;
&lt;br /&gt;
=== Static IP ===&lt;br /&gt;
 ip address 10.10.10.104/24&lt;br /&gt;
 # or&lt;br /&gt;
 ip address 10.10.10.104 255.255.255.0&lt;br /&gt;
&lt;br /&gt;
 ip default-gateway 10.10.10.1&lt;br /&gt;
 no ip dhcp-client auto-update enable&lt;br /&gt;
 no ip dhcp-client enable&lt;br /&gt;
&lt;br /&gt;
Show IP:&lt;br /&gt;
 show ip&lt;br /&gt;
&lt;br /&gt;
=== Management VLAN ===&lt;br /&gt;
&lt;br /&gt;
Desginate which VLAN carries the management traffic: &amp;lt;ref&amp;gt;https://docs.commscope.com/bundle/fastiron-08095-securityguide/page/GUID-61483D35-3F95-43FB-8092-33C14E0D188D.html&amp;lt;/ref&amp;gt;&lt;br /&gt;
 vlan 10 by port&lt;br /&gt;
   management-vlan&lt;br /&gt;
&lt;br /&gt;
Default is VLAN 1&lt;br /&gt;
&lt;br /&gt;
== License ==&lt;br /&gt;
&lt;br /&gt;
set license &amp;lt;ref&amp;gt;https://support.ruckuswireless.com/articles/000007612&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 license install perpetual &amp;lt;unit number&amp;gt; &amp;lt;type of license&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 license install perpetual 1 4x10GR&lt;br /&gt;
&lt;br /&gt;
 license delete perpetual 1 4x10gr&lt;br /&gt;
&lt;br /&gt;
== SFP ==&lt;br /&gt;
&lt;br /&gt;
GBIC&lt;br /&gt;
&lt;br /&gt;
Types:&lt;br /&gt;
* 1G M-TX(SFP) - 1 GigE&lt;br /&gt;
&lt;br /&gt;
Part#&lt;br /&gt;
* SFP-1000BASE-TX = 1 GigE Copper&lt;br /&gt;
* SFP-GE-T = 1 GigE Copper&lt;br /&gt;
&lt;br /&gt;
Combos:&lt;br /&gt;
* 1G M-TX(SFP) w/ SFP-1000BASE-TX = 1 GigE Copper&lt;br /&gt;
* 1G M-TX(SFP) w/ SFP-GE-T = 1 GigE Copper&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# show media&lt;br /&gt;
...&lt;br /&gt;
Port 1/3/1:  Type  : EMPTY&lt;br /&gt;
Port 1/3/2:  Type  : EMPTY&lt;br /&gt;
Port 1/3/3:  Type  : 1G M-TX(SFP)&lt;br /&gt;
Port 1/3/4:  Type  : EMPTY&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# sh media et 1/3/3&lt;br /&gt;
Port   1/3/3: Type  : 1G M-TX(SFP)&lt;br /&gt;
             Vendor: XXX    Version: D1&lt;br /&gt;
             Part# : SFP-1000BASE-TX    Serial#: XXX&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 # sh int bri&lt;br /&gt;
 ..&lt;br /&gt;
 1/3/3      Up      Forward Full 1G    None  No  1    0   xxxx.xxxx.xxxx&lt;br /&gt;
&lt;br /&gt;
 #sh int et 1/3/3&lt;br /&gt;
 10GigabitEthernet1/3/3 is up, line protocol is up&lt;br /&gt;
&lt;br /&gt;
Note: If a 1-Gbps optic transceiver is inserted, you must configure the port using the &#039;&#039;speed-duplex 1000-full-master&#039;&#039; command at the interface level. &amp;lt;ref&amp;gt;https://docs.commscope.com/bundle/icx7150-installguide/page/GUID-B346251F-DFCC-4441-B047-6E3A3E88839C.html&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Enable port: &amp;lt;ref&amp;gt;https://docs.commscope.com/bundle/icx7150-installguide/page/GUID-B346251F-DFCC-4441-B047-6E3A3E88839C.html&amp;lt;/ref&amp;gt;&lt;br /&gt;
 # conf term&lt;br /&gt;
 # int ethernet 1/3/3&lt;br /&gt;
 # speed-duplex 1000-full-master&lt;br /&gt;
&lt;br /&gt;
or short form: &amp;lt;ref&amp;gt;https://community.ruckuswireless.com/t5/ICX-Switches/Configuring-SFP-port-on-7150-C08p/td-p/27124&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
config t&lt;br /&gt;
int e 1/2/1&lt;br /&gt;
speed 1000-full&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# sh run&lt;br /&gt;
...&lt;br /&gt;
stack unit 1&lt;br /&gt;
  module 1 icx7150-48pf-poe-port-management-module&lt;br /&gt;
  module 2 icx7150-2-copper-port-2g-module&lt;br /&gt;
  module 3 icx7150-4-sfp-plus-port-40g-module&lt;br /&gt;
  stack-port 1/3/1&lt;br /&gt;
  stack-port 1/3/3&lt;br /&gt;
!&lt;br /&gt;
interface ethernet 1/3/3&lt;br /&gt;
 speed-duplex 1000-full&lt;br /&gt;
!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 10GE SFP+ ===&lt;br /&gt;
&lt;br /&gt;
* 10GE SR 300m ((SFP+))&lt;br /&gt;
* 10GE USR 100m (SFP +)&lt;br /&gt;
&lt;br /&gt;
== Spanning Tree ==&lt;br /&gt;
&lt;br /&gt;
[[Spanning Tree Protocol]] (STP) is a network protocol that creates a loop-free logical topology for Ethernet networks by blocking redundant links. It prevents network loops that can cause &amp;quot;broadcast storms,&amp;quot; which overwhelm a network and bring it down. STP ensures there is only one active path between any two devices and automatically reroutes traffic through a backup link if an active one fails, thus providing network redundancy and stability&lt;br /&gt;
&lt;br /&gt;
* Prevents network loops: STP is designed to prevent loops that occur when there are multiple active paths between switches. Loops cause data packets to circulate endlessly, leading to a broadcast storm that can crash the network.&lt;br /&gt;
* Creates a single active path: STP builds a logical tree topology and blocks redundant links, leaving only one active path between any two network devices.&lt;br /&gt;
* Provides redundancy: While blocking redundant paths to prevent loops, STP maintains these paths as backups. If an active link fails, STP will automatically enable a blocked port to restore connectivity without manual intervention.&lt;br /&gt;
* How it works: Switches use special messages called Bridge Protocol Data Units (BPDUs) to communicate with each other. They exchange information to elect a &amp;quot;root bridge&amp;quot; and then determine the best path to that root bridge. Ports that are not part of the optimal path are placed in a blocking state.&lt;br /&gt;
* Standardization: STP is an IEEE 802.1D standard. Modern variations like Rapid Spanning Tree Protocol (RSTP) provide faster convergence times when a network change occurs&lt;br /&gt;
&lt;br /&gt;
References: https://en.wikipedia.org/wiki/Spanning_Tree_Protocol&lt;br /&gt;
&lt;br /&gt;
=== Disable Spanning Tree ===&lt;br /&gt;
&lt;br /&gt;
Disable Spanning Tree On specific port:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
interface ethernet 1/1/1&lt;br /&gt;
 no spanning-tree&lt;br /&gt;
!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Disable Spanning Tree Globally:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
no global-stp&lt;br /&gt;
!&lt;br /&gt;
vlan 1 name DEFAULT-VLAN by port&lt;br /&gt;
 no spanning-tree&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Generally bad practice, but maybe you need to turn your smart switch into a &amp;quot;dumb&amp;quot; switch to bypass &amp;quot;BPDU&amp;quot; guard (also very very bad practice).&lt;br /&gt;
* BPDU (Bridge Protocol Data Unit) packets are messages that network switches use to communicate with each other to maintain a loop-free topology using the Spanning Tree Protocol (STP). These packets contain information about the switch&#039;s priority, address, ports, and path costs to the root bridge, and are crucial for electing a root bridge and for detecting changes in the network topology.&lt;br /&gt;
&lt;br /&gt;
=== BPDU Guard ===&lt;br /&gt;
&lt;br /&gt;
Switches will detect loops by checking BPDU packets, which is a good thing.  BPDU Guard is a setting that states that there should be NO switces downstream, and will disable the port if BPDU packets are detected.  This is saying only end point client systems should be past this point.  The silly thing is &amp;quot;dumb&amp;quot; switches will work just fine, and you can have multiple clients down stream connected to a &amp;quot;dumb&amp;quot; switch.  So if you turn a &amp;quot;smart&amp;quot; switch into a &amp;quot;dumb&amp;quot; switch by disabling spanning tree, it can also sit down stream just fine.&lt;br /&gt;
&lt;br /&gt;
:&amp;quot;BPDU guard is a security feature in Spanning Tree Protocol (STP) that protects a network from rogue switches by disabling ports that receive Bridge Protocol Data Units (BPDUs).&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Enable BPDU Guard:&lt;br /&gt;
 device(config)# interface ethernet 1/1/1&lt;br /&gt;
 device(config-if-e1000-1/1/1)# stp-bpdu-guard&lt;br /&gt;
&lt;br /&gt;
Reference: https://docs.commscope.com/bundle/fastiron-08095-l2guide/page/GUID-DB9A959B-AAE7-42C1-BEE7-3C008151A3C3.html&lt;br /&gt;
&lt;br /&gt;
== SSH ==&lt;br /&gt;
&lt;br /&gt;
Show ssh config settings:&lt;br /&gt;
 sh ip ssh config&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt; sh ip ssh config&lt;br /&gt;
...&lt;br /&gt;
SSH server                 : Enabled&lt;br /&gt;
SSH port                   : tcp\22&lt;br /&gt;
Host Key                   : DSA 1024,  RSA 1024&lt;br /&gt;
Encryption                 : aes256-cbc, aes192-cbc, aes128-cbc, aes256-ctr, aes192-ctr, aes128-ctr, 3des-cbc&lt;br /&gt;
...&lt;br /&gt;
Authentication methods     : Password, Public-key, Interactive&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Enable SSH:&lt;br /&gt;
 ## Generate keys&lt;br /&gt;
 crypto key generate rsa&lt;br /&gt;
   # ^ Their offer: ssh-rsa&lt;br /&gt;
 crypto key generate dsa&lt;br /&gt;
   # ^ Their offer: ssh-dss&lt;br /&gt;
 # Add admin user:&lt;br /&gt;
 username admin pri 0 password [PASSWORD]&lt;br /&gt;
 # enable &lt;br /&gt;
 aaa authentication login default local&lt;br /&gt;
&lt;br /&gt;
Disable SSH:&lt;br /&gt;
 crypto key zeroize&lt;br /&gt;
 crypto key zeroize dsa&lt;br /&gt;
&lt;br /&gt;
Note, the ICX uses really old key exchange method &#039;diffie-hellman-group1-sha1&#039;&lt;br /&gt;
 debug1: kex: algorithm: diffie-hellman-group1-sha1&lt;br /&gt;
 debug1: kex: host key algorithm: ssh-rsa&lt;br /&gt;
 # or&lt;br /&gt;
 debug1: kex: host key algorithm: ssh-dss&lt;br /&gt;
 debug1: kex: server-&amp;gt;client cipher: aes128-ctr MAC: hmac-sha1 compression: none&lt;br /&gt;
 debug1: kex: client-&amp;gt;server cipher: aes128-ctr MAC: hmac-sha1 compression: none&lt;br /&gt;
&lt;br /&gt;
=== Linux Client ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To allow diffie-hellman-group1-sha1, edit either .ssh/config(to host) or /etc/ssh/ssh_config and add the following:&lt;br /&gt;
 # ICX SSH&lt;br /&gt;
 # KexAlgorithms +diffie-hellman-group1-sha1&lt;br /&gt;
 KexAlgorithms +diffie-hellman-group14-sha1,diffie-hellman-group1-sha1&lt;br /&gt;
 HostKeyAlgorithms +ssh-dss,ssh-rsa&lt;br /&gt;
 # for ssh key to icx&lt;br /&gt;
 PubkeyAcceptedKeyTypes +ssh-dss,ssh-rsa&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.ssh/config&lt;br /&gt;
Host *&lt;br /&gt;
  # ICX SSH&lt;br /&gt;
  KexAlgorithms +diffie-hellman-group1-sha1&lt;br /&gt;
  HostKeyAlgorithms +ssh-dss,ssh-rsa&lt;br /&gt;
  # for ssh key to icx&lt;br /&gt;
  PubkeyAcceptedKeyTypes +ssh-dss,ssh-rsa&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
NOTE: If you want to have the switch connect in reverse to do firmware updates, make sure to add the same to /etc/ssh/sshd_config&lt;br /&gt;
 # Allow Legacy ICX switches (or https://www.digital-loggers.com/) to connect to Linux System to scp updates&lt;br /&gt;
 KexAlgorithms +diffie-hellman-group1-sha1&lt;br /&gt;
 HostKeyAlgorithms +ssh-dss,ssh-rsa&lt;br /&gt;
 ## PubkeyAcceptedKeyTypes +ssh-dss,ssh-rsa # icx doesn&#039;t have a private key option - sadness&lt;br /&gt;
&lt;br /&gt;
=== Git-Bash Client ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.ssh/config&lt;br /&gt;
Host 10.0.100.* 10.0.200.*&lt;br /&gt;
    User admin&lt;br /&gt;
    # ICX SSH&lt;br /&gt;
    KexAlgorithms +diffie-hellman-group1-sha1&lt;br /&gt;
    HostKeyAlgorithms +ssh-rsa&lt;br /&gt;
    MACs hmac-sha1&lt;br /&gt;
    # # for ssh key to icx&lt;br /&gt;
    #PubkeyAcceptedKeyTypes +ssh-dss,ssh-rsa&lt;br /&gt;
Host *&lt;br /&gt;
  # General settings&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Public Keys ===&lt;br /&gt;
&lt;br /&gt;
* Note: The public key file may contain up to 16 DSA or RSA key pairs.&lt;br /&gt;
* Note: Each key in the public key must be in exactly this format (remove the ssh-rsa prefix, the &#039;Comment&#039; line is optional): &amp;lt;ref&amp;gt;ref https://docs.commscope.com/bundle/fastiron-08095-securityguide/page/GUID-E00DB049-9D65-4438-A64F-A947648A70AE.html&amp;lt;/ref&amp;gt;&lt;br /&gt;
* Note: Use a 2048 bit key (ssh-keygen -b 2048).  The larger key will generate connect issues for 6450s (probably 7150s too). (no key from blob. pkalg ssh-rsa: invalid format) &amp;lt;ref&amp;gt;https://apple.stackexchange.com/questions/356323/ssh-fails-with-ssh-dispatch-run-fatal-invalid-format&amp;lt;/ref&amp;gt;&lt;br /&gt;
 ssh-keygen -b 2048&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
---- BEGIN SSH2 PUBLIC KEY ---- &lt;br /&gt;
Comment:  &amp;quot;2048-bit RSA, converted from OpenSSH&amp;quot;&lt;br /&gt;
AAAAB3NaC1yc2EAAAABIwAAAQEA0pt94yJmKwPfPZnxxYSS1aVaaqWgRM79EfRXf2XUrs&lt;br /&gt;
834hx881MmQedye1oJrntvA8LyVUIepOdbc874i4259mtSXx+cfZW0/QeJggT/1zE82+n&lt;br /&gt;
w706gGqNsE+XsT12bi6KU4Al2IWULce74yfQY9/amy38ZPCesKKurH4+2m/Ba69391lp&lt;br /&gt;
nJ0BIQidn+I8hARUGayrOTrx/e2^kdC+2aNh6mS17KDiRyj8WBV3F5z5f5rlYBL/WoJ2beo&lt;br /&gt;
R3L6H6wHXP8dZ1F4IqeVxeIimkFTzMEE*r/wHCnhewetnDy3iJAgr0TXTicJ1Qpb1MCBkB&lt;br /&gt;
XaynjuDYSf4Kmgn8znaQ==&lt;br /&gt;
---- END SSH2 PUBLIC KEY ----&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Copy the combined key file (up to 16 keys) to tftp server, and have the ICX pull and override keyfile with:&lt;br /&gt;
 conf term&lt;br /&gt;
  ip ssh pub-key-file tftp [TFTP_IP] [PATH/keyfile.txt]&lt;br /&gt;
&lt;br /&gt;
List keys:&lt;br /&gt;
 show ip client-pub-key&lt;br /&gt;
&lt;br /&gt;
Remove pub key file:&lt;br /&gt;
 ip ssh pub-key-file remove&lt;br /&gt;
&lt;br /&gt;
== Neighbour Detection ==&lt;br /&gt;
&lt;br /&gt;
Neighbour Detection &amp;lt;ref&amp;gt;https://support.purdi.com/hc/en-gb/articles/360021220292-Ruckus-ICX-Neighbour-Detection-using-LLDP-CDP-FDP&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Link Layer Discovery Protocol (LLDP)&#039;&#039;&#039; - Vendor agnostic link layer protocol to advertise device capabilities and directly connected neighbours on the network.&lt;br /&gt;
 lldp run&lt;br /&gt;
 show lldp neighbors&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Foundry Discovery Protocol (FDP)&#039;&#039;&#039; - Foundry/Brocade specific link layer protocol to advertise device capabilities and directly connected neighbours on the network.&lt;br /&gt;
 fdp run&lt;br /&gt;
 show fdp neighbors&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cisco Discovery Protocol (CDP)&#039;&#039;&#039; - Cisco specific link layer protocol to advertise device capabilities and directly connected neighbours on the network.&lt;br /&gt;
 cdp run&lt;br /&gt;
 show cdp neighbors&lt;br /&gt;
&lt;br /&gt;
== VLAN ==&lt;br /&gt;
&lt;br /&gt;
Show VLANs:&lt;br /&gt;
 show vlan&lt;br /&gt;
&lt;br /&gt;
Clear VLAN:&lt;br /&gt;
 no vlan [#]&lt;br /&gt;
&lt;br /&gt;
Simple VLAN&lt;br /&gt;
 vlan 100 name MyVLAN by port&lt;br /&gt;
  tagged e 1/2/1&lt;br /&gt;
  untagged e 1/1/1 to 1/1/48&lt;br /&gt;
 !&lt;br /&gt;
&lt;br /&gt;
== LAG ==&lt;br /&gt;
&lt;br /&gt;
Simple LAG with VLAN:&lt;br /&gt;
 lag LAG1 dynamic id 1&lt;br /&gt;
  ports ethe 1/1/47 to 1/1/48&lt;br /&gt;
 !&lt;br /&gt;
 vlan 3200 name MyVLAN by port&lt;br /&gt;
  tagged lag 1&lt;br /&gt;
  untagged e 1/1/1 to 1/1/46&lt;br /&gt;
 !&lt;br /&gt;
&lt;br /&gt;
Static vs dynamic:&lt;br /&gt;
 lag LAG1 dynamic id 1&lt;br /&gt;
&lt;br /&gt;
 lag LAG1 static id 1&lt;br /&gt;
&lt;br /&gt;
Show lag:&lt;br /&gt;
 sh lag&lt;br /&gt;
 sh lag id 1&lt;br /&gt;
&lt;br /&gt;
Name ports:&lt;br /&gt;
 lag LAG1&lt;br /&gt;
   port-name UPLINK-A ethernet 1/1/47&lt;br /&gt;
   port-name UPLINK-B ethernet 1/1/48&lt;br /&gt;
&lt;br /&gt;
Disable one port:&lt;br /&gt;
 lag LAG1&lt;br /&gt;
   disable e 1/1/48&lt;br /&gt;
&lt;br /&gt;
 lag LAG1&lt;br /&gt;
   enable e 1/1/48&lt;br /&gt;
 &lt;br /&gt;
Remove a port:&lt;br /&gt;
 lag LAG1&lt;br /&gt;
   no ports e 1/1/47&lt;br /&gt;
&lt;br /&gt;
== Time ==&lt;br /&gt;
&lt;br /&gt;
 clock summer-time&lt;br /&gt;
 clock timezone us Pacific&lt;br /&gt;
 clock timezone us mountain&lt;br /&gt;
&lt;br /&gt;
 sh clock&lt;br /&gt;
 sh clock detail&lt;br /&gt;
&lt;br /&gt;
NTP Client:&lt;br /&gt;
 ntp&lt;br /&gt;
   server 10.x.x.1&lt;br /&gt;
   server 10.x.x.2&lt;br /&gt;
&lt;br /&gt;
   server 0.pool.ntp.org minpoll 10 burst&lt;br /&gt;
   server 1.pool.ntp.org minpoll 10 burst&lt;br /&gt;
&lt;br /&gt;
Show ntp status: &amp;lt;ref&amp;gt;https://docs.commscope.com/bundle/fastiron-08095-managementguide/page/GUID-98F32DCC-B4D7-4531-BC58-42F47C984868.html&amp;lt;/ref&amp;gt;&lt;br /&gt;
 show ntp status&lt;br /&gt;
 show ntp associations&lt;br /&gt;
&lt;br /&gt;
Disable NTP client:&lt;br /&gt;
 ntp&lt;br /&gt;
   disable&lt;br /&gt;
&lt;br /&gt;
Enable NTP client:&lt;br /&gt;
 ntp&lt;br /&gt;
   no disable&lt;br /&gt;
&lt;br /&gt;
Disable serving time to clients:&lt;br /&gt;
 ntp&lt;br /&gt;
   disable serve&lt;br /&gt;
&lt;br /&gt;
Specify source interface: &amp;lt;ref&amp;gt;https://docs.commscope.com/bundle/fastiron-08095-managementguide/page/GUID-0A5F29D9-CBA8-440A-9EB7-61BCEA35E240.html&amp;lt;/ref&amp;gt;&lt;br /&gt;
 source-interface ethernet 1/3/1&lt;br /&gt;
&lt;br /&gt;
 ! ntp-interface management 1&lt;br /&gt;
&lt;br /&gt;
Daylight Saving (Summer Time) &amp;lt;ref&amp;gt;https://docs.commscope.com/bundle/fastiron-08091-managementguide/page/GUID-E670EE11-FBD6-4D1E-9099-6E231887D245.html&amp;lt;/ref&amp;gt; &amp;lt;ref&amp;gt;https://docs.commscope.com/bundle/fastiron-08095-managementguide/page/GUID-E670EE11-FBD6-4D1E-9099-6E231887D245.html&amp;lt;/ref&amp;gt;&lt;br /&gt;
 clock summer-time zone us pacific start 02-28-21 02:00:00 end 10-30-21 02:00:00 offset 60&lt;br /&gt;
 clock summer-time zone us mountain start 02-28-16 02:00:00 end 10-30-16 02:00:00 offset 30&lt;br /&gt;
&lt;br /&gt;
Note: Will have to be manually updated each year.&lt;br /&gt;
&lt;br /&gt;
Note: &amp;quot;Before you begin to configure NTP, you must use the clock set command to set the time on your device to within 1000 seconds of the coordinated Universal Time (UTC).&amp;quot; &amp;lt;ref&amp;gt;https://community.ruckuswireless.com/t5/ICX-Switches/Force-sync-ntp/m-p/45909&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
clock set &amp;lt;ref&amp;gt;https://docs.commscope.com/bundle/icx7150-installguide/page/GUID-453AC7E4-0CCF-4EB0-8E4B-3002CE8CCB24.html&amp;lt;/ref&amp;gt;&lt;br /&gt;
 exit&lt;br /&gt;
 ! clock set hh:mm:ss mm-dd-yy/yyyy&lt;br /&gt;
 clock set 02:49:00 11-23-24&lt;br /&gt;
&lt;br /&gt;
== Users ==&lt;br /&gt;
&lt;br /&gt;
Add Users:&lt;br /&gt;
 username admin password [PASSWORD]&lt;br /&gt;
 no username admin&lt;br /&gt;
&lt;br /&gt;
 username myuser privilege [LEVEL] password [PASSWORD]&lt;br /&gt;
 # LEVEL:   &amp;lt;0 READ-WRITE, 4 PORT-CONFIG, 5 READ-ONLY&amp;gt; User privilege level&lt;br /&gt;
&lt;br /&gt;
Require Login:&lt;br /&gt;
 aaa authentication web-server default local&lt;br /&gt;
 aaa authentication login default local&lt;br /&gt;
&lt;br /&gt;
Configure seperate enable privilege passwords:&lt;br /&gt;
 enable super-user-password [PASSWORD]&lt;br /&gt;
 enable port-config-password [PASSWORD]&lt;br /&gt;
 enable read-only-password [PASSWORD]&lt;br /&gt;
&lt;br /&gt;
 no enable super-user-password&lt;br /&gt;
&lt;br /&gt;
Enter enable mode:&lt;br /&gt;
 enable&lt;br /&gt;
&lt;br /&gt;
Show who logged in as:&lt;br /&gt;
 sh who&lt;br /&gt;
&lt;br /&gt;
=== Privilege Levels ===&lt;br /&gt;
&lt;br /&gt;
3 privileged levels:&lt;br /&gt;
#  enable &#039;&#039;&#039;super-user-password&#039;&#039;&#039; [PASSWORD] -          Super-user level password&lt;br /&gt;
#  enable &#039;&#039;&#039;port-config-password&#039;&#039;&#039; [PASSWORD] -         Port level configuration password&lt;br /&gt;
#  enable &#039;&#039;&#039;read-only-password&#039;&#039;&#039; [PASSWORD] -           Read-only level password&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;Super User level&#039;&#039; - Allows complete read-and-write access to the system. This is generally for system administrators and is the only management privilege level that allows you to configure passwords.&lt;br /&gt;
* &#039;&#039;Port Configuration level&#039;&#039; - Allows read-and-write access for specific ports but not for global (system-wide) parameters.&lt;br /&gt;
* &#039;&#039;Read-only level&#039;&#039; - Allows access to the Privileged EXEC mode and User EXEC mode of the CLI but only with read access.&lt;br /&gt;
&lt;br /&gt;
== Authentication, Authorization, and Accounting ==&lt;br /&gt;
&lt;br /&gt;
 Authentication, Authorization, and Accounting (AAA) is a security framework that controls access to computer resources, enforces policies, and audits usage.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Authentication&#039;&#039;&#039; - confirm users are who they claim they are (username/password)&lt;br /&gt;
* &#039;&#039;&#039;Authorization &#039;&#039;&#039; - granted privileges to authorized user&lt;br /&gt;
* &#039;&#039;&#039;Accounting&#039;&#039;&#039; - tracking user activity&lt;br /&gt;
&lt;br /&gt;
Sample config:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 aaa authentication web-server default local&lt;br /&gt;
 aaa authentication login default tacacs+ local&lt;br /&gt;
 aaa authentication login privilege-mode&lt;br /&gt;
&lt;br /&gt;
 aaa authorization exec default tacacs+&lt;br /&gt;
&lt;br /&gt;
 aaa accounting exec default start-stop tacacs+&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;privilege-mode&amp;quot; will attempt to auto-promote the user to privileged mode when logged in, based on TACACS+ allowed privileged level &amp;lt;ref&amp;gt;https://arubanetworking.hpe.com/techdocs/AOS-S/16.10/ASG/KB/content/asg%20kb/usi-pri-mod-opt-log.htm&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
AAA Protocols:&lt;br /&gt;
* &#039;&#039;&#039;Remote Authentication Dial-In User Service (RADIUS)&#039;&#039;&#039; is a networking protocol that authorizes and authenticates users who access a remote network&lt;br /&gt;
* &#039;&#039;&#039;Terminal Access Controller Access Control System Plus (TACACS+)&#039;&#039;&#039; - a remote authentication AAA protocol that lets a remote access server communicate with an authentication server for user validation&lt;br /&gt;
* &#039;&#039;&#039;Diameter&#039;&#039;&#039; - evolved from the RADIUS protocol&lt;br /&gt;
&lt;br /&gt;
= Firmware =&lt;br /&gt;
&lt;br /&gt;
== Firmware Versions ==&lt;br /&gt;
&lt;br /&gt;
ICX FastIron Stable series:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
08.0.95p	2024-06-27&lt;br /&gt;
08.0.95n	2024-01-31  *** recommended stable ***&lt;br /&gt;
08.0.95m	2023-08-24&lt;br /&gt;
08.0.95k	2023-06-16&lt;br /&gt;
08.0.95j	2023-06-16&lt;br /&gt;
08.0.95h	2022-09-02&lt;br /&gt;
...&lt;br /&gt;
08.0.95 	2020-09-14&lt;br /&gt;
...&lt;br /&gt;
08.0.90d	2019-09-27 *** used as jump to ufi ***&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 https://support.ruckuswireless.com/software/1186-ruckus-icx-7xxx-icx-6xxxx-campus-switch-firmware-download&lt;br /&gt;
&lt;br /&gt;
 https://support.ruckuswireless.com/products/108-ruckus-icx-7150-campus-switches?open=document#firmwares&lt;br /&gt;
&lt;br /&gt;
 https://support.ruckuswireless.com/products/108-ruckus-icx-7150-campus-switches&lt;br /&gt;
 Recommended Software: (as of 2024.07.08)&lt;br /&gt;
  Stability Release: RUCKUS ICX FastIron 08.0.95n (GA) Software Release (.zip)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
&amp;quot;Ruckus ICX software currently has two recommended release types; Stability and Technology.&lt;br /&gt;
&lt;br /&gt;
Stability Release: This is for customers where stability is of utmost importance. This release may not contain every feature available for your product.&lt;br /&gt;
&lt;br /&gt;
Technology Release: This is for customers looking to utilize the maximum feature set available for your product.&lt;br /&gt;
&lt;br /&gt;
We recommend most customers utilize the Stability Release if it contains all needed features for your network. A Technology Release is recommended if your network requires newer features not available in the Stability Release.&amp;quot;&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 08.0.95n ===&lt;br /&gt;
&lt;br /&gt;
 RUCKUS ICX FastIron 08.0.95n (GA) Software Release (.zip)&lt;br /&gt;
 https://support.ruckuswireless.com/software/3958-ruckus-icx-fastiron-08-0-95n-ga-software-release-zip&lt;br /&gt;
&lt;br /&gt;
 Applies to: ICX7150, ICX7250, ICX7450, ICX7550, ICX7650, ICX7750, ICX7850&lt;br /&gt;
&lt;br /&gt;
=== 08.0.95m ===&lt;br /&gt;
&lt;br /&gt;
 RUCKUS ICX FastIron 08.0.95m (GA) Software Release (.zip)&lt;br /&gt;
 https://support.ruckuswireless.com/software/3749-ruckus-icx-fastiron-08-0-95m-ga-software-release-zip&lt;br /&gt;
&lt;br /&gt;
 Applies to: ICX7150, ICX7250, ICX7450, ICX7550, ICX7650, ICX7750, ICX7850&lt;br /&gt;
&lt;br /&gt;
== Select Boot Slot ==&lt;br /&gt;
&lt;br /&gt;
Show boot configuration:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ICX7450 #sh boot-preference&lt;br /&gt;
Boot system preference(Configured):&lt;br /&gt;
        Use Default&lt;br /&gt;
&lt;br /&gt;
Boot system preference(Default):&lt;br /&gt;
        Boot system flash primary&lt;br /&gt;
        Boot system flash secondary&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Select second boot slot:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ICX7450# Boot system flash secondary&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Show boot configuration after change:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ICX7450# sh boot-preference&lt;br /&gt;
Boot system preference(Configured):&lt;br /&gt;
        Boot system flash secondary&lt;br /&gt;
&lt;br /&gt;
Boot system preference(Default):&lt;br /&gt;
        Boot system flash primary&lt;br /&gt;
        Boot system flash secondary&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Show configuration:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ICX7450# sh run&lt;br /&gt;
Current configuration:&lt;br /&gt;
!&lt;br /&gt;
...&lt;br /&gt;
!&lt;br /&gt;
boot sys fl sec&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Reset Password =&lt;br /&gt;
&lt;br /&gt;
As switch boots up, when you see the following, press &#039;b&#039;:&lt;br /&gt;
 Enter &#039;b&#039; to stop at boot monitor:&lt;br /&gt;
then type &amp;quot;no password&amp;quot;:&lt;br /&gt;
 no password&lt;br /&gt;
then type &amp;quot;boot&amp;quot; to continue booting:&lt;br /&gt;
 boot&lt;br /&gt;
 # or boot_primary&lt;br /&gt;
Then either change password&lt;br /&gt;
 enable&lt;br /&gt;
 conf t&lt;br /&gt;
&lt;br /&gt;
== Default Login ==&lt;br /&gt;
&lt;br /&gt;
 super&lt;br /&gt;
 sp-admin&lt;br /&gt;
&lt;br /&gt;
= Reset Configuration =&lt;br /&gt;
&lt;br /&gt;
 enable&lt;br /&gt;
 erase startup-config&lt;br /&gt;
 reload&lt;br /&gt;
&lt;br /&gt;
= Recovery Mode =&lt;br /&gt;
&lt;br /&gt;
As switch boots up, when you see the following, press &#039;b&#039;:&lt;br /&gt;
 Enter &#039;b&#039; to stop at boot monitor:&lt;br /&gt;
&lt;br /&gt;
Useful commands:&lt;br /&gt;
* boot_primary&lt;br /&gt;
* boot_secondary&lt;br /&gt;
* show_image&lt;br /&gt;
* no password  (not even listed in the help!!)&lt;br /&gt;
&lt;br /&gt;
Help:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Enter &#039;b&#039; to stop at boot monitor:  0&lt;br /&gt;
ICX7250-Boot&amp;gt; help&lt;br /&gt;
?       - alias for &#039;help&#039;&lt;br /&gt;
boot    - boot default, i.e., run &#039;bootcmd&#039;&lt;br /&gt;
boot_primary-  boot from primary partition&lt;br /&gt;
&lt;br /&gt;
boot_secondary-  boot from secondary partition&lt;br /&gt;
&lt;br /&gt;
bootm   - boot application image from memory&lt;br /&gt;
cp      - memory copy&lt;br /&gt;
cpld_read- Read from cpld&lt;br /&gt;
cpld_write- write to cpld&lt;br /&gt;
dump_cpld- Dump CPLD Registers&lt;br /&gt;
eeprom  - EEPROM sub-system&lt;br /&gt;
ext2load- load binary file from a Ext2 filesystem&lt;br /&gt;
ext2ls  - list files in a directory (default /)&lt;br /&gt;
help    - print command description/usage&lt;br /&gt;
hwinfo  - Show HW Info&lt;br /&gt;
logging_disable- Disable Uboot Logs.&lt;br /&gt;
logging_enable- Enable Uboot Logs.&lt;br /&gt;
md      - memory display&lt;br /&gt;
nand    - NAND sub-system&lt;br /&gt;
ping    - send ICMP ECHO_REQUEST to network host&lt;br /&gt;
powercycle- Do a Hard Reset&lt;br /&gt;
printenv- print environment variables&lt;br /&gt;
reset   - Perform RESET of the CPU&lt;br /&gt;
saveenv - save environment variables to persistent storage&lt;br /&gt;
setenv  - set environment variables&lt;br /&gt;
sf      - SPI flash sub-system&lt;br /&gt;
show_image- Show Stored Images.&lt;br /&gt;
tftpboot-  boot image via network using TFTP protocol&lt;br /&gt;
&lt;br /&gt;
update_primary-  update primary partition&lt;br /&gt;
&lt;br /&gt;
update_secondary-  update secondary partition&lt;br /&gt;
&lt;br /&gt;
update_uboot-  - get the uboot image over tftp.&lt;br /&gt;
&lt;br /&gt;
usb     - USB sub-system&lt;br /&gt;
verify  - Verify Image&lt;br /&gt;
version - print monitor, compiler and linker version&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Recoverying Firmware ==&lt;br /&gt;
&lt;br /&gt;
 Recovering Software - explains how to recover devices from image installation failure or deleted or corrupted flash images.&lt;br /&gt;
 https://docs.commscope.com/bundle/fastiron-09010-upgradeguide/page/GUID-9B5D5A56-039D-44FB-8FD2-B9B55E71ADE8.html&lt;br /&gt;
&lt;br /&gt;
Update flash image: &amp;lt;ref&amp;gt;https://docs.commscope.com/bundle/fastiron-09010-upgradeguide/page/GUID-9B5D5A56-039D-44FB-8FD2-B9B55E71ADE8.html&amp;lt;/ref&amp;gt; &amp;lt;ref&amp;gt;https://community.ruckuswireless.com/t5/RUCKUS-Support-for-Lennar-Homes/How-to-perform-a-Software-recovery-on-an-ICX7150-switch/m-p/47483&amp;lt;/ref&amp;gt;&lt;br /&gt;
* tftp 64 - https://bitbucket.org/phjounin/tftpd64/downloads/&lt;br /&gt;
** https://github.com/peacepenguin/tftpd64/releases&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
setenv ipaddr 192.168.0.3&lt;br /&gt;
setenv gatewayip 192.168.0.2&lt;br /&gt;
setenv netmask 255.255.255.0&lt;br /&gt;
setenv serverip 192.168.0.2&lt;br /&gt;
printenv&lt;br /&gt;
saveenv&lt;br /&gt;
ping 192.168.0.2&lt;br /&gt;
setenv image_name SPS08090k.bin&lt;br /&gt;
update_primary&lt;br /&gt;
# ...&lt;br /&gt;
reset&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Advanced =&lt;br /&gt;
&lt;br /&gt;
== Loop Detection ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
&amp;quot;Spanning Tree Protocol doesn&#039;t cause problems; loops cause problems.  STP is a way of dealing with loops.  If you don&#039;t have STP enabled already and your network is working correctly, then you don&#039;t have any loops.  So loop protect will not gain you anything.&amp;lt;br/&amp;gt;&lt;br /&gt;
It&#039;s not as simple as just enabling spanning tree.  You need to plan your topology, then set your switch priorities so that the planned topology is achieved.  To achieve protection against loops (due to users plugging switches into each other), the preferred approach would be to set up STP correctly, then enable BPDU guard and loop protect on all edge ports.&amp;lt;br/&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Definitely don&#039;t use loop protect on uplinks and trunks; it is designed for edge ports.&#039;&#039;&#039;&amp;quot; &amp;lt;ref&amp;gt;https://community.hpe.com/t5/hpe-aruba-networking-provision/loop-protect-and-trunk-groups-or-uplinks/td-p/6098585&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 sh loop-detection status&lt;br /&gt;
&lt;br /&gt;
 sh loop-detection disabled&lt;br /&gt;
&lt;br /&gt;
 sh errdisable summary&lt;br /&gt;
&lt;br /&gt;
 sh errdisable recovery&lt;br /&gt;
&lt;br /&gt;
== More ==&lt;br /&gt;
&lt;br /&gt;
 hitless-failover enable&lt;br /&gt;
&lt;br /&gt;
 sz registrar&lt;br /&gt;
&lt;br /&gt;
= License Upgrades =&lt;br /&gt;
&lt;br /&gt;
=== ICX 7150-48 10G Upgrade ===&lt;br /&gt;
&lt;br /&gt;
Sample:&lt;br /&gt;
 CoE certificate license to upgrade any ICX 7150 24-port or 48-port model from 4x 1G SFP to 2x 1G SFP &amp;amp; 2x 10G SFP+ uplink ports.&lt;br /&gt;
 https://www.ispsupplies.com/Brocade-BR-ICX-7150-41U210-P-01&lt;br /&gt;
 SKU: BR-ICX-7150-41U210-P-01&lt;br /&gt;
 $750&lt;br /&gt;
&lt;br /&gt;
 CoE certificate license to upgrade any ICX 7150 24-port or 48-port model from 2x 1G SFP &amp;amp; 2x 10G SFP+ to 4x 10G SFP+ uplink ports. Also includes L3 features (OSPF, VRRP, PIM, PBR)&lt;br /&gt;
 https://www.ispsupplies.com/Brocade-BR-ICX-7150-210U410R-P-01&lt;br /&gt;
 SKU: BR-ICX-7150-210U410R-P-01&lt;br /&gt;
 $750.00&lt;br /&gt;
&lt;br /&gt;
 CoE certificate license to upgrade any ICX 7150 24-port or 48-port model from 4x 1G SFP to 4x 10G SFP+ uplink ports. Also includes L3 features (OSPF, VRRP, PIM, PBR)&lt;br /&gt;
 https://www.ispsupplies.com/Brocade-BR-ICX-7150-41U410R-P-01&lt;br /&gt;
 SKU: BR-ICX-7150-41U410R-P-01&lt;br /&gt;
 $1,500.00&lt;br /&gt;
&lt;br /&gt;
So license progression is: 4x1G -&amp;gt; 2x1G &amp;amp; 2x10G -&amp;gt; 4x10G&lt;br /&gt;
&lt;br /&gt;
= Example Dumps =&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
interface ethernet 1/1/1&lt;br /&gt;
 port-name UPLINK&lt;br /&gt;
 loop-detection shutdown-disable&lt;br /&gt;
 speed-duplex 10G-full&lt;br /&gt;
!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
interface ethernet 1/1/5&lt;br /&gt;
 loop-detection&lt;br /&gt;
 speed-duplex 1000-full&lt;br /&gt;
 spanning-tree root-protect&lt;br /&gt;
 spanning-tree 802-1w admin-edge-port&lt;br /&gt;
 broadcast limit 1000 kbps&lt;br /&gt;
 multicast limit 8000 kbps&lt;br /&gt;
 trust dscp&lt;br /&gt;
!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
lag UPLINK1010 dynamic id 13&lt;br /&gt;
 ports ethe 1/1/3 to 1/1/4 ethe 2/1/3 to 2/1/4&lt;br /&gt;
 port-name UPLINK ethernet 1/1/3&lt;br /&gt;
 port-name UPLINK ethernet 1/1/4&lt;br /&gt;
 port-name UPLINK ethernet 2/1/3&lt;br /&gt;
 port-name UPLINK ethernet 2/1/4&lt;br /&gt;
!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
vlan 1010 name XYZ_1010_CI by port&lt;br /&gt;
 tagged ethe 1/1/10 to 1/1/20 ethe 2/1/15 to 2/1/20 lag 13&lt;br /&gt;
 spanning-tree 802-1w&lt;br /&gt;
 spanning-tree 802-1w priority 65535&lt;br /&gt;
 loop-detection&lt;br /&gt;
!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
vlan 3000 name LAB_MANAGEMENT by port&lt;br /&gt;
 tagged lag 10&lt;br /&gt;
 router-interface ve 3000&lt;br /&gt;
 spanning-tree 802-1w&lt;br /&gt;
 spanning-tree 802-1w priority 65535&lt;br /&gt;
 loop-detection&lt;br /&gt;
!&lt;br /&gt;
&lt;br /&gt;
hostname MRSwitch&lt;br /&gt;
ip dhcp-client disable&lt;br /&gt;
ip dns domain-list example.com&lt;br /&gt;
ip dns server-address 10.10.10.2&lt;br /&gt;
ip route 0.0.0.0/0 10.10.10.1&lt;br /&gt;
&lt;br /&gt;
interface ve 3000&lt;br /&gt;
 ip address 10.10.10.10 255.255.255.0&lt;br /&gt;
!&lt;br /&gt;
&lt;br /&gt;
ntp&lt;br /&gt;
 source-interface ve 3000&lt;br /&gt;
 server 10.20.2.1&lt;br /&gt;
 server 10.20.1.1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ntp&lt;br /&gt;
 server 10.20.2.1&lt;br /&gt;
 server 10.20.1.1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
banner motd ^C&lt;br /&gt;
################################################################################^C&lt;br /&gt;
#                          NOTICE TO USERS                                     #^C&lt;br /&gt;
# This is an official computer system and is the property of Example Corp.     #^C&lt;br /&gt;
# It is for authorized users only. Unauthorized users are prohibited. Users    #^C&lt;br /&gt;
# (authorized or unauthorized) have no explicit or implicit expectation of     #^C&lt;br /&gt;
# privacy. Any or all uses of this system may be subject to one or more of the #^C&lt;br /&gt;
# following actions: interception, monitoring, recording, auditing, inspection #^C&lt;br /&gt;
# and disclosing to security personnel and law enforcement personnel, as well  #^C&lt;br /&gt;
# as authorized officials of other agencies, both domestic and foreign. By     #^C&lt;br /&gt;
# using this system, the user consents to these actions. Unauthorized or       #^C&lt;br /&gt;
# improper use of this system may result in administrative disciplinary action #^C&lt;br /&gt;
# and civil and criminal penalties. By accessing this system you indicate your #^C&lt;br /&gt;
# awareness of and consent to these terms and conditions of use. Discontinue   #^C&lt;br /&gt;
# access immediately if you do not agree to the conditions stated in this      #^C&lt;br /&gt;
# notice.                                                                      #^C&lt;br /&gt;
################################################################################^C&lt;br /&gt;
^C&lt;br /&gt;
!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
banner motd ^C&lt;br /&gt;
-------------------------------------------------------------^C&lt;br /&gt;
- Note: Legal Notice!                                       -^C&lt;br /&gt;
-                                                           -^C&lt;br /&gt;
- You must have prior authorization to access this system.  -^C&lt;br /&gt;
- All connections to this system are logged and monitored.  -^C&lt;br /&gt;
- By connecting to this system you fully consent to all     -^C&lt;br /&gt;
- monitoring. Unauthorized access or use will be prosecuted -^C&lt;br /&gt;
- to the full extent of the law.                            -^C&lt;br /&gt;
-------------------------------------------------------------^C&lt;br /&gt;
^C&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
interface ethernet 1/1/1 to 1/1/48&lt;br /&gt;
 port-name DATA&lt;br /&gt;
 loop-detection&lt;br /&gt;
 spanning-tree root-protect&lt;br /&gt;
 spanning-tree 802-1w admin-edge-port&lt;br /&gt;
 broadcast limit 8192&lt;br /&gt;
 multicast limit 8192&lt;br /&gt;
 stp-bpdu-guard&lt;br /&gt;
 trust dscp&lt;br /&gt;
 enable&lt;br /&gt;
 exit&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= keywords =&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=SSSD&amp;diff=9837</id>
		<title>SSSD</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=SSSD&amp;diff=9837"/>
		<updated>2026-04-18T08:15:44Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: /* Configure /etc/sssd/sssd.conf */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Install SSSD ==&lt;br /&gt;
&lt;br /&gt;
 sudo apt install sssd-ad sssd-tools realmd adcli&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
The following additional packages will be installed:&lt;br /&gt;
  ldap-utils libbasicobjects0 libc-ares2 libcollection4 libdhash1 libini-config5 libipa-hbac0 libldap-2.5-0 libnfsidmap1 libnss-sss&lt;br /&gt;
  libpam-sss libpath-utils1 libref-array1 libsss-certmap0 libsss-idmap0 libsss-nss-idmap0 python3-sss sssd sssd-ad-common sssd-common&lt;br /&gt;
  sssd-dbus sssd-ipa sssd-krb5 sssd-krb5-common sssd-ldap sssd-proxy&lt;br /&gt;
Suggested packages:&lt;br /&gt;
  libsss-sudo libsasl2-modules-ldap&lt;br /&gt;
The following NEW packages will be installed:&lt;br /&gt;
  adcli ldap-utils libbasicobjects0 libc-ares2 libcollection4 libdhash1 libini-config5 libipa-hbac0 libnfsidmap1 libnss-sss&lt;br /&gt;
  libpath-utils1 libref-array1 libsss-certmap0 libsss-idmap0 libsss-nss-idmap0 python3-sss realmd sssd sssd-ad sssd-ad-common sssd-common&lt;br /&gt;
  sssd-dbus sssd-ipa sssd-krb5 sssd-krb5-common sssd-ldap sssd-proxy sssd-tools&lt;br /&gt;
The following packages will be upgraded:&lt;br /&gt;
  libldap-2.5-0 libpam-sss&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Prestage Machine in AD ==&lt;br /&gt;
&lt;br /&gt;
Someone with AD permission needs to give your userid permission to join the machine to AD.&lt;br /&gt;
&lt;br /&gt;
== Join AD ==&lt;br /&gt;
&lt;br /&gt;
 sudo realm join myad.example.com -U &amp;lt;userid_with_access&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Join with Additional verbosity, and specified computer-name&lt;br /&gt;
 sudo realm join myad.example.com -v --computer-name &amp;lt;system_name&amp;gt; -U &amp;lt;userid_with_access&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Leave AD ===&lt;br /&gt;
&lt;br /&gt;
 sudo realm leave myad.example.com&lt;br /&gt;
&lt;br /&gt;
 sudo realm join myad.example.com -U &amp;lt;userid_with_access&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Enable PAM mkhomedir ==&lt;br /&gt;
&lt;br /&gt;
 sudo pam-auth-update --enable mkhomedir&lt;br /&gt;
&lt;br /&gt;
== Configure /etc/sssd/sssd.conf ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[sssd]&lt;br /&gt;
domains = myad.example.com&lt;br /&gt;
config_file_version = 2&lt;br /&gt;
services = nss, pam&lt;br /&gt;
&lt;br /&gt;
[domain/myad.example.com]&lt;br /&gt;
default_shell = /bin/bash&lt;br /&gt;
krb5_store_password_if_offline = True&lt;br /&gt;
cache_credentials = True&lt;br /&gt;
krb5_realm = MYAD.example.com&lt;br /&gt;
realmd_tags = manages-system joined-with-adcli&lt;br /&gt;
id_provider = ad&lt;br /&gt;
ad_domain = myad.example.com&lt;br /&gt;
override_homedir = /home/%u&lt;br /&gt;
use_fully_qualified_names = False&lt;br /&gt;
ldap_id_mapping = True&lt;br /&gt;
access_provider = ad&lt;br /&gt;
ad_access_filter = DOM:myad.example.com:(memberOf=CN=&amp;lt;ad group name&amp;gt;,OU=user-managed,OU=security,OU=groups,OU=usersandgroups,OU=accounts,DC=myad,DC=example,DC=com)&lt;br /&gt;
ad_gpo_ignore_unreadable = True&lt;br /&gt;
ad_gpo_access_control = Permissive&lt;br /&gt;
ignore_group_members = True&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
Generic Template:&lt;br /&gt;
&lt;br /&gt;
== Enable Sudo ==&lt;br /&gt;
&lt;br /&gt;
 sudo vim /etc/sudoers&lt;br /&gt;
&lt;br /&gt;
* add individuals or groups from AD&lt;br /&gt;
* add line for individual like: MYAD\&amp;lt;employee-#&amp;gt; ALL=(ALL:ALL) ALL&lt;br /&gt;
* add line for group like: %MYAD\&amp;lt;myad.group&amp;gt; ALL=(ALL:ALL) ALL&lt;br /&gt;
&lt;br /&gt;
== Realm Details ==&lt;br /&gt;
&lt;br /&gt;
 sudo realm list&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ sudo realm list&lt;br /&gt;
myad.example.com&lt;br /&gt;
  type: kerberos&lt;br /&gt;
  realm-name: MYAD.EXAMPLE.COM&lt;br /&gt;
  domain-name: myad.example.com&lt;br /&gt;
  configured: kerberos-member&lt;br /&gt;
  server-software: active-directory&lt;br /&gt;
  client-software: sssd&lt;br /&gt;
  required-package: sssd-tools&lt;br /&gt;
  required-package: sssd&lt;br /&gt;
  required-package: libnss-sss&lt;br /&gt;
  required-package: libpam-sss&lt;br /&gt;
  required-package: adcli&lt;br /&gt;
  required-package: samba-common-bin&lt;br /&gt;
  login-formats: %U@myad.example.com&lt;br /&gt;
  login-policy: allow-realm-logins&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Or if using &amp;quot;simple&amp;quot; provider, with a couple of permitted logins, tail end might show up like this:&lt;br /&gt;
  login-formats: %U&lt;br /&gt;
  login-policy: allow-realm-logins&lt;br /&gt;
  permitted-logins: 123456, 456789&lt;br /&gt;
  permitted-groups: somegroup@myad.example.com, othergroup@myad.example.com&lt;br /&gt;
&lt;br /&gt;
== Restart Service ==&lt;br /&gt;
&lt;br /&gt;
 sudo systemctl restart sssd&lt;br /&gt;
&lt;br /&gt;
 sudo systemctl stop sssd ; sleep 3 ; sudo systemctl start sssd&lt;br /&gt;
&lt;br /&gt;
 sudo systemctl status sssd&lt;br /&gt;
&lt;br /&gt;
== Check User ==&lt;br /&gt;
&lt;br /&gt;
 getent -s sss passwd [USERID]&lt;br /&gt;
&lt;br /&gt;
 getent -s sss passwd 12345@myad.example.com&lt;br /&gt;
 12345:*:1455846733:1356800513:My User:/home/12345:/bin/bash&lt;br /&gt;
&lt;br /&gt;
 id [USERID]&lt;br /&gt;
&lt;br /&gt;
 id 12345@myad.example.com&lt;br /&gt;
 uid=1395846733(12345@myad.example.com) gid=1395800513(domain users@myad.example.com) groups=1395800513(domain users@myad.example.com),........&lt;br /&gt;
&lt;br /&gt;
== Clear Cache ==&lt;br /&gt;
&lt;br /&gt;
sss_cache - sss_cache invalidates records in SSSD cache. Invalidated records are forced to be reloaded from server as soon as related SSSD backend is online. Options that invalidate a single object only accept a single provided argument.&lt;br /&gt;
&lt;br /&gt;
Clear cache:&lt;br /&gt;
 # -E means everything&lt;br /&gt;
 sss_cache -E&lt;br /&gt;
&lt;br /&gt;
ref: https://docs.redhat.com/de/documentation/red_hat_enterprise_linux/6/html/deployment_guide/sssd-cache#sssd-cache&lt;br /&gt;
&lt;br /&gt;
=== Cache Size ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[nss]&lt;br /&gt;
# memcache_size_group = 6&lt;br /&gt;
memcache_size_group = 12&lt;br /&gt;
# memcache_size_initgroups = 10&lt;br /&gt;
memcache_size_initgroups = 20&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Files and Folders ==&lt;br /&gt;
&lt;br /&gt;
DB File:&lt;br /&gt;
 /var/lib/sss/db/cache_myad.example.com.ldb&lt;br /&gt;
&lt;br /&gt;
Timestamp file:&lt;br /&gt;
 /var/lib/sss/db/timestamps_myad.example.com.ldb&lt;br /&gt;
&lt;br /&gt;
Search/Dump the LDB DB:&lt;br /&gt;
 sudo apt install ldb-tools&lt;br /&gt;
 sudo ldbsearch -H /var/lib/sss/db/cache_myad.example.com.ldb&lt;br /&gt;
&lt;br /&gt;
== Issues ==&lt;br /&gt;
&lt;br /&gt;
=== Dynamic DNS update failed ===&lt;br /&gt;
&lt;br /&gt;
Logs report:&lt;br /&gt;
 [ad_dyndns_sdap_update_done] (0x0040): Dynamic DNS update failed [1432158240]: Dynamic DNS update failed&lt;br /&gt;
&lt;br /&gt;
Cause:&lt;br /&gt;
* You do not have AD permission to do Dynamic DNS updates&lt;br /&gt;
&lt;br /&gt;
Solution:&lt;br /&gt;
* Disable AD Dynamic DNS updates (or get permissions)&lt;br /&gt;
&lt;br /&gt;
/etc/sssd/sssd.conf&lt;br /&gt;
 [domain/DOMAIN_SECTION]&lt;br /&gt;
 # dyndns_update = True&lt;br /&gt;
 dyndns_update = False&lt;br /&gt;
&lt;br /&gt;
== PBIS ==&lt;br /&gt;
&lt;br /&gt;
See [[BeyondTrust]] / [[PBIS]]&lt;br /&gt;
&lt;br /&gt;
== keywords ==&lt;br /&gt;
&lt;br /&gt;
[[Category:Linux AD]]&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=BeyondTrust&amp;diff=9836</id>
		<title>BeyondTrust</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=BeyondTrust&amp;diff=9836"/>
		<updated>2026-04-15T22:39:22Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: /* BeyondTrust Enterprise AD Bridge */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== BeyondTrust AD Bridge Open-Source Community Project ==&lt;br /&gt;
&lt;br /&gt;
BeyondTrust AD Bridge Open is an open-source community project sponsored by BeyondTrust Corporation. It is currently archived and will no longer receive updates. If you are interested in an Enterprise version of this project, please see our AD Bridge product.&lt;br /&gt;
&lt;br /&gt;
See [[SSSD]] instead&lt;br /&gt;
&lt;br /&gt;
== SSSD ==&lt;br /&gt;
&lt;br /&gt;
See [[SSSD]]&lt;br /&gt;
&lt;br /&gt;
== Github ==&lt;br /&gt;
&lt;br /&gt;
 BeyondTrust AD Bridge Open&lt;br /&gt;
 https://github.com/BeyondTrust/pbis-open&lt;br /&gt;
&lt;br /&gt;
 PROJECT HAS BEEN ARCHIVED&lt;br /&gt;
 This repository has been archived by the owner on Nov 8, 2021. It is now read-only.&lt;br /&gt;
&lt;br /&gt;
 &amp;quot;We have decided to fork BeyondTrust AD Bridge Enterprise from BeyondTrust AD Bridge Open solution.&lt;br /&gt;
 Please consider BeyondTrust Active Directory Bridge for continued support.&amp;quot;&lt;br /&gt;
 https://www.beyondtrust.com/privilege-management/active-directory-bridge&lt;br /&gt;
 https://www.beyondtrust.com/products/active-directory-bridge&lt;br /&gt;
&lt;br /&gt;
== Install BeyondTrust AD Bridge ==&lt;br /&gt;
 BeyondTrust AD Bridge: APT Repository&lt;br /&gt;
 https://repo.pbis.beyondtrust.com/apt.html&lt;br /&gt;
&lt;br /&gt;
To add the BeyondTrust AD Bridge GPG key to your system:&lt;br /&gt;
 sudo wget -O /usr/share/keyrings/DEB-GPG-KEY-adb.gpg https://repo.pbis.beyondtrust.com/apt/DEB-GPG-KEY-adb.gpg&lt;br /&gt;
&lt;br /&gt;
To add the BeyondTrust AD Bridge repository to your system:&lt;br /&gt;
 sudo wget -O /etc/apt/sources.list.d/adbridge.sources https://repo.pbis.beyondtrust.com/apt/adbridge.sources&lt;br /&gt;
 sudo apt update&lt;br /&gt;
&lt;br /&gt;
Once your Repository has been added, install BeyondTrust AD Bridge:&lt;br /&gt;
 sudo apt install pbis-enterprise&lt;br /&gt;
&lt;br /&gt;
== What is PBIS ==&lt;br /&gt;
&lt;br /&gt;
 &amp;quot;PowerBroker Identity Services&amp;quot; &amp;lt;ref&amp;gt;https://github.com/BeyondTrust/pbis-open/releases/tag/8.8.0&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ref: &lt;br /&gt;
&lt;br /&gt;
It was renamed / rebranded to &amp;quot;BeyondTrust AD Bridge&amp;quot; in the 9.0 release. &amp;lt;ref&amp;gt;https://github.com/BeyondTrust/pbis-open/releases/tag/9.0.0&amp;lt;/ref&amp;gt; &amp;lt;ref&amp;gt;https://github.com/BeyondTrust/pbis-open/commit/54e888873e455aa876f5623b01aa36fedf6506a9&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Join Domain ==&lt;br /&gt;
&lt;br /&gt;
 /opt/pbis/bin/domainjoin-cli join AD-DOMAIN USER@AD-DOMAIN&lt;br /&gt;
&lt;br /&gt;
 /opt/pbis/bin/config UserDomainPrefix AD-DOMAIN&lt;br /&gt;
 /opt/pbis/bin/config AssumeDefaultDomain True&lt;br /&gt;
 /opt/pbis/bin/config LoginShellTemplate /bin/bash&lt;br /&gt;
 /opt/pbis/bin/config HomeDirTemplate %H/%U&lt;br /&gt;
&lt;br /&gt;
Grand AD users or security groups as &#039;root&#039;:&lt;br /&gt;
 /opt/pbis/bin/config RequireMembershipOf “AD-DOMAIN\&amp;lt;AD-DOMAIN-GROUP&amp;gt;” “AD-DOMAIN\&amp;lt;user&amp;gt;”&lt;br /&gt;
&lt;br /&gt;
Sudo: /etc/sudoers&lt;br /&gt;
 %DOMAIN\\&amp;lt;AD-DOMAIN-GROUP&amp;gt; ALL=(ALL) NOPASSWD:ALL&lt;br /&gt;
&lt;br /&gt;
== Set Machine Name ==&lt;br /&gt;
&lt;br /&gt;
Set machine name before joining:&lt;br /&gt;
 pbis set-machine-name [name]&lt;br /&gt;
&lt;br /&gt;
== Show All Config Settings ==&lt;br /&gt;
&lt;br /&gt;
 /opt/pbis/bin/config --dump&lt;br /&gt;
&lt;br /&gt;
== Show System Joined Details ==&lt;br /&gt;
&lt;br /&gt;
 $ /opt/pbis/bin/domainjoin-cli query&lt;br /&gt;
&lt;br /&gt;
 Name = MYSYSTEMNAME&lt;br /&gt;
 Domain = CORP.EXAMPLE.COM&lt;br /&gt;
 Distinguished Name = CN=MYSYSTEMNAME,OU=SOMESITE,OU=UnitedStates,OU=Eng,OU=Workstations,DC=corp,DC=example,DC=com&lt;br /&gt;
&lt;br /&gt;
== PBIS Full Details ==&lt;br /&gt;
&lt;br /&gt;
 pbis status&lt;br /&gt;
&lt;br /&gt;
== Dump all users ==&lt;br /&gt;
&lt;br /&gt;
 /opt/pbis/bin/enum-users&lt;br /&gt;
&lt;br /&gt;
== Authenticate User ==&lt;br /&gt;
&lt;br /&gt;
 pbis authenticate-user --user [USER]&lt;br /&gt;
&lt;br /&gt;
 pbis authenticate-user --user [USER] --domain [DOMAIN]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Usage: authenticate-user --user &amp;lt;name&amp;gt; --domain &amp;lt;name&amp;gt; [ --password &amp;lt;pass&amp;gt; ] [ --provider name ]&lt;br /&gt;
&lt;br /&gt;
    --user                  User name to authenticate with&lt;br /&gt;
    --domain                User&#039;s domain&lt;br /&gt;
    --password              User&#039;s password (prompted if not passed on commandline)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Clear Cache ==&lt;br /&gt;
&lt;br /&gt;
 /opt/pbis/bin/ad-cache --delete-all&lt;br /&gt;
 /opt/pbis/bin/lwsm restart lsass&lt;br /&gt;
&lt;br /&gt;
 rm -f /tmp/krb5cc_*&lt;br /&gt;
&lt;br /&gt;
 /opt/pbis/bin/ad-cache --delete-all&lt;br /&gt;
&lt;br /&gt;
== Allow Local Users ==&lt;br /&gt;
&lt;br /&gt;
If you still want to allow local users on the system, allow &amp;quot;Local&amp;quot; user providers, or &amp;quot;passwd&amp;quot; is not going to work for local accounts.&lt;br /&gt;
 /opt/pbis/bin/domainjoin-cli configure --enable nsswitch&lt;br /&gt;
 /opt/pbis/bin/domainjoin-cli configure --enable pam&lt;br /&gt;
 /opt/pbis/bin/config Providers &amp;quot;ActiveDirectory&amp;quot; &amp;quot;Local&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Add local users to pbis ignore list (one user per line). Default entries include &#039;root&#039; and &#039;tty&#039;.&lt;br /&gt;
 /etc/pbis/user-ignore&lt;br /&gt;
 /etc/pbis/group-ignore&lt;br /&gt;
&lt;br /&gt;
ref:&lt;br /&gt;
* https://docs.beyondtrust.com/adb/docs/configure-user-group-ignore&lt;br /&gt;
&lt;br /&gt;
--&lt;br /&gt;
&lt;br /&gt;
Also suggested to change Domain Prefix to &amp;quot;&amp;quot;&lt;br /&gt;
 /opt/pbis/bin/config UserDomainPrefix &amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== logs ==&lt;br /&gt;
&lt;br /&gt;
 /var/log/auth.log&lt;br /&gt;
&lt;br /&gt;
 /var/log/syslog or /var/log/messages&lt;br /&gt;
&lt;br /&gt;
== Services Status ==&lt;br /&gt;
&lt;br /&gt;
 /opt/pbis/bin/lwsm list&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
lwreg          running (container: 960)&lt;br /&gt;
dcerpc         stopped&lt;br /&gt;
eventlog       running (container: 1040)&lt;br /&gt;
lsass          running (container: 2701213)&lt;br /&gt;
lwio           running (container: 1183)&lt;br /&gt;
netlogon       running (container: 1126)&lt;br /&gt;
rdr            running (io: 1183)&lt;br /&gt;
reapsysl       running (container: 1324)&lt;br /&gt;
usermonitor    stopped&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== lwsm ===&lt;br /&gt;
&lt;br /&gt;
 /opt/pbis/bin/lwsm settings&lt;br /&gt;
   watchdog: on&lt;br /&gt;
&lt;br /&gt;
 /opt/pbis/bin/lwsm shutdown&lt;br /&gt;
&lt;br /&gt;
== Latest Release ==&lt;br /&gt;
&lt;br /&gt;
AD Bridge Open 9.1.0.551&lt;br /&gt;
 pbis-open-9.1.0.551.linux.x86.deb.sh - https://github.com/BeyondTrust/pbis-open/releases/download/9.1.0/pbis-open-9.1.0.551.linux.x86.deb.sh&lt;br /&gt;
 pbis-open-9.1.0.551.linux.x86.rpm.sh - https://github.com/BeyondTrust/pbis-open/releases/download/9.1.0/pbis-open-9.1.0.551.linux.x86.rpm.sh&lt;br /&gt;
 pbis-open-9.1.0.551.linux.x86_64.deb.sh - https://github.com/BeyondTrust/pbis-open/releases/download/9.1.0/pbis-open-9.1.0.551.linux.x86_64.deb.sh&lt;br /&gt;
 pbis-open-9.1.0.551.linux.x86_64.rpm.sh - https://github.com/BeyondTrust/pbis-open/releases/download/9.1.0/pbis-open-9.1.0.551.linux.x86_64.rpm.sh&lt;br /&gt;
&lt;br /&gt;
Source:&lt;br /&gt;
 https://github.com/BeyondTrust/pbis-open/archive/refs/tags/9.1.0.zip&lt;br /&gt;
 https://github.com/BeyondTrust/pbis-open/archive/refs/tags/9.1.0.tar.gz&lt;br /&gt;
&lt;br /&gt;
Tag: AD Bridge Open 9.1.0.551&lt;br /&gt;
 https://github.com/BeyondTrust/pbis-open/releases/tag/9.1.0&lt;br /&gt;
&lt;br /&gt;
== Sudo ==&lt;br /&gt;
&lt;br /&gt;
 [root@license-01 sudoers.d]# cat admin&lt;br /&gt;
 # Ansible managed | any changes in this file will be overwritten&lt;br /&gt;
 %AD\\it-infra ALL=(ALL:ALL) NOPASSWD: ALL&lt;br /&gt;
&lt;br /&gt;
 [root@license-01 sudoers.d]# cat pbissudouser&lt;br /&gt;
 # Ansible managed | any changes in this file will be overwritten&lt;br /&gt;
 1234   ALL=(root) NOPASSWD: ALL&lt;br /&gt;
 %ENG-INFRA   ALL=(root) NOPASSWD: ALL&lt;br /&gt;
 %eng-infra   ALL=(root) NOPASSWD: ALL&lt;br /&gt;
&lt;br /&gt;
== BeyondTrust Enterprise AD Bridge ==&lt;br /&gt;
&lt;br /&gt;
 https://repo.pbis.beyondtrust.com/&lt;br /&gt;
* https://repo.pbis.beyondtrust.com/apt.html&lt;br /&gt;
* https://repo.pbis.beyondtrust.com/yum.html&lt;br /&gt;
&lt;br /&gt;
 https://www.beyondtrust.com/docs/archive/ad-bridge/9-1/adb-windows-administration-guide-9-1.pdf&lt;br /&gt;
&lt;br /&gt;
 https://docs.beyondtrust.com/adb/docs/adb-overview&lt;br /&gt;
&lt;br /&gt;
 https://docs.beyondtrust.com/adb/docs/install-adb&lt;br /&gt;
&lt;br /&gt;
== Issues ==&lt;br /&gt;
&lt;br /&gt;
=== LW_ERROR_LDAP_INSUFFICIENT_ACCESS ===&lt;br /&gt;
&lt;br /&gt;
Error:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# /opt/pbis/bin/domainjoin-cli --loglevel verbose join corp.example.com MYUSER&lt;br /&gt;
Joining to AD Domain:   corp.example.com&lt;br /&gt;
With Computer DNS Name: fixit01.corp.example.com&lt;br /&gt;
&lt;br /&gt;
MYUSER@CORP.EXAMPLE.COM&#039;s password:&lt;br /&gt;
&lt;br /&gt;
Error: LW_ERROR_LDAP_INSUFFICIENT_ACCESS [code 0x00009d8b]&lt;br /&gt;
&lt;br /&gt;
Insufficient access to perform LDAP operation&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Logs:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Apr 15 15:27:09 fixit01 lsass: [lsass] Failed to set computer account attribute msDS-SupportedEncryptionTypes. LW_ERROR_LDAP_INSUFFICIENT_ACCESS(40331)&lt;br /&gt;
Apr 15 15:27:09 fixit01 lsass: [lsass] Failed to run provider specific request (request code = 8, provider = &#039;lsa-activedirectory-provider&#039;) -&amp;gt; error = 40331, symbol = LW_ERROR_LDAP_INSUFFICIENT_ACCESS, client pid = 5462&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Solution:&lt;br /&gt;
* Have your IT give you write permission to attribute msDS-SupportedEncryptionTypes.  PBIS does not give you a way to not actively try to set this.&lt;br /&gt;
&lt;br /&gt;
== keywords ==&lt;br /&gt;
&lt;br /&gt;
[[Category:Linux AD]]&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=BeyondTrust&amp;diff=9835</id>
		<title>BeyondTrust</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=BeyondTrust&amp;diff=9835"/>
		<updated>2026-04-15T21:38:20Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: /* Github */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== BeyondTrust AD Bridge Open-Source Community Project ==&lt;br /&gt;
&lt;br /&gt;
BeyondTrust AD Bridge Open is an open-source community project sponsored by BeyondTrust Corporation. It is currently archived and will no longer receive updates. If you are interested in an Enterprise version of this project, please see our AD Bridge product.&lt;br /&gt;
&lt;br /&gt;
See [[SSSD]] instead&lt;br /&gt;
&lt;br /&gt;
== SSSD ==&lt;br /&gt;
&lt;br /&gt;
See [[SSSD]]&lt;br /&gt;
&lt;br /&gt;
== Github ==&lt;br /&gt;
&lt;br /&gt;
 BeyondTrust AD Bridge Open&lt;br /&gt;
 https://github.com/BeyondTrust/pbis-open&lt;br /&gt;
&lt;br /&gt;
 PROJECT HAS BEEN ARCHIVED&lt;br /&gt;
 This repository has been archived by the owner on Nov 8, 2021. It is now read-only.&lt;br /&gt;
&lt;br /&gt;
 &amp;quot;We have decided to fork BeyondTrust AD Bridge Enterprise from BeyondTrust AD Bridge Open solution.&lt;br /&gt;
 Please consider BeyondTrust Active Directory Bridge for continued support.&amp;quot;&lt;br /&gt;
 https://www.beyondtrust.com/privilege-management/active-directory-bridge&lt;br /&gt;
 https://www.beyondtrust.com/products/active-directory-bridge&lt;br /&gt;
&lt;br /&gt;
== Install BeyondTrust AD Bridge ==&lt;br /&gt;
 BeyondTrust AD Bridge: APT Repository&lt;br /&gt;
 https://repo.pbis.beyondtrust.com/apt.html&lt;br /&gt;
&lt;br /&gt;
To add the BeyondTrust AD Bridge GPG key to your system:&lt;br /&gt;
 sudo wget -O /usr/share/keyrings/DEB-GPG-KEY-adb.gpg https://repo.pbis.beyondtrust.com/apt/DEB-GPG-KEY-adb.gpg&lt;br /&gt;
&lt;br /&gt;
To add the BeyondTrust AD Bridge repository to your system:&lt;br /&gt;
 sudo wget -O /etc/apt/sources.list.d/adbridge.sources https://repo.pbis.beyondtrust.com/apt/adbridge.sources&lt;br /&gt;
 sudo apt update&lt;br /&gt;
&lt;br /&gt;
Once your Repository has been added, install BeyondTrust AD Bridge:&lt;br /&gt;
 sudo apt install pbis-enterprise&lt;br /&gt;
&lt;br /&gt;
== What is PBIS ==&lt;br /&gt;
&lt;br /&gt;
 &amp;quot;PowerBroker Identity Services&amp;quot; &amp;lt;ref&amp;gt;https://github.com/BeyondTrust/pbis-open/releases/tag/8.8.0&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ref: &lt;br /&gt;
&lt;br /&gt;
It was renamed / rebranded to &amp;quot;BeyondTrust AD Bridge&amp;quot; in the 9.0 release. &amp;lt;ref&amp;gt;https://github.com/BeyondTrust/pbis-open/releases/tag/9.0.0&amp;lt;/ref&amp;gt; &amp;lt;ref&amp;gt;https://github.com/BeyondTrust/pbis-open/commit/54e888873e455aa876f5623b01aa36fedf6506a9&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Join Domain ==&lt;br /&gt;
&lt;br /&gt;
 /opt/pbis/bin/domainjoin-cli join AD-DOMAIN USER@AD-DOMAIN&lt;br /&gt;
&lt;br /&gt;
 /opt/pbis/bin/config UserDomainPrefix AD-DOMAIN&lt;br /&gt;
 /opt/pbis/bin/config AssumeDefaultDomain True&lt;br /&gt;
 /opt/pbis/bin/config LoginShellTemplate /bin/bash&lt;br /&gt;
 /opt/pbis/bin/config HomeDirTemplate %H/%U&lt;br /&gt;
&lt;br /&gt;
Grand AD users or security groups as &#039;root&#039;:&lt;br /&gt;
 /opt/pbis/bin/config RequireMembershipOf “AD-DOMAIN\&amp;lt;AD-DOMAIN-GROUP&amp;gt;” “AD-DOMAIN\&amp;lt;user&amp;gt;”&lt;br /&gt;
&lt;br /&gt;
Sudo: /etc/sudoers&lt;br /&gt;
 %DOMAIN\\&amp;lt;AD-DOMAIN-GROUP&amp;gt; ALL=(ALL) NOPASSWD:ALL&lt;br /&gt;
&lt;br /&gt;
== Set Machine Name ==&lt;br /&gt;
&lt;br /&gt;
Set machine name before joining:&lt;br /&gt;
 pbis set-machine-name [name]&lt;br /&gt;
&lt;br /&gt;
== Show All Config Settings ==&lt;br /&gt;
&lt;br /&gt;
 /opt/pbis/bin/config --dump&lt;br /&gt;
&lt;br /&gt;
== Show System Joined Details ==&lt;br /&gt;
&lt;br /&gt;
 $ /opt/pbis/bin/domainjoin-cli query&lt;br /&gt;
&lt;br /&gt;
 Name = MYSYSTEMNAME&lt;br /&gt;
 Domain = CORP.EXAMPLE.COM&lt;br /&gt;
 Distinguished Name = CN=MYSYSTEMNAME,OU=SOMESITE,OU=UnitedStates,OU=Eng,OU=Workstations,DC=corp,DC=example,DC=com&lt;br /&gt;
&lt;br /&gt;
== PBIS Full Details ==&lt;br /&gt;
&lt;br /&gt;
 pbis status&lt;br /&gt;
&lt;br /&gt;
== Dump all users ==&lt;br /&gt;
&lt;br /&gt;
 /opt/pbis/bin/enum-users&lt;br /&gt;
&lt;br /&gt;
== Authenticate User ==&lt;br /&gt;
&lt;br /&gt;
 pbis authenticate-user --user [USER]&lt;br /&gt;
&lt;br /&gt;
 pbis authenticate-user --user [USER] --domain [DOMAIN]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Usage: authenticate-user --user &amp;lt;name&amp;gt; --domain &amp;lt;name&amp;gt; [ --password &amp;lt;pass&amp;gt; ] [ --provider name ]&lt;br /&gt;
&lt;br /&gt;
    --user                  User name to authenticate with&lt;br /&gt;
    --domain                User&#039;s domain&lt;br /&gt;
    --password              User&#039;s password (prompted if not passed on commandline)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Clear Cache ==&lt;br /&gt;
&lt;br /&gt;
 /opt/pbis/bin/ad-cache --delete-all&lt;br /&gt;
 /opt/pbis/bin/lwsm restart lsass&lt;br /&gt;
&lt;br /&gt;
 rm -f /tmp/krb5cc_*&lt;br /&gt;
&lt;br /&gt;
 /opt/pbis/bin/ad-cache --delete-all&lt;br /&gt;
&lt;br /&gt;
== Allow Local Users ==&lt;br /&gt;
&lt;br /&gt;
If you still want to allow local users on the system, allow &amp;quot;Local&amp;quot; user providers, or &amp;quot;passwd&amp;quot; is not going to work for local accounts.&lt;br /&gt;
 /opt/pbis/bin/domainjoin-cli configure --enable nsswitch&lt;br /&gt;
 /opt/pbis/bin/domainjoin-cli configure --enable pam&lt;br /&gt;
 /opt/pbis/bin/config Providers &amp;quot;ActiveDirectory&amp;quot; &amp;quot;Local&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Add local users to pbis ignore list (one user per line). Default entries include &#039;root&#039; and &#039;tty&#039;.&lt;br /&gt;
 /etc/pbis/user-ignore&lt;br /&gt;
 /etc/pbis/group-ignore&lt;br /&gt;
&lt;br /&gt;
ref:&lt;br /&gt;
* https://docs.beyondtrust.com/adb/docs/configure-user-group-ignore&lt;br /&gt;
&lt;br /&gt;
--&lt;br /&gt;
&lt;br /&gt;
Also suggested to change Domain Prefix to &amp;quot;&amp;quot;&lt;br /&gt;
 /opt/pbis/bin/config UserDomainPrefix &amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== logs ==&lt;br /&gt;
&lt;br /&gt;
 /var/log/auth.log&lt;br /&gt;
&lt;br /&gt;
 /var/log/syslog or /var/log/messages&lt;br /&gt;
&lt;br /&gt;
== Services Status ==&lt;br /&gt;
&lt;br /&gt;
 /opt/pbis/bin/lwsm list&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
lwreg          running (container: 960)&lt;br /&gt;
dcerpc         stopped&lt;br /&gt;
eventlog       running (container: 1040)&lt;br /&gt;
lsass          running (container: 2701213)&lt;br /&gt;
lwio           running (container: 1183)&lt;br /&gt;
netlogon       running (container: 1126)&lt;br /&gt;
rdr            running (io: 1183)&lt;br /&gt;
reapsysl       running (container: 1324)&lt;br /&gt;
usermonitor    stopped&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== lwsm ===&lt;br /&gt;
&lt;br /&gt;
 /opt/pbis/bin/lwsm settings&lt;br /&gt;
   watchdog: on&lt;br /&gt;
&lt;br /&gt;
 /opt/pbis/bin/lwsm shutdown&lt;br /&gt;
&lt;br /&gt;
== Latest Release ==&lt;br /&gt;
&lt;br /&gt;
AD Bridge Open 9.1.0.551&lt;br /&gt;
 pbis-open-9.1.0.551.linux.x86.deb.sh - https://github.com/BeyondTrust/pbis-open/releases/download/9.1.0/pbis-open-9.1.0.551.linux.x86.deb.sh&lt;br /&gt;
 pbis-open-9.1.0.551.linux.x86.rpm.sh - https://github.com/BeyondTrust/pbis-open/releases/download/9.1.0/pbis-open-9.1.0.551.linux.x86.rpm.sh&lt;br /&gt;
 pbis-open-9.1.0.551.linux.x86_64.deb.sh - https://github.com/BeyondTrust/pbis-open/releases/download/9.1.0/pbis-open-9.1.0.551.linux.x86_64.deb.sh&lt;br /&gt;
 pbis-open-9.1.0.551.linux.x86_64.rpm.sh - https://github.com/BeyondTrust/pbis-open/releases/download/9.1.0/pbis-open-9.1.0.551.linux.x86_64.rpm.sh&lt;br /&gt;
&lt;br /&gt;
Source:&lt;br /&gt;
 https://github.com/BeyondTrust/pbis-open/archive/refs/tags/9.1.0.zip&lt;br /&gt;
 https://github.com/BeyondTrust/pbis-open/archive/refs/tags/9.1.0.tar.gz&lt;br /&gt;
&lt;br /&gt;
Tag: AD Bridge Open 9.1.0.551&lt;br /&gt;
 https://github.com/BeyondTrust/pbis-open/releases/tag/9.1.0&lt;br /&gt;
&lt;br /&gt;
== Sudo ==&lt;br /&gt;
&lt;br /&gt;
 [root@license-01 sudoers.d]# cat admin&lt;br /&gt;
 # Ansible managed | any changes in this file will be overwritten&lt;br /&gt;
 %AD\\it-infra ALL=(ALL:ALL) NOPASSWD: ALL&lt;br /&gt;
&lt;br /&gt;
 [root@license-01 sudoers.d]# cat pbissudouser&lt;br /&gt;
 # Ansible managed | any changes in this file will be overwritten&lt;br /&gt;
 1234   ALL=(root) NOPASSWD: ALL&lt;br /&gt;
 %ENG-INFRA   ALL=(root) NOPASSWD: ALL&lt;br /&gt;
 %eng-infra   ALL=(root) NOPASSWD: ALL&lt;br /&gt;
&lt;br /&gt;
== BeyondTrust Enterprise AD Bridge ==&lt;br /&gt;
&lt;br /&gt;
 https://repo.pbis.beyondtrust.com/&lt;br /&gt;
* https://repo.pbis.beyondtrust.com/apt.html&lt;br /&gt;
* https://repo.pbis.beyondtrust.com/yum.html&lt;br /&gt;
&lt;br /&gt;
 https://www.beyondtrust.com/docs/archive/ad-bridge/9-1/adb-windows-administration-guide-9-1.pdf&lt;br /&gt;
&lt;br /&gt;
 https://docs.beyondtrust.com/adb/docs/adb-overview&lt;br /&gt;
&lt;br /&gt;
 https://docs.beyondtrust.com/adb/docs/install-adb&lt;br /&gt;
&lt;br /&gt;
== keywords ==&lt;br /&gt;
&lt;br /&gt;
[[Category:Linux AD]]&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=Netplan&amp;diff=9834</id>
		<title>Netplan</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=Netplan&amp;diff=9834"/>
		<updated>2026-04-15T18:09:21Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: /* dhcp */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== config ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# /etc/netplan/01-netcfg.yaml&lt;br /&gt;
network:&lt;br /&gt;
  ethernets:&lt;br /&gt;
    ens18:&lt;br /&gt;
      dhcp4: true&lt;br /&gt;
  version: 2&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
-&lt;br /&gt;
&lt;br /&gt;
 sudo netplan apply&lt;br /&gt;
&lt;br /&gt;
Debug plan:&lt;br /&gt;
 sudo netplan --debug apply&lt;br /&gt;
   # note &amp;quot;apply --debug&amp;quot; does not work&lt;br /&gt;
&lt;br /&gt;
-&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# networkctl&lt;br /&gt;
IDX LINK  TYPE     OPERATIONAL SETUP&lt;br /&gt;
  1 lo    loopback carrier     unmanaged&lt;br /&gt;
  2 ens18 ether    routable    configured&lt;br /&gt;
&lt;br /&gt;
2 links listed.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
-&lt;br /&gt;
&lt;br /&gt;
Ubuntu to regen machine-id &amp;lt;ref&amp;gt;https://unix.stackexchange.com/questions/402999/is-it-ok-to-change-etc-machine-id&amp;lt;/ref&amp;gt;&lt;br /&gt;
 rm -f /etc/machine-id /var/lib/dbus/machine-id&lt;br /&gt;
 # dbus-uuidgen --ensure=/etc/machine-id&lt;br /&gt;
 dbus-uuidgen --ensure&lt;br /&gt;
 #cp /var/lib/dbus/machine-id /etc/machine-id&lt;br /&gt;
 systemd-machine-id-setup&lt;br /&gt;
 # verify:&lt;br /&gt;
 cat /etc/machine-id /var/lib/dbus/machine-id&lt;br /&gt;
 hostnamectl&lt;br /&gt;
&lt;br /&gt;
== examples ==&lt;br /&gt;
&lt;br /&gt;
 https://github.com/canonical/netplan/tree/main/examples&lt;br /&gt;
&lt;br /&gt;
== static ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
network:&lt;br /&gt;
  version: 2&lt;br /&gt;
  renderer: networkd&lt;br /&gt;
  ethernets:&lt;br /&gt;
    enp3s0:&lt;br /&gt;
      addresses:&lt;br /&gt;
        - 10.10.10.2/24&lt;br /&gt;
      nameservers:&lt;br /&gt;
        search: [mydomain, otherdomain]&lt;br /&gt;
        addresses: [10.10.10.1, 1.1.1.1]&lt;br /&gt;
      routes: &lt;br /&gt;
        - to: default&lt;br /&gt;
          via: 10.10.10.1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ref: https://github.com/canonical/netplan/blob/main/examples/static.yaml&lt;br /&gt;
&lt;br /&gt;
== dhcp ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
network:&lt;br /&gt;
  version: 2&lt;br /&gt;
  renderer: networkd&lt;br /&gt;
  ethernets:&lt;br /&gt;
    enp3s0:&lt;br /&gt;
      dhcp4: true&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ref: https://github.com/canonical/netplan/blob/main/examples/dhcp.yaml&lt;br /&gt;
&lt;br /&gt;
== vlan ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
network:&lt;br /&gt;
    version: 2&lt;br /&gt;
    ethernets:&lt;br /&gt;
        eno1:&lt;br /&gt;
            ... eno1 config ...&lt;br /&gt;
    vlans:&lt;br /&gt;
        vlan100:&lt;br /&gt;
            id: 100&lt;br /&gt;
            link: eno1&lt;br /&gt;
            addresses: [10.0.0.100/24]&lt;br /&gt;
            # dhcp4: true&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Renderer ==&lt;br /&gt;
&lt;br /&gt;
Warning: If both systemd-networkd and NetworkManager are active on the same interface, conflicts may occur. The renderer setting ensures control is delegated correctly.&lt;br /&gt;
&lt;br /&gt;
=== networkd ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
network:&lt;br /&gt;
  version: 2&lt;br /&gt;
  renderer: networkd&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== NetworkManager ===&lt;br /&gt;
&lt;br /&gt;
This system is being managed by NetworkManager.&lt;br /&gt;
&lt;br /&gt;
Default:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Let NetworkManager manage all devices on this system&lt;br /&gt;
network:&lt;br /&gt;
  version: 2&lt;br /&gt;
  renderer: NetworkManager&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
More:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Let NetworkManager manage all devices on this system&lt;br /&gt;
network:&lt;br /&gt;
  version: 2&lt;br /&gt;
  renderer: NetworkManager&lt;br /&gt;
  ethernets:&lt;br /&gt;
    enp3s0:&lt;br /&gt;
      dhcp4: true&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Apply configuration:&lt;br /&gt;
 sudo netplan apply&lt;br /&gt;
&lt;br /&gt;
Verify backend:&lt;br /&gt;
 nmcli device status&lt;br /&gt;
&lt;br /&gt;
Warning: If both systemd-networkd and NetworkManager are active on the same interface, conflicts may occur. The renderer setting ensures control is delegated correctly.&lt;br /&gt;
&lt;br /&gt;
== keywords ==&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=Linux/ip&amp;diff=9833</id>
		<title>Linux/ip</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=Linux/ip&amp;diff=9833"/>
		<updated>2026-04-15T18:07:06Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: /* VLAN */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Install ip tool ==&lt;br /&gt;
&lt;br /&gt;
 apt install iproute2&lt;br /&gt;
&lt;br /&gt;
== Add static IP ==&lt;br /&gt;
&lt;br /&gt;
 sudo ip addr add 192.168.1.2/24 dev eth0;&lt;br /&gt;
 sudo ip route add default via 192.168.1.1 dev eth0;&lt;br /&gt;
&lt;br /&gt;
=== Remove static IP ===&lt;br /&gt;
&lt;br /&gt;
 sudo ip addr del 192.168.1.2/24 dev eth0;&lt;br /&gt;
&lt;br /&gt;
== Bring interface online ==&lt;br /&gt;
&lt;br /&gt;
 ip link set dev &amp;lt;interface&amp;gt; up&lt;br /&gt;
 ip link set dev &amp;lt;interface&amp;gt; down&lt;br /&gt;
&lt;br /&gt;
== Interface Alias ==&lt;br /&gt;
&lt;br /&gt;
Change name: (change enp39s0 to eth0)&lt;br /&gt;
 ip link set enp39s0 name eth0&lt;br /&gt;
&lt;br /&gt;
Add Alias: (add eth0 to enp39s0)&lt;br /&gt;
 ip link property add dev enp39s0 altname eth0&lt;br /&gt;
 ip link property del dev enp39s0 altname eth0&lt;br /&gt;
&lt;br /&gt;
== Add Temporary IP to Interface ==&lt;br /&gt;
&lt;br /&gt;
 ip a add 192.168.178.2/24 dev eth0&lt;br /&gt;
&lt;br /&gt;
== Route ==&lt;br /&gt;
&lt;br /&gt;
Print routes:&lt;br /&gt;
 ip route&lt;br /&gt;
&lt;br /&gt;
Add default route:&lt;br /&gt;
 sudo ip route add default via 192.168.1.1 dev eth0;&lt;br /&gt;
&lt;br /&gt;
Add route:&lt;br /&gt;
 sudo ip route add 172.10.1.0/24 via 192.168.1.1 dev eth0;&lt;br /&gt;
&lt;br /&gt;
== VLAN ==&lt;br /&gt;
&lt;br /&gt;
The 8021q module is often loaded by default. If necessary, you can make sure that the module is loaded by issuing the following command as root:&lt;br /&gt;
 # modprobe --first-time 8021q&lt;br /&gt;
 modprobe: ERROR: could not insert &#039;8021q&#039;: Module already in kernel&lt;br /&gt;
&lt;br /&gt;
 To display information about the module, issue the following command:&lt;br /&gt;
 $ modinfo 8021q&lt;br /&gt;
&lt;br /&gt;
802.1Q VLAN Tagging using ip command:&lt;br /&gt;
 ip link add link enp1s0 name enp1s0.8 type vlan id 8&lt;br /&gt;
&lt;br /&gt;
 # or&lt;br /&gt;
 ip link add link enp1s0 name vlan100 type vlan id 100&lt;br /&gt;
&lt;br /&gt;
 # Syntax: sudo ip link add link [parent] name [vlan_name] type vlan id [vlan_id]&lt;br /&gt;
 sudo ip link add link eth0 name eth0.100 type vlan id 100&lt;br /&gt;
&lt;br /&gt;
Activate interface:&lt;br /&gt;
 sudo ip link set dev eth0.100 up&lt;br /&gt;
 sudo ip link set dev eth0 up&lt;br /&gt;
&lt;br /&gt;
 sudo ip link set dev vlan100 up&lt;br /&gt;
 &lt;br /&gt;
Assign ip:&lt;br /&gt;
 sudo ip addr add 192.168.100.10/24 dev eth0.100&lt;br /&gt;
&lt;br /&gt;
OR DHCP:&lt;br /&gt;
 dhclient -v eth0.100&lt;br /&gt;
&lt;br /&gt;
 # to release&lt;br /&gt;
 dhclient -r eth0.100&lt;br /&gt;
&lt;br /&gt;
To view the VLAN:&lt;br /&gt;
 ip -d link show enp1s0.8&lt;br /&gt;
&lt;br /&gt;
Show general details:&lt;br /&gt;
 ip addr show eth0.100&lt;br /&gt;
&lt;br /&gt;
To remove:&lt;br /&gt;
 sudo ip link set dev eth0.100 down&lt;br /&gt;
 sudo ip link delete eth0.100&lt;br /&gt;
&lt;br /&gt;
 sudo ip link delete enp1s0.8&lt;br /&gt;
&lt;br /&gt;
To use multiple interfaces belonging to multiple VLANs, create locally enp1s0.1 and enp1s0.2 with the appropriate VLAN ID on top of a physical interface enp1s0:&lt;br /&gt;
 # ip link add link enp1s0 name enp1s0.1 type vlan id 1&lt;br /&gt;
    ip link set dev enp1s0.1 up&lt;br /&gt;
 # ip link add link enp1s0 name enp1s0.2 type vlan id 2&lt;br /&gt;
    ip link set dev enp1s0.2 up&lt;br /&gt;
&lt;br /&gt;
tcpdump capture tagged frames:&lt;br /&gt;
 tcpdump -nnei enp1s0 -vvv&lt;br /&gt;
&lt;br /&gt;
To make permanent: &amp;lt;ref&amp;gt;https://askubuntu.com/questions/660506/how-to-setup-and-save-vlans-on-ethernet&amp;lt;/ref&amp;gt;&lt;br /&gt;
 # install vlan tool:&lt;br /&gt;
 sudo apt-get install vlan&lt;br /&gt;
&lt;br /&gt;
 # load module:&lt;br /&gt;
 sudo modprobe 8021q&lt;br /&gt;
&lt;br /&gt;
 # add interface:&lt;br /&gt;
 sudo vconfig add eth0 100&lt;br /&gt;
&lt;br /&gt;
 # assign ip&lt;br /&gt;
 sudo ip addr add 10.0.0.1/24 dev eth0.100&lt;br /&gt;
&lt;br /&gt;
 # add to modules:&lt;br /&gt;
 sudo bash -c &#039;echo &amp;quot;8021q&amp;quot; &amp;gt;&amp;gt; /etc/modules&#039;&lt;br /&gt;
&lt;br /&gt;
 /etc/network/interfaces&lt;br /&gt;
  auto eth0.100&lt;br /&gt;
  iface eth0.100 inet dhcp&lt;br /&gt;
&lt;br /&gt;
 # or&lt;br /&gt;
 auto eth0.100&lt;br /&gt;
 iface eth0.100 inet dhcp&lt;br /&gt;
    vlan-raw-device eth0&lt;br /&gt;
&lt;br /&gt;
netplan version: &amp;lt;ref&amp;gt;https://askubuntu.com/questions/660506/how-to-setup-and-save-vlans-on-ethernet&amp;lt;/ref&amp;gt; &amp;lt;ref&amp;gt;https://netplan.io/reference/#properties-for-device-type-vlans%3A&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
network:&lt;br /&gt;
    version: 2&lt;br /&gt;
    ethernets:&lt;br /&gt;
        eno1:&lt;br /&gt;
            ... eno1 config ...&lt;br /&gt;
    vlans:&lt;br /&gt;
        vlan100:&lt;br /&gt;
            id: 100&lt;br /&gt;
            link: eno1&lt;br /&gt;
            addresses: [10.0.0.100/24]&lt;br /&gt;
            # dhcp4: true&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will make an interface called vlan100@eno1&lt;br /&gt;
&lt;br /&gt;
ref:&lt;br /&gt;
* 10.4. Configure 802.1Q VLAN Tagging Using the Command Line | Networking Guide | Red Hat Enterprise Linux | 7 | Red Hat Documentation - https://docs.redhat.com/en/documentation/red_hat_enterprise_linux/7/html/networking_guide/sec-configure_802_1q_vlan_tagging_using_the_command_line&lt;br /&gt;
&lt;br /&gt;
== Ways to get Private IP Address ==&lt;br /&gt;
&lt;br /&gt;
=== ifconfig ===&lt;br /&gt;
&lt;br /&gt;
 ifconfig&lt;br /&gt;
&lt;br /&gt;
=== ip addr ===&lt;br /&gt;
&lt;br /&gt;
 # will need to be parsed&lt;br /&gt;
 ip addr&lt;br /&gt;
 ip a&lt;br /&gt;
 ip addr show&lt;br /&gt;
 ip -br -c a&lt;br /&gt;
&lt;br /&gt;
 # parsed&lt;br /&gt;
 ip route get 1 | awk &#039;{print $(NF-2);exit}&#039; &lt;br /&gt;
 ip route get 1 | sed -n &#039;s/^.*src \([0-9.]*\) .*$/\1/p&#039;&lt;br /&gt;
 ip -o route get to 8.8.8.8 | sed -n &#039;s/.*src \([0-9.]\+\).*/\1/p&#039;&lt;br /&gt;
 read -r _{,} gateway _ iface _ ip _ &amp;lt; &amp;lt;(ip r g 1.0.0.0) ; printf &#039;%-12s %s\n&#039;  gateway $gateway iface $iface ip $ip # &amp;lt;ref&amp;gt;https://stackoverflow.com/questions/13322485/how-to-get-the-primary-ip-address-of-the-local-machine-on-linux-and-os-x&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== hostname ===&lt;br /&gt;
&lt;br /&gt;
 # will need to be parsed&lt;br /&gt;
 hostname -I&lt;br /&gt;
&lt;br /&gt;
 # parsed&lt;br /&gt;
 hostname -I | cut -d&#039; &#039; -f1&lt;br /&gt;
&lt;br /&gt;
== Ways to Get IPv4 Public IP Address ==&lt;br /&gt;
&lt;br /&gt;
=== curl ===&lt;br /&gt;
&lt;br /&gt;
 curl ip.ixota.com&lt;br /&gt;
 curl ifconfig.me&lt;br /&gt;
 curl api.ipify.org&lt;br /&gt;
 curl icanhazip.com&lt;br /&gt;
&lt;br /&gt;
=== wget ===&lt;br /&gt;
&lt;br /&gt;
 wget -qO- ipecho.net/plain&lt;br /&gt;
&lt;br /&gt;
=== dig ===&lt;br /&gt;
&lt;br /&gt;
 dig +short myip.opendns.com @resolver1.opendns.com&lt;br /&gt;
&lt;br /&gt;
== Ways to Get IPv6 Public IP Address ==&lt;br /&gt;
&lt;br /&gt;
=== curl ===&lt;br /&gt;
&lt;br /&gt;
 curl https://i-p.show&lt;br /&gt;
&lt;br /&gt;
 curl https://ipv6.icanhazip.com&lt;br /&gt;
 curl http://ip6only.me/api/   # not as clean&lt;br /&gt;
&lt;br /&gt;
 curl -6 icanhazip.com&lt;br /&gt;
 curl -6 https://ifconfig.co&lt;br /&gt;
 curl -6 ip.sb&lt;br /&gt;
 curl -6 https://ipv6.icanhazip.com&lt;br /&gt;
 curl https://api64.ipify.org&lt;br /&gt;
&lt;br /&gt;
== keywords ==&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=Netplan&amp;diff=9832</id>
		<title>Netplan</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=Netplan&amp;diff=9832"/>
		<updated>2026-04-15T17:58:13Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: /* dhcp */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== config ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# /etc/netplan/01-netcfg.yaml&lt;br /&gt;
network:&lt;br /&gt;
  ethernets:&lt;br /&gt;
    ens18:&lt;br /&gt;
      dhcp4: true&lt;br /&gt;
  version: 2&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
-&lt;br /&gt;
&lt;br /&gt;
 sudo netplan apply&lt;br /&gt;
&lt;br /&gt;
Debug plan:&lt;br /&gt;
 sudo netplan --debug apply&lt;br /&gt;
   # note &amp;quot;apply --debug&amp;quot; does not work&lt;br /&gt;
&lt;br /&gt;
-&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# networkctl&lt;br /&gt;
IDX LINK  TYPE     OPERATIONAL SETUP&lt;br /&gt;
  1 lo    loopback carrier     unmanaged&lt;br /&gt;
  2 ens18 ether    routable    configured&lt;br /&gt;
&lt;br /&gt;
2 links listed.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
-&lt;br /&gt;
&lt;br /&gt;
Ubuntu to regen machine-id &amp;lt;ref&amp;gt;https://unix.stackexchange.com/questions/402999/is-it-ok-to-change-etc-machine-id&amp;lt;/ref&amp;gt;&lt;br /&gt;
 rm -f /etc/machine-id /var/lib/dbus/machine-id&lt;br /&gt;
 # dbus-uuidgen --ensure=/etc/machine-id&lt;br /&gt;
 dbus-uuidgen --ensure&lt;br /&gt;
 #cp /var/lib/dbus/machine-id /etc/machine-id&lt;br /&gt;
 systemd-machine-id-setup&lt;br /&gt;
 # verify:&lt;br /&gt;
 cat /etc/machine-id /var/lib/dbus/machine-id&lt;br /&gt;
 hostnamectl&lt;br /&gt;
&lt;br /&gt;
== examples ==&lt;br /&gt;
&lt;br /&gt;
 https://github.com/canonical/netplan/tree/main/examples&lt;br /&gt;
&lt;br /&gt;
== static ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
network:&lt;br /&gt;
  version: 2&lt;br /&gt;
  renderer: networkd&lt;br /&gt;
  ethernets:&lt;br /&gt;
    enp3s0:&lt;br /&gt;
      addresses:&lt;br /&gt;
        - 10.10.10.2/24&lt;br /&gt;
      nameservers:&lt;br /&gt;
        search: [mydomain, otherdomain]&lt;br /&gt;
        addresses: [10.10.10.1, 1.1.1.1]&lt;br /&gt;
      routes: &lt;br /&gt;
        - to: default&lt;br /&gt;
          via: 10.10.10.1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ref: https://github.com/canonical/netplan/blob/main/examples/static.yaml&lt;br /&gt;
&lt;br /&gt;
== dhcp ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
network:&lt;br /&gt;
  version: 2&lt;br /&gt;
  renderer: networkd&lt;br /&gt;
  ethernets:&lt;br /&gt;
    enp3s0:&lt;br /&gt;
      dhcp4: true&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ref: https://github.com/canonical/netplan/blob/main/examples/dhcp.yaml&lt;br /&gt;
&lt;br /&gt;
== Renderer ==&lt;br /&gt;
&lt;br /&gt;
Warning: If both systemd-networkd and NetworkManager are active on the same interface, conflicts may occur. The renderer setting ensures control is delegated correctly.&lt;br /&gt;
&lt;br /&gt;
=== networkd ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
network:&lt;br /&gt;
  version: 2&lt;br /&gt;
  renderer: networkd&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== NetworkManager ===&lt;br /&gt;
&lt;br /&gt;
This system is being managed by NetworkManager.&lt;br /&gt;
&lt;br /&gt;
Default:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Let NetworkManager manage all devices on this system&lt;br /&gt;
network:&lt;br /&gt;
  version: 2&lt;br /&gt;
  renderer: NetworkManager&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
More:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Let NetworkManager manage all devices on this system&lt;br /&gt;
network:&lt;br /&gt;
  version: 2&lt;br /&gt;
  renderer: NetworkManager&lt;br /&gt;
  ethernets:&lt;br /&gt;
    enp3s0:&lt;br /&gt;
      dhcp4: true&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Apply configuration:&lt;br /&gt;
 sudo netplan apply&lt;br /&gt;
&lt;br /&gt;
Verify backend:&lt;br /&gt;
 nmcli device status&lt;br /&gt;
&lt;br /&gt;
Warning: If both systemd-networkd and NetworkManager are active on the same interface, conflicts may occur. The renderer setting ensures control is delegated correctly.&lt;br /&gt;
&lt;br /&gt;
== keywords ==&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=GitHub/Workflow&amp;diff=9831</id>
		<title>GitHub/Workflow</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=GitHub/Workflow&amp;diff=9831"/>
		<updated>2026-04-14T20:57:07Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: /* Bash */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== GitHub Actions Workflow ==&lt;br /&gt;
&lt;br /&gt;
== Starter Workflows ==&lt;br /&gt;
&lt;br /&gt;
 Quickstart for GitHub Actions - GitHub Docs&lt;br /&gt;
 https://docs.github.com/en/actions/quickstart&lt;br /&gt;
&lt;br /&gt;
 actions/starter-workflows: Accelerating new GitHub Actions workflows&lt;br /&gt;
 https://github.com/actions/starter-workflows&lt;br /&gt;
&lt;br /&gt;
 GitHub Marketplace - Actions&lt;br /&gt;
 https://github.com/marketplace?category=&amp;amp;query=&amp;amp;type=actions&amp;amp;verification=&lt;br /&gt;
&lt;br /&gt;
== Manual Run ==&lt;br /&gt;
&lt;br /&gt;
manual.yaml:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
name: Manual Run&lt;br /&gt;
run-name: Test&lt;br /&gt;
on:&lt;br /&gt;
  workflow_dispatch:&lt;br /&gt;
    inputs:&lt;br /&gt;
      LABEL:&lt;br /&gt;
        required: true&lt;br /&gt;
        type: string&lt;br /&gt;
        description: label&lt;br /&gt;
&lt;br /&gt;
jobs:&lt;br /&gt;
  run:&lt;br /&gt;
    runs-on: ${{ inputs.LABEL }}&lt;br /&gt;
    steps:&lt;br /&gt;
      - run: hostname&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== workflow dispatch limits ==&lt;br /&gt;
&lt;br /&gt;
https://docs.github.com/en/actions/writing-workflows/choosing-when-your-workflow-runs/events-that-trigger-workflows#workflow_dispatch&lt;br /&gt;
&lt;br /&gt;
Limits:&lt;br /&gt;
* The maximum number of top-level properties for inputs is 10.&lt;br /&gt;
* The maximum payload for inputs is 65,535 characters.&lt;br /&gt;
&lt;br /&gt;
== Don&#039;t Immediately Fail on Non Zero Return Code ==&lt;br /&gt;
&lt;br /&gt;
 # exit on error temporarily&lt;br /&gt;
 set -e&lt;br /&gt;
&lt;br /&gt;
 # disable exitting on error temporarily&lt;br /&gt;
 set +e&lt;br /&gt;
&lt;br /&gt;
== Multiline GITHUB_OUTPUT ==&lt;br /&gt;
&lt;br /&gt;
=== Bash ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
- name: Set multiline output&lt;br /&gt;
  id: example_step&lt;br /&gt;
  run: |&lt;br /&gt;
    # 1. Define your multiline content&lt;br /&gt;
    CONTENT=$(printf &amp;quot;Line 1\nLine 2\nLine 3&amp;quot;)&lt;br /&gt;
    &lt;br /&gt;
    # 2. Append to GITHUB_OUTPUT using a delimiter&lt;br /&gt;
    echo &amp;quot;MY_OUTPUT&amp;lt;&amp;lt;EOF&amp;quot; &amp;gt;&amp;gt; &amp;quot;$GITHUB_OUTPUT&amp;quot;&lt;br /&gt;
    echo &amp;quot;$CONTENT&amp;quot; &amp;gt;&amp;gt; &amp;quot;$GITHUB_OUTPUT&amp;quot;&lt;br /&gt;
    echo &amp;quot;EOF&amp;quot; &amp;gt;&amp;gt; &amp;quot;$GITHUB_OUTPUT&amp;quot;&lt;br /&gt;
&lt;br /&gt;
- name: Use the output&lt;br /&gt;
  run: echo &amp;quot;${{ steps.example_step.outputs.MY_OUTPUT }}&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Python ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import os&lt;br /&gt;
&lt;br /&gt;
# The multiline content you want to save&lt;br /&gt;
multiline_string = &amp;quot;&amp;quot;&amp;quot;Line 1: Hello&lt;br /&gt;
Line 2: World&lt;br /&gt;
Line 3: From Python&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# Define a unique delimiter&lt;br /&gt;
delimiter = &amp;quot;EOF&amp;quot;&lt;br /&gt;
output_file = os.getenv(&#039;GITHUB_OUTPUT&#039;)&lt;br /&gt;
&lt;br /&gt;
with open(output_file, &amp;quot;a&amp;quot;) as f:&lt;br /&gt;
    f.write(f&amp;quot;my_output&amp;lt;&amp;lt;{delimiter}\n&amp;quot;)&lt;br /&gt;
    f.write(f&amp;quot;{multiline_string}\n&amp;quot;)&lt;br /&gt;
    f.write(f&amp;quot;{delimiter}\n&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the workflow:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
      - name: Some Automation&lt;br /&gt;
        id: some-automation&lt;br /&gt;
        run: |&lt;br /&gt;
            ...&lt;br /&gt;
        shell: python&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Change Run Name with Input ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
name: Nodecheck&lt;br /&gt;
run-name: Nodecheck for ${{ inputs.RUNNER_LABEL }}&lt;br /&gt;
on:&lt;br /&gt;
  workflow_dispatch:&lt;br /&gt;
    inputs:&lt;br /&gt;
      RUNNER_LABEL:&lt;br /&gt;
        description: Name of runner to target&lt;br /&gt;
        required: true&lt;br /&gt;
        type: string&lt;br /&gt;
  workflow_call:&lt;br /&gt;
    inputs:&lt;br /&gt;
      RUNNER_LABEL:&lt;br /&gt;
        required: true&lt;br /&gt;
        type: string&lt;br /&gt;
        description: Name of runner to target&lt;br /&gt;
&lt;br /&gt;
jobs:&lt;br /&gt;
  run:&lt;br /&gt;
    uses: some-org/some-repo/.github/workflows/nodecheck.yaml@latest&lt;br /&gt;
    with:&lt;br /&gt;
      RUNNER_LABEL: ${{ inputs.RUNNER_LABEL }}&lt;br /&gt;
    secrets: inherit&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== On Pull Request ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
name: On Pull Request&lt;br /&gt;
on:&lt;br /&gt;
  pull_request:&lt;br /&gt;
    types: [opened, reopened]&lt;br /&gt;
&lt;br /&gt;
jobs:&lt;br /&gt;
  test:&lt;br /&gt;
    runs-on: [ubuntu-latest]&lt;br /&gt;
    steps:&lt;br /&gt;
      - name: do something&lt;br /&gt;
        shell: bash&lt;br /&gt;
        run: |&lt;br /&gt;
          echo &amp;quot;hi&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== On Label Change ==&lt;br /&gt;
&lt;br /&gt;
Note: Must have event in &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
name: On Label&lt;br /&gt;
on:&lt;br /&gt;
  pull_request:&lt;br /&gt;
    types:&lt;br /&gt;
      - labeled&lt;br /&gt;
jobs:&lt;br /&gt;
  label-job:&lt;br /&gt;
    if: &amp;quot;github.event.label.name == &#039;run-mylabel&#039;&amp;quot;&lt;br /&gt;
    uses: myorg/myrepo/.github/workflows/dolabel.yaml@v2&lt;br /&gt;
    with:&lt;br /&gt;
      VAR1: VAR1&lt;br /&gt;
    secrets: inherit&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Basic Workflow ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
name: GitHub Actions Demo&lt;br /&gt;
run-name: ${{ github.actor }} is testing out GitHub Actions 🚀&lt;br /&gt;
on: [push]&lt;br /&gt;
jobs:&lt;br /&gt;
  Explore-GitHub-Actions:&lt;br /&gt;
    runs-on: ubuntu-latest&lt;br /&gt;
    steps:&lt;br /&gt;
      - run: echo &amp;quot;🎉 The job was automatically triggered by a ${{ github.event_name }} event.&amp;quot;&lt;br /&gt;
      - run: echo &amp;quot;🐧 This job is now running on a ${{ runner.os }} server hosted by GitHub!&amp;quot;&lt;br /&gt;
      - run: echo &amp;quot;🔎 The name of your branch is ${{ github.ref }} and your repository is ${{ github.repository }}.&amp;quot;&lt;br /&gt;
      - name: Check out repository code&lt;br /&gt;
        uses: actions/checkout@v3&lt;br /&gt;
      - run: echo &amp;quot;💡 The ${{ github.repository }} repository has been cloned to the runner.&amp;quot;&lt;br /&gt;
      - run: echo &amp;quot;🖥️ The workflow is now ready to test your code on the runner.&amp;quot;&lt;br /&gt;
      - name: List files in the repository&lt;br /&gt;
        run: |&lt;br /&gt;
          ls ${{ github.workspace }}&lt;br /&gt;
      - run: echo &amp;quot;🍏 This job&#039;s status is ${{ job.status }}.&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ref: https://docs.github.com/en/actions/quickstart&lt;br /&gt;
&lt;br /&gt;
== Using Job Output ==&lt;br /&gt;
&lt;br /&gt;
if you want to export the job output from the workflow:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
name: CI Precommit Automation Pipeline - Get Builds&lt;br /&gt;
on:&lt;br /&gt;
  workflow_call:&lt;br /&gt;
    inputs:&lt;br /&gt;
      ...&lt;br /&gt;
    outputs:&lt;br /&gt;
      output1: ${{ jobs.job1.outputs.output1 }}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
job outputs:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
jobs:&lt;br /&gt;
  job1:&lt;br /&gt;
    runs-on: ubuntu-latest&lt;br /&gt;
    # Map a step output to a job output&lt;br /&gt;
    outputs:&lt;br /&gt;
      output1: ${{ steps.step1.outputs.test }}&lt;br /&gt;
      output2: ${{ steps.step2.outputs.test }}&lt;br /&gt;
    steps:&lt;br /&gt;
      - id: step1&lt;br /&gt;
        run: echo &amp;quot;test=hello&amp;quot; &amp;gt;&amp;gt; &amp;quot;$GITHUB_OUTPUT&amp;quot;&lt;br /&gt;
      - id: step2&lt;br /&gt;
        run: echo &amp;quot;test=world&amp;quot; &amp;gt;&amp;gt; &amp;quot;$GITHUB_OUTPUT&amp;quot;&lt;br /&gt;
      - id: step3&lt;br /&gt;
        run: echo &amp;quot;I see step1: ${{ steps.step1.outputs.test }}&lt;br /&gt;
  job2:&lt;br /&gt;
    runs-on: ubuntu-latest&lt;br /&gt;
    needs: job1&lt;br /&gt;
    steps:&lt;br /&gt;
      - env:&lt;br /&gt;
          OUTPUT1: ${{needs.job1.outputs.output1}}&lt;br /&gt;
          OUTPUT2: ${{needs.job1.outputs.output2}}&lt;br /&gt;
        run: echo &amp;quot;$OUTPUT1 $OUTPUT2&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ref: Defining outputs for jobs - GitHub Enterprise Cloud Docs - https://docs.github.com/en/enterprise-cloud@latest/actions/using-jobs/defining-outputs-for-jobs&lt;br /&gt;
&lt;br /&gt;
Multi-line output: &amp;lt;ref&amp;gt;https://github.com/github/docs/issues/21529&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    run: |&lt;br /&gt;
      echo &#039;JSON_RESPONSE&amp;lt;&amp;lt;EOF&#039; &amp;gt;&amp;gt; $GITHUB_OUTPUT&lt;br /&gt;
      curl https://example.lab &amp;gt;&amp;gt; $GITHUB_OUTPUT&lt;br /&gt;
      echo &#039;EOF&#039; &amp;gt;&amp;gt; $GITHUB_OUTPUT&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Python version job output ===&lt;br /&gt;
&lt;br /&gt;
Python version: &amp;lt;ref&amp;gt;https://github.com/orgs/community/discussions/28146&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
with open(os.environ[&#039;GITHUB_OUTPUT&#039;], &#039;a&#039;) as fh:&lt;br /&gt;
  print(f&#039;{SOME}={THING}&#039;, file=fh)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Function version:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def set_output(name, value):&lt;br /&gt;
    with open(os.environ[&#039;GITHUB_OUTPUT&#039;], &#039;a&#039;) as fh:&lt;br /&gt;
        print(f&#039;{name}={value}&#039;, file=fh)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Multi lined version:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import uuid&lt;br /&gt;
&lt;br /&gt;
def set_multiline_output(name, value):&lt;br /&gt;
    with open(os.environ[&#039;GITHUB_OUTPUT&#039;], &#039;a&#039;) as fh:&lt;br /&gt;
        delimiter = uuid.uuid1()&lt;br /&gt;
        print(f&#039;{name}&amp;lt;&amp;lt;{delimiter}&#039;, file=fh)&lt;br /&gt;
        print(value, file=fh)&lt;br /&gt;
        print(delimiter, file=fh)&lt;br /&gt;
&lt;br /&gt;
# call example:&lt;br /&gt;
set_multiline_output(&amp;quot;value&amp;quot;, my_multiline_string)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Dynamic Runs-on ==&lt;br /&gt;
&lt;br /&gt;
Dynamic from Input:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
name: Dynamic Labels&lt;br /&gt;
run-name: Dynamic Labels&lt;br /&gt;
on:&lt;br /&gt;
  workflow_dispatch:&lt;br /&gt;
    inputs:&lt;br /&gt;
      LABELS:&lt;br /&gt;
        required: false&lt;br /&gt;
        type: string&lt;br /&gt;
        default: &amp;quot;[ \&amp;quot;CI\&amp;quot; ]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
jobs:&lt;br /&gt;
  run:&lt;br /&gt;
    # runs-on: ${{ fromJSON( &#039;[&amp;quot;CI&amp;quot;]&#039; ) }}  # This works&lt;br /&gt;
    # runs-on: ${{ fromJSON( &#039;[&amp;quot;CI&amp;quot;, &amp;quot;MORE&amp;quot;]&#039; ) }}  # This works&lt;br /&gt;
    runs-on: ${{ fromJSON( inputs.LABELS ) }}  # This works if formatted like: [&amp;quot;CI&amp;quot;, &amp;quot;MORE&amp;quot;]&lt;br /&gt;
    # runs-on: ${{ inputs.LABELS }}  # this works for single label&lt;br /&gt;
    # runs-on: [ CI, MORE ]  # this works&lt;br /&gt;
    steps:&lt;br /&gt;
      - run: hostname&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dynamic from script:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
name: Dynamic Script&lt;br /&gt;
run-name: Test&lt;br /&gt;
on:&lt;br /&gt;
  workflow_dispatch:&lt;br /&gt;
    inputs:&lt;br /&gt;
      Go:&lt;br /&gt;
        required: false&lt;br /&gt;
        type: string&lt;br /&gt;
&lt;br /&gt;
jobs:&lt;br /&gt;
  job1:&lt;br /&gt;
    runs-on: ubuntu-latest&lt;br /&gt;
    outputs:&lt;br /&gt;
      RUNS: ${{ steps.set-RUNS.outputs.RUNS }}&lt;br /&gt;
    steps:&lt;br /&gt;
    - id: set-RUNS&lt;br /&gt;
      run: echo &amp;quot;RUNS=[\&amp;quot;CI\&amp;quot;,\&amp;quot;MORE\&amp;quot;]&amp;quot; &amp;gt;&amp;gt; $GITHUB_OUTPUT&lt;br /&gt;
  job2:&lt;br /&gt;
    needs: job1&lt;br /&gt;
    runs-on: ${{fromJSON(needs.job1.outputs.RUNS)}}&lt;br /&gt;
    steps:&lt;br /&gt;
    - run: hostname&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ref:&lt;br /&gt;
* How to Dynamically assign the runs-on value in the github actions - Stack Overflow - https://stackoverflow.com/questions/73241812/how-to-dynamically-assign-the-runs-on-value-in-the-github-actions&lt;br /&gt;
* Github Actions: How use strategy/matrix with script - Stack Overflow - https://stackoverflow.com/questions/59977364/github-actions-how-use-strategy-matrix-with-script&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--- todo ---&lt;br /&gt;
&lt;br /&gt;
ideas:&lt;br /&gt;
 runs-on: ${{ fromJson(format(&#039;[{0}]&#039;, github.event.inputs.LABELS)) }}&lt;br /&gt;
&lt;br /&gt;
this will work if labels is a string of quoted labels: &amp;quot;a&amp;quot;,&amp;quot;b&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Sadness - if the actions expressions supported a &amp;quot;replace()&amp;quot; function, could have the comma replace with a &amp;quot;,&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Dynamic Jobs #1 ==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{ &amp;quot;include&amp;quot;: [&lt;br /&gt;
    {&amp;quot;runson&amp;quot;: [&amp;quot;CI&amp;quot;, &amp;quot;MORE&amp;quot;],&lt;br /&gt;
     &amp;quot;task&amp;quot;: &amp;quot;joe&amp;quot;},&lt;br /&gt;
    {&amp;quot;runson&amp;quot;: [&amp;quot;CI&amp;quot;, &amp;quot;LESS&amp;quot;],&lt;br /&gt;
     &amp;quot;task&amp;quot;: &amp;quot;bob&amp;quot;}&lt;br /&gt;
  ]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
name: Dynamic Jobs&lt;br /&gt;
run-name: Test&lt;br /&gt;
on:&lt;br /&gt;
  workflow_dispatch:&lt;br /&gt;
    inputs:&lt;br /&gt;
      Go:&lt;br /&gt;
        required: false&lt;br /&gt;
        type: string&lt;br /&gt;
&lt;br /&gt;
jobs:&lt;br /&gt;
  generate:&lt;br /&gt;
    runs-on: ubuntu-latest&lt;br /&gt;
    outputs:&lt;br /&gt;
      MATRIX: ${{ steps.set-MATRIX.outputs.MATRIX }}&lt;br /&gt;
    steps:&lt;br /&gt;
    - id: set-MATRIX&lt;br /&gt;
      run: echo &amp;quot;MATRIX={\&amp;quot;include\&amp;quot;:[{\&amp;quot;runson\&amp;quot;:[\&amp;quot;CI\&amp;quot;,\&amp;quot;MORE\&amp;quot;],\&amp;quot;task\&amp;quot;:\&amp;quot;joe\&amp;quot;},{\&amp;quot;runson\&amp;quot;:[\&amp;quot;CI\&amp;quot;,\&amp;quot;LESS\&amp;quot;],\&amp;quot;task\&amp;quot;:\&amp;quot;bob\&amp;quot;}]}&amp;quot; &amp;gt;&amp;gt; $GITHUB_OUTPUT&lt;br /&gt;
  jober:&lt;br /&gt;
    needs: generate&lt;br /&gt;
    runs-on: ${{ matrix.runson }}&lt;br /&gt;
    strategy:&lt;br /&gt;
      matrix: ${{fromJson(needs.generate.outputs.matrix)}}&lt;br /&gt;
    steps:&lt;br /&gt;
    - run: hostname&lt;br /&gt;
    - run: echo ${{ matrix.runson }}&lt;br /&gt;
    - run: echo ${{ matrix.task }}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will generate 2 sub jobs:&lt;br /&gt;
* jober (CI, MORE, joe)&lt;br /&gt;
** Requested labels: CI, MORE&lt;br /&gt;
* jober (CI, LESS, bob)&lt;br /&gt;
** Requested labels: CI, LESS&lt;br /&gt;
&lt;br /&gt;
== Dynamic Jobs #2 ==&lt;br /&gt;
&lt;br /&gt;
Matrix Multiplier --- THIS WILL TRY EVERY EVERY EVERY COMBINATION!!!&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
color  = [ &amp;quot;red&amp;quot;,   &amp;quot;blue&amp;quot;,  &amp;quot;yellow&amp;quot; ]&lt;br /&gt;
fruit  = [ &amp;quot;apple&amp;quot;, &amp;quot;berry&amp;quot;,  &amp;quot;banana&amp;quot; ]&lt;br /&gt;
runner = [ &amp;quot;CI&amp;quot;,    &amp;quot;CI&amp;quot;,      [&amp;quot;Linux&amp;quot;, &amp;quot;Automation&amp;quot;]   ]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
jobs will be generated in a matrix multipler like so:&lt;br /&gt;
* ci_red_apple_CI&lt;br /&gt;
** Requested labels: CI&lt;br /&gt;
* ci_red_app_CD&lt;br /&gt;
** Requested labels: CD&lt;br /&gt;
* ci_red_apple_Array&lt;br /&gt;
** Requested labels: Linux, Automation   (note: [&amp;quot;Linux, Automation&amp;quot;] output to the name as &amp;quot;Array&amp;quot;)&lt;br /&gt;
* ci_blue_apple_CI&lt;br /&gt;
* ci_blue_apple_CD&lt;br /&gt;
* ci_blue_apple_Array&lt;br /&gt;
* etc...&lt;br /&gt;
* etc...&lt;br /&gt;
* etc...&lt;br /&gt;
* etc...&lt;br /&gt;
* etc...&lt;br /&gt;
* etc...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
name: Dynamic Jobs&lt;br /&gt;
run-name: Test&lt;br /&gt;
on:&lt;br /&gt;
  workflow_dispatch:&lt;br /&gt;
    inputs:&lt;br /&gt;
      Go:&lt;br /&gt;
        required: false&lt;br /&gt;
        type: string&lt;br /&gt;
&lt;br /&gt;
jobs:&lt;br /&gt;
  generate:&lt;br /&gt;
    runs-on: ubuntu-latest&lt;br /&gt;
    outputs:&lt;br /&gt;
      color: ${{ steps.set-matrix.outputs.color }}&lt;br /&gt;
      fruit: ${{ steps.set-matrix.outputs.fruit }}&lt;br /&gt;
      runner: ${{ steps.set-matrix.outputs.runner }}&lt;br /&gt;
    steps:&lt;br /&gt;
    - id: set-matrix&lt;br /&gt;
      run: &amp;gt;&lt;br /&gt;
        echo &#039;color=[&amp;quot;red&amp;quot;, &amp;quot;berry&amp;quot;, &amp;quot;yellow&amp;quot;]&#039; &amp;gt;&amp;gt; $GITHUB_OUTPUT&lt;br /&gt;
        echo &#039;fruit=[&amp;quot;apple&amp;quot;, &amp;quot;blue&amp;quot;, &amp;quot;banana&amp;quot;]&#039; &amp;gt;&amp;gt; $GITHUB_OUTPUT&lt;br /&gt;
        echo &#039;runner=[&amp;quot;CI&amp;quot;, &amp;quot;CD&amp;quot;, [&amp;quot;Linux&amp;quot;, &amp;quot;Automation&amp;quot;] ]&#039; &amp;gt;&amp;gt; $GITHUB_OUTPUT&lt;br /&gt;
&lt;br /&gt;
  jober:&lt;br /&gt;
    name: ci_${{ matrix.color }}_${{ matrix.fruit }}_${{ matrix.runner }}&lt;br /&gt;
    needs: generate&lt;br /&gt;
    runs-on: ${{ matrix.runner }}&lt;br /&gt;
    strategy:&lt;br /&gt;
      matrix:&lt;br /&gt;
        color: ${{fromJson(needs.generate.outputs.color)}}&lt;br /&gt;
        fruit: ${{fromJson(needs.generate.outputs.fruit)}}&lt;br /&gt;
        runner: ${{fromJson(needs.generate.outputs.runner)}}&lt;br /&gt;
    steps:&lt;br /&gt;
    - run: &amp;gt;&lt;br /&gt;
        echo &amp;quot;FRUIT: ${{ matrix.fruit }}&amp;quot;&lt;br /&gt;
        echo &amp;quot;COLOR: ${{ matrix.color }}&amp;quot;&lt;br /&gt;
        echo &amp;quot;RUNNER: ${{ matrix.runner }}&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Dynamic Jobs #3 ==&lt;br /&gt;
&lt;br /&gt;
Seems like the perfect option&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
include:&lt;br /&gt;
[&lt;br /&gt;
 { &amp;quot;color&amp;quot;:&amp;quot;red&amp;quot;,    &amp;quot;fruit&amp;quot;:&amp;quot;apple&amp;quot;,  &amp;quot;runner&amp;quot;:&amp;quot;CI&amp;quot;                    },&lt;br /&gt;
 { &amp;quot;color&amp;quot;:&amp;quot;blue&amp;quot;,   &amp;quot;fruit&amp;quot;:&amp;quot;berry&amp;quot;,  &amp;quot;runner&amp;quot;:&amp;quot;CD&amp;quot;                    },&lt;br /&gt;
 { &amp;quot;color&amp;quot;:&amp;quot;yellow&amp;quot;, &amp;quot;fruit&amp;quot;:&amp;quot;banana&amp;quot;, &amp;quot;runner&amp;quot;:[&amp;quot;Linux&amp;quot;, &amp;quot;Automation&amp;quot;] }&lt;br /&gt;
]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
jobs will be generated in a matrix multipler like so:&lt;br /&gt;
* ci_red_apple_CI&lt;br /&gt;
** Requested labels: CI&lt;br /&gt;
* ci_blue_berry_CD&lt;br /&gt;
** Requested labels: CD&lt;br /&gt;
* ci_yellow_banana_Array&lt;br /&gt;
** Requested labels: Linux, Automation   (note: [&amp;quot;Linux, Automation&amp;quot;] output to the name as &amp;quot;Array&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
name: Dynamic Jobs&lt;br /&gt;
run-name: Test&lt;br /&gt;
on:&lt;br /&gt;
  workflow_dispatch:&lt;br /&gt;
    inputs:&lt;br /&gt;
      Go:&lt;br /&gt;
        required: false&lt;br /&gt;
        type: string&lt;br /&gt;
&lt;br /&gt;
jobs:&lt;br /&gt;
  # automation-matrix:&lt;br /&gt;
  generate:&lt;br /&gt;
    # name: automation-matrix&lt;br /&gt;
    # needs: [ some-requirements ]&lt;br /&gt;
    runs-on: ubuntu-latest&lt;br /&gt;
    outputs:&lt;br /&gt;
      matrixgen: ${{ steps.set-matrix.outputs.matrixgen }}&lt;br /&gt;
    steps:&lt;br /&gt;
    - id: set-matrix&lt;br /&gt;
      run: |&lt;br /&gt;
        tmp=$(mktemp)&lt;br /&gt;
        echo &amp;quot;[&amp;quot; &amp;gt; $tmp&lt;br /&gt;
        echo &#039;{&amp;quot;color&amp;quot;:&amp;quot;red&amp;quot;,&amp;quot;fruit&amp;quot;:&amp;quot;apple&amp;quot;,&amp;quot;runner&amp;quot;:&amp;quot;CI&amp;quot;},&#039; &amp;gt;&amp;gt; $tmp&lt;br /&gt;
        echo &#039;{&amp;quot;color&amp;quot;:&amp;quot;blue&amp;quot;,&amp;quot;fruit&amp;quot;:&amp;quot;berry&amp;quot;,&amp;quot;runner&amp;quot;:&amp;quot;CD&amp;quot;},&#039; &amp;gt;&amp;gt; $tmp&lt;br /&gt;
        echo &#039;{&amp;quot;color&amp;quot;:&amp;quot;yellow&amp;quot;,&amp;quot;fruit&amp;quot;:&amp;quot;banana&amp;quot;,&amp;quot;runner&amp;quot;:[&amp;quot;Linux&amp;quot;, &amp;quot;Automation&amp;quot;]}&#039; &amp;gt;&amp;gt; $tmp&lt;br /&gt;
        echo &amp;quot;]&amp;quot; &amp;gt;&amp;gt; $tmp&lt;br /&gt;
&lt;br /&gt;
        cat $tmp&lt;br /&gt;
        echo &amp;quot;matrixgen&amp;lt;&amp;lt;EOF&amp;quot; &amp;gt;&amp;gt; $GITHUB_OUTPUT&lt;br /&gt;
        cat $tmp &amp;gt;&amp;gt; $GITHUB_OUTPUT&lt;br /&gt;
        echo &amp;quot;EOF&amp;quot; &amp;gt;&amp;gt; $GITHUB_OUTPUT&lt;br /&gt;
        rm -f $tmp&lt;br /&gt;
&lt;br /&gt;
  automation:&lt;br /&gt;
    # name: ${{ matrix.name }}&lt;br /&gt;
    name: ci_${{ matrix.color }}_${{ matrix.fruit }}_${{ matrix.runner }}&lt;br /&gt;
    needs: generate&lt;br /&gt;
    runs-on: ${{ matrix.runner }}&lt;br /&gt;
    strategy:&lt;br /&gt;
      matrix:&lt;br /&gt;
        include: ${{ fromJson(needs.generate.outputs.matrixgen) }}&lt;br /&gt;
    steps:&lt;br /&gt;
    - run: |&lt;br /&gt;
        echo &amp;quot;FRUIT: ${{ matrix.fruit }}&amp;quot;&lt;br /&gt;
        echo &amp;quot;COLOR: ${{ matrix.color }}&amp;quot;&lt;br /&gt;
        echo &amp;quot;RUNNER: ${{ matrix.runner }}&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The file processor could also be done in-line, but generally it makes more sense to process a file.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    - id: set-matrix&lt;br /&gt;
      run: |&lt;br /&gt;
        echo &amp;quot;matrixgen&amp;lt;&amp;lt;EOF&amp;quot; &amp;gt;&amp;gt; $GITHUB_OUTPUT&lt;br /&gt;
        echo &amp;quot;[&amp;quot; &amp;gt;&amp;gt; $GITHUB_OUTPUT&lt;br /&gt;
        echo &#039;{&amp;quot;color&amp;quot;:&amp;quot;red&amp;quot;,&amp;quot;fruit&amp;quot;:&amp;quot;apple&amp;quot;,&amp;quot;runner&amp;quot;:&amp;quot;CI&amp;quot;},&#039; &amp;gt;&amp;gt; $GITHUB_OUTPUT&lt;br /&gt;
        echo &#039;{&amp;quot;color&amp;quot;:&amp;quot;blue&amp;quot;,&amp;quot;fruit&amp;quot;:&amp;quot;berry&amp;quot;,&amp;quot;runner&amp;quot;:&amp;quot;CD&amp;quot;},&#039; &amp;gt;&amp;gt; $GITHUB_OUTPUT&lt;br /&gt;
        echo &#039;{&amp;quot;color&amp;quot;:&amp;quot;yellow&amp;quot;,&amp;quot;fruit&amp;quot;:&amp;quot;banana&amp;quot;,&amp;quot;runner&amp;quot;:[&amp;quot;Linux&amp;quot;, &amp;quot;Automation&amp;quot;]}&#039; &amp;gt;&amp;gt; $GITHUB_OUTPUT&lt;br /&gt;
        echo &amp;quot;]&amp;quot; &amp;gt;&amp;gt; $GITHUB_OUTPUT&lt;br /&gt;
        echo &amp;quot;EOF&amp;quot; &amp;gt;&amp;gt; $GITHUB_OUTPUT&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Official Dynamic Job Examples ==&lt;br /&gt;
&lt;br /&gt;
Reference: https://docs.github.com/en/actions/learn-github-actions/expressions#example-returning-a-json-object&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
name: build&lt;br /&gt;
on: push&lt;br /&gt;
jobs:&lt;br /&gt;
  job1:&lt;br /&gt;
    runs-on: ubuntu-latest&lt;br /&gt;
    outputs:&lt;br /&gt;
      matrix: ${{ steps.set-matrix.outputs.matrix }}&lt;br /&gt;
    steps:&lt;br /&gt;
      - id: set-matrix&lt;br /&gt;
        run: echo &amp;quot;matrix={\&amp;quot;include\&amp;quot;:[{\&amp;quot;project\&amp;quot;:\&amp;quot;foo\&amp;quot;,\&amp;quot;config\&amp;quot;:\&amp;quot;Debug\&amp;quot;},{\&amp;quot;project\&amp;quot;:\&amp;quot;bar\&amp;quot;,\&amp;quot;config\&amp;quot;:\&amp;quot;Release\&amp;quot;}]}&amp;quot; &amp;gt;&amp;gt; $GITHUB_OUTPUT&lt;br /&gt;
  job2:&lt;br /&gt;
    needs: job1&lt;br /&gt;
    runs-on: ubuntu-latest&lt;br /&gt;
    strategy:&lt;br /&gt;
      matrix: ${{ fromJSON(needs.job1.outputs.matrix) }}&lt;br /&gt;
    steps:&lt;br /&gt;
      - run: echo &amp;quot;Matrix - Project ${{ matrix.project }}, Config ${{ matrix.config }}&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
jobs:&lt;br /&gt;
  example_matrix:&lt;br /&gt;
    strategy:&lt;br /&gt;
      matrix:&lt;br /&gt;
        os: [ubuntu-22.04, ubuntu-20.04]&lt;br /&gt;
        version: [10, 12, 14]&lt;br /&gt;
    runs-on: ${{ matrix.os }}&lt;br /&gt;
    steps:&lt;br /&gt;
      - uses: actions/setup-node@v4&lt;br /&gt;
        with:&lt;br /&gt;
          node-version: ${{ matrix.version }}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Remotely Trigger Workflow - repository_dispatch ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
on:&lt;br /&gt;
  repository_dispatch:&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
on:&lt;br /&gt;
  repository_dispatch:&lt;br /&gt;
    types: [some_event_type]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 curl -X POST https://api.github.com/repos/OWNER/REPO/dispatches -H &amp;quot;Authorization: Bearer ${GH_TOKEN}&amp;quot; -d &#039;{&amp;quot;event_type&amp;quot;:&amp;quot;some_event_type&amp;quot;}&#039;&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
 curl -X POST https://api.github.com/repos/ORG/REPO/dispatches -d &#039;{&amp;quot;event_type&amp;quot;:&amp;quot;some_event_type&amp;quot;}&#039;&lt;br /&gt;
  #  -d or --data, -X or --request&lt;br /&gt;
  #  -H &amp;quot;Accept: application/vnd.github.v3+json&amp;quot;&lt;br /&gt;
  #  -H &amp;quot;Accept: application/vnd.github+json&amp;quot;&lt;br /&gt;
  # You will most likely need to also pass along auth: (unless you are silly and on a publicly executable workflow?)&lt;br /&gt;
  # -H &amp;quot;Authorization: Bearer $GITHUB_TOKEN&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 curl -L \&lt;br /&gt;
  -X POST \&lt;br /&gt;
  -H &amp;quot;Accept: application/vnd.github+json&amp;quot; \&lt;br /&gt;
  -H &amp;quot;Authorization: Bearer &amp;lt;YOUR-TOKEN&amp;gt;&amp;quot; \&lt;br /&gt;
  -H &amp;quot;X-GitHub-Api-Version: 2022-11-28&amp;quot; \&lt;br /&gt;
  https://api.github.com/repos/OWNER/REPO/dispatches \&lt;br /&gt;
  -d &#039;{&amp;quot;event_type&amp;quot;:&amp;quot;on-demand-test&amp;quot;,&amp;quot;client_payload&amp;quot;:{&amp;quot;unit&amp;quot;:false,&amp;quot;integration&amp;quot;:true}}&#039;&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
 if you want to trigger from some other branch:&lt;br /&gt;
  {...,&#039;ref&#039;:&#039;other_branch_or_ref&#039;},...}&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
 repository_dispatch - Events that trigger workflows - GitHub Docs&lt;br /&gt;
 https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#repository_dispatch&lt;br /&gt;
&lt;br /&gt;
 repository_dispatch - Repositories - GitHub Docs&lt;br /&gt;
 https://docs.github.com/rest/repos/repos#create-a-repository-dispatch-event&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
If you pass this payload through, you can limit the workflow, and access it in the workflow:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;event_type&amp;quot;: &amp;quot;test_result&amp;quot;,&lt;br /&gt;
  &amp;quot;client_payload&amp;quot;: {&lt;br /&gt;
    &amp;quot;passed&amp;quot;: false,&lt;br /&gt;
    &amp;quot;message&amp;quot;: &amp;quot;Error: timeout&amp;quot;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
workflow:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
on:&lt;br /&gt;
  repository_dispatch:&lt;br /&gt;
    types: [test_result]&lt;br /&gt;
&lt;br /&gt;
jobs:&lt;br /&gt;
  run_if_failure:&lt;br /&gt;
    if: ${{ !github.event.client_payload.passed }}&lt;br /&gt;
    runs-on: ubuntu-latest&lt;br /&gt;
    steps:&lt;br /&gt;
      - env:&lt;br /&gt;
          MESSAGE: ${{ github.event.client_payload.message }}&lt;br /&gt;
        run: echo $MESSAGE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Job Timeout ==&lt;br /&gt;
&lt;br /&gt;
Workflow syntax - jobs - timeout-minutes https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idtimeout-minutes&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
my-job:&lt;br /&gt;
 runs-on:         ubuntu-latest&lt;br /&gt;
 timeout-minutes: 30&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 jobs.&amp;lt;job_id&amp;gt;.timeout-minutes&lt;br /&gt;
 The maximum number of minutes to let a job run before GitHub automatically cancels it. Default: 360&lt;br /&gt;
&lt;br /&gt;
If the timeout exceeds the job execution time limit for the runner, the job will be canceled when the execution time limit is met instead. For more information about job execution time limits, see &amp;quot;Usage limits, billing, and administration&amp;quot; for GitHub-hosted runners and &amp;quot;About self-hosted runners&amp;quot; for self-hosted runner usage limits.&lt;br /&gt;
&lt;br /&gt;
Usage Limits:&lt;br /&gt;
&lt;br /&gt;
There are some limits on GitHub Actions usage when using GitHub-hosted runners. These limits are subject to change. &amp;lt;ref&amp;gt;https://docs.github.com/en/actions/learn-github-actions/usage-limits-billing-and-administration#usage-limits&amp;lt;/ref&amp;gt;&lt;br /&gt;
* Job execution time - Each job in a workflow can run for up to 6 hours of execution time. If a job reaches this limit, the job is terminated and fails to complete.&lt;br /&gt;
&lt;br /&gt;
There are some limits on GitHub Actions usage when using self-hosted runners. These limits are subject to change. &amp;lt;ref&amp;gt;https://docs.github.com/en/actions/hosting-your-own-runners/managing-self-hosted-runners/about-self-hosted-runners#usage-limits&amp;lt;/ref&amp;gt;&lt;br /&gt;
* Job execution time - Each job in a workflow can run for up to 5 days of execution time. If a job reaches this limit, the job is terminated and fails to complete.&lt;br /&gt;
&lt;br /&gt;
=== Step Timeout ===&lt;br /&gt;
&lt;br /&gt;
 jobs.&amp;lt;job_id&amp;gt;.steps[*].timeout-minutes&lt;br /&gt;
 The maximum number of minutes to run the step before killing the process.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Status Check Functions ==&lt;br /&gt;
&lt;br /&gt;
 Expressions - GitHub Docs&lt;br /&gt;
 https://docs.github.com/en/actions/learn-github-actions/expressions#status-check-functions&lt;br /&gt;
&lt;br /&gt;
 How to run a github-actions step, even if the previous step fails, while still failing the job - Stack Overflow&lt;br /&gt;
 https://stackoverflow.com/questions/58858429/how-to-run-a-github-actions-step-even-if-the-previous-step-fails-while-still-f&lt;br /&gt;
&lt;br /&gt;
=== success ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
steps:&lt;br /&gt;
  ...&lt;br /&gt;
  - name: The job has succeeded&lt;br /&gt;
    if: ${{ success() }}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== failure ===&lt;br /&gt;
&lt;br /&gt;
Returns true when any previous step of a job fails.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
steps:&lt;br /&gt;
  ...&lt;br /&gt;
  - name: The job has failed&lt;br /&gt;
    if: ${{ failure() }}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
with step conclusion check:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
steps:&lt;br /&gt;
  ...&lt;br /&gt;
  - name: Failing step&lt;br /&gt;
    id: demo&lt;br /&gt;
    run: exit 1&lt;br /&gt;
  - name: The demo step has failed&lt;br /&gt;
    if: ${{ failure() &amp;amp;&amp;amp; steps.demo.conclusion == &#039;failure&#039; }}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== always ===&lt;br /&gt;
&lt;br /&gt;
Causes the step to always execute, and returns true, even when canceled. The always expression is best used at the step level or on tasks that you expect to run even when a job is canceled.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if: ${{ always() }}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 if: always()&lt;br /&gt;
&lt;br /&gt;
=== cancelled ===&lt;br /&gt;
&lt;br /&gt;
Returns true if the workflow was canceled.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if: ${{ cancelled() }}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Pass Status to Step ===&lt;br /&gt;
&lt;br /&gt;
Use:&lt;br /&gt;
 steps.&amp;lt;id&amp;gt;.outcome != &#039;success&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
- name: Check status step&lt;br /&gt;
  id: check-step&lt;br /&gt;
  if: success()&lt;br /&gt;
  shell: bash&lt;br /&gt;
  run: |&lt;br /&gt;
    echo &amp;quot;Workflow successful&amp;quot;&lt;br /&gt;
&lt;br /&gt;
- name: The step to call the action&lt;br /&gt;
   if: always()&lt;br /&gt;
   uses: ./path/to/action&lt;br /&gt;
   with:&lt;br /&gt;
    some-token: ${{ inputs.some-token }}&lt;br /&gt;
    some-value: ${{ inputs.some-value }}&lt;br /&gt;
    workflow-status: ${{ steps.check-step.outcome }}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ref: https://stackoverflow.com/questions/75987303/how-to-pass-success-or-failure-to-a-github-action-from-a-workflow&lt;br /&gt;
&lt;br /&gt;
== keywords ==&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=GitHub/GitHub_Actions_Workflow&amp;diff=9830</id>
		<title>GitHub/GitHub Actions Workflow</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=GitHub/GitHub_Actions_Workflow&amp;diff=9830"/>
		<updated>2026-04-14T20:56:00Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;See [[GitHub/Workflow]]&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=GitHub/GitHub_Actions_Workflow&amp;diff=9829</id>
		<title>GitHub/GitHub Actions Workflow</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=GitHub/GitHub_Actions_Workflow&amp;diff=9829"/>
		<updated>2026-04-14T20:55:53Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: Created page with &amp;quot;See GitHub/Workflow&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;See GitHub/Workflow&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=GitHub/Workflow&amp;diff=9828</id>
		<title>GitHub/Workflow</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=GitHub/Workflow&amp;diff=9828"/>
		<updated>2026-04-14T20:55:37Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: /* Starter Workflows */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== GitHub Actions Workflow ==&lt;br /&gt;
&lt;br /&gt;
== Starter Workflows ==&lt;br /&gt;
&lt;br /&gt;
 Quickstart for GitHub Actions - GitHub Docs&lt;br /&gt;
 https://docs.github.com/en/actions/quickstart&lt;br /&gt;
&lt;br /&gt;
 actions/starter-workflows: Accelerating new GitHub Actions workflows&lt;br /&gt;
 https://github.com/actions/starter-workflows&lt;br /&gt;
&lt;br /&gt;
 GitHub Marketplace - Actions&lt;br /&gt;
 https://github.com/marketplace?category=&amp;amp;query=&amp;amp;type=actions&amp;amp;verification=&lt;br /&gt;
&lt;br /&gt;
== Manual Run ==&lt;br /&gt;
&lt;br /&gt;
manual.yaml:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
name: Manual Run&lt;br /&gt;
run-name: Test&lt;br /&gt;
on:&lt;br /&gt;
  workflow_dispatch:&lt;br /&gt;
    inputs:&lt;br /&gt;
      LABEL:&lt;br /&gt;
        required: true&lt;br /&gt;
        type: string&lt;br /&gt;
        description: label&lt;br /&gt;
&lt;br /&gt;
jobs:&lt;br /&gt;
  run:&lt;br /&gt;
    runs-on: ${{ inputs.LABEL }}&lt;br /&gt;
    steps:&lt;br /&gt;
      - run: hostname&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== workflow dispatch limits ==&lt;br /&gt;
&lt;br /&gt;
https://docs.github.com/en/actions/writing-workflows/choosing-when-your-workflow-runs/events-that-trigger-workflows#workflow_dispatch&lt;br /&gt;
&lt;br /&gt;
Limits:&lt;br /&gt;
* The maximum number of top-level properties for inputs is 10.&lt;br /&gt;
* The maximum payload for inputs is 65,535 characters.&lt;br /&gt;
&lt;br /&gt;
== Don&#039;t Immediately Fail on Non Zero Return Code ==&lt;br /&gt;
&lt;br /&gt;
 # exit on error temporarily&lt;br /&gt;
 set -e&lt;br /&gt;
&lt;br /&gt;
 # disable exitting on error temporarily&lt;br /&gt;
 set +e&lt;br /&gt;
&lt;br /&gt;
== Multiline GITHUB_OUTPUT ==&lt;br /&gt;
&lt;br /&gt;
=== Bash ===&lt;br /&gt;
&lt;br /&gt;
=== Python ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import os&lt;br /&gt;
&lt;br /&gt;
# The multiline content you want to save&lt;br /&gt;
multiline_string = &amp;quot;&amp;quot;&amp;quot;Line 1: Hello&lt;br /&gt;
Line 2: World&lt;br /&gt;
Line 3: From Python&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# Define a unique delimiter&lt;br /&gt;
delimiter = &amp;quot;EOF&amp;quot;&lt;br /&gt;
output_file = os.getenv(&#039;GITHUB_OUTPUT&#039;)&lt;br /&gt;
&lt;br /&gt;
with open(output_file, &amp;quot;a&amp;quot;) as f:&lt;br /&gt;
    f.write(f&amp;quot;my_output&amp;lt;&amp;lt;{delimiter}\n&amp;quot;)&lt;br /&gt;
    f.write(f&amp;quot;{multiline_string}\n&amp;quot;)&lt;br /&gt;
    f.write(f&amp;quot;{delimiter}\n&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the workflow:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
      - name: Some Automation&lt;br /&gt;
        id: some-automation&lt;br /&gt;
        run: |&lt;br /&gt;
            ...&lt;br /&gt;
        shell: python&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Change Run Name with Input ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
name: Nodecheck&lt;br /&gt;
run-name: Nodecheck for ${{ inputs.RUNNER_LABEL }}&lt;br /&gt;
on:&lt;br /&gt;
  workflow_dispatch:&lt;br /&gt;
    inputs:&lt;br /&gt;
      RUNNER_LABEL:&lt;br /&gt;
        description: Name of runner to target&lt;br /&gt;
        required: true&lt;br /&gt;
        type: string&lt;br /&gt;
  workflow_call:&lt;br /&gt;
    inputs:&lt;br /&gt;
      RUNNER_LABEL:&lt;br /&gt;
        required: true&lt;br /&gt;
        type: string&lt;br /&gt;
        description: Name of runner to target&lt;br /&gt;
&lt;br /&gt;
jobs:&lt;br /&gt;
  run:&lt;br /&gt;
    uses: some-org/some-repo/.github/workflows/nodecheck.yaml@latest&lt;br /&gt;
    with:&lt;br /&gt;
      RUNNER_LABEL: ${{ inputs.RUNNER_LABEL }}&lt;br /&gt;
    secrets: inherit&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== On Pull Request ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
name: On Pull Request&lt;br /&gt;
on:&lt;br /&gt;
  pull_request:&lt;br /&gt;
    types: [opened, reopened]&lt;br /&gt;
&lt;br /&gt;
jobs:&lt;br /&gt;
  test:&lt;br /&gt;
    runs-on: [ubuntu-latest]&lt;br /&gt;
    steps:&lt;br /&gt;
      - name: do something&lt;br /&gt;
        shell: bash&lt;br /&gt;
        run: |&lt;br /&gt;
          echo &amp;quot;hi&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== On Label Change ==&lt;br /&gt;
&lt;br /&gt;
Note: Must have event in &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
name: On Label&lt;br /&gt;
on:&lt;br /&gt;
  pull_request:&lt;br /&gt;
    types:&lt;br /&gt;
      - labeled&lt;br /&gt;
jobs:&lt;br /&gt;
  label-job:&lt;br /&gt;
    if: &amp;quot;github.event.label.name == &#039;run-mylabel&#039;&amp;quot;&lt;br /&gt;
    uses: myorg/myrepo/.github/workflows/dolabel.yaml@v2&lt;br /&gt;
    with:&lt;br /&gt;
      VAR1: VAR1&lt;br /&gt;
    secrets: inherit&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Basic Workflow ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
name: GitHub Actions Demo&lt;br /&gt;
run-name: ${{ github.actor }} is testing out GitHub Actions 🚀&lt;br /&gt;
on: [push]&lt;br /&gt;
jobs:&lt;br /&gt;
  Explore-GitHub-Actions:&lt;br /&gt;
    runs-on: ubuntu-latest&lt;br /&gt;
    steps:&lt;br /&gt;
      - run: echo &amp;quot;🎉 The job was automatically triggered by a ${{ github.event_name }} event.&amp;quot;&lt;br /&gt;
      - run: echo &amp;quot;🐧 This job is now running on a ${{ runner.os }} server hosted by GitHub!&amp;quot;&lt;br /&gt;
      - run: echo &amp;quot;🔎 The name of your branch is ${{ github.ref }} and your repository is ${{ github.repository }}.&amp;quot;&lt;br /&gt;
      - name: Check out repository code&lt;br /&gt;
        uses: actions/checkout@v3&lt;br /&gt;
      - run: echo &amp;quot;💡 The ${{ github.repository }} repository has been cloned to the runner.&amp;quot;&lt;br /&gt;
      - run: echo &amp;quot;🖥️ The workflow is now ready to test your code on the runner.&amp;quot;&lt;br /&gt;
      - name: List files in the repository&lt;br /&gt;
        run: |&lt;br /&gt;
          ls ${{ github.workspace }}&lt;br /&gt;
      - run: echo &amp;quot;🍏 This job&#039;s status is ${{ job.status }}.&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ref: https://docs.github.com/en/actions/quickstart&lt;br /&gt;
&lt;br /&gt;
== Using Job Output ==&lt;br /&gt;
&lt;br /&gt;
if you want to export the job output from the workflow:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
name: CI Precommit Automation Pipeline - Get Builds&lt;br /&gt;
on:&lt;br /&gt;
  workflow_call:&lt;br /&gt;
    inputs:&lt;br /&gt;
      ...&lt;br /&gt;
    outputs:&lt;br /&gt;
      output1: ${{ jobs.job1.outputs.output1 }}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
job outputs:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
jobs:&lt;br /&gt;
  job1:&lt;br /&gt;
    runs-on: ubuntu-latest&lt;br /&gt;
    # Map a step output to a job output&lt;br /&gt;
    outputs:&lt;br /&gt;
      output1: ${{ steps.step1.outputs.test }}&lt;br /&gt;
      output2: ${{ steps.step2.outputs.test }}&lt;br /&gt;
    steps:&lt;br /&gt;
      - id: step1&lt;br /&gt;
        run: echo &amp;quot;test=hello&amp;quot; &amp;gt;&amp;gt; &amp;quot;$GITHUB_OUTPUT&amp;quot;&lt;br /&gt;
      - id: step2&lt;br /&gt;
        run: echo &amp;quot;test=world&amp;quot; &amp;gt;&amp;gt; &amp;quot;$GITHUB_OUTPUT&amp;quot;&lt;br /&gt;
      - id: step3&lt;br /&gt;
        run: echo &amp;quot;I see step1: ${{ steps.step1.outputs.test }}&lt;br /&gt;
  job2:&lt;br /&gt;
    runs-on: ubuntu-latest&lt;br /&gt;
    needs: job1&lt;br /&gt;
    steps:&lt;br /&gt;
      - env:&lt;br /&gt;
          OUTPUT1: ${{needs.job1.outputs.output1}}&lt;br /&gt;
          OUTPUT2: ${{needs.job1.outputs.output2}}&lt;br /&gt;
        run: echo &amp;quot;$OUTPUT1 $OUTPUT2&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ref: Defining outputs for jobs - GitHub Enterprise Cloud Docs - https://docs.github.com/en/enterprise-cloud@latest/actions/using-jobs/defining-outputs-for-jobs&lt;br /&gt;
&lt;br /&gt;
Multi-line output: &amp;lt;ref&amp;gt;https://github.com/github/docs/issues/21529&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    run: |&lt;br /&gt;
      echo &#039;JSON_RESPONSE&amp;lt;&amp;lt;EOF&#039; &amp;gt;&amp;gt; $GITHUB_OUTPUT&lt;br /&gt;
      curl https://example.lab &amp;gt;&amp;gt; $GITHUB_OUTPUT&lt;br /&gt;
      echo &#039;EOF&#039; &amp;gt;&amp;gt; $GITHUB_OUTPUT&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Python version job output ===&lt;br /&gt;
&lt;br /&gt;
Python version: &amp;lt;ref&amp;gt;https://github.com/orgs/community/discussions/28146&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
with open(os.environ[&#039;GITHUB_OUTPUT&#039;], &#039;a&#039;) as fh:&lt;br /&gt;
  print(f&#039;{SOME}={THING}&#039;, file=fh)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Function version:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def set_output(name, value):&lt;br /&gt;
    with open(os.environ[&#039;GITHUB_OUTPUT&#039;], &#039;a&#039;) as fh:&lt;br /&gt;
        print(f&#039;{name}={value}&#039;, file=fh)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Multi lined version:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import uuid&lt;br /&gt;
&lt;br /&gt;
def set_multiline_output(name, value):&lt;br /&gt;
    with open(os.environ[&#039;GITHUB_OUTPUT&#039;], &#039;a&#039;) as fh:&lt;br /&gt;
        delimiter = uuid.uuid1()&lt;br /&gt;
        print(f&#039;{name}&amp;lt;&amp;lt;{delimiter}&#039;, file=fh)&lt;br /&gt;
        print(value, file=fh)&lt;br /&gt;
        print(delimiter, file=fh)&lt;br /&gt;
&lt;br /&gt;
# call example:&lt;br /&gt;
set_multiline_output(&amp;quot;value&amp;quot;, my_multiline_string)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Dynamic Runs-on ==&lt;br /&gt;
&lt;br /&gt;
Dynamic from Input:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
name: Dynamic Labels&lt;br /&gt;
run-name: Dynamic Labels&lt;br /&gt;
on:&lt;br /&gt;
  workflow_dispatch:&lt;br /&gt;
    inputs:&lt;br /&gt;
      LABELS:&lt;br /&gt;
        required: false&lt;br /&gt;
        type: string&lt;br /&gt;
        default: &amp;quot;[ \&amp;quot;CI\&amp;quot; ]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
jobs:&lt;br /&gt;
  run:&lt;br /&gt;
    # runs-on: ${{ fromJSON( &#039;[&amp;quot;CI&amp;quot;]&#039; ) }}  # This works&lt;br /&gt;
    # runs-on: ${{ fromJSON( &#039;[&amp;quot;CI&amp;quot;, &amp;quot;MORE&amp;quot;]&#039; ) }}  # This works&lt;br /&gt;
    runs-on: ${{ fromJSON( inputs.LABELS ) }}  # This works if formatted like: [&amp;quot;CI&amp;quot;, &amp;quot;MORE&amp;quot;]&lt;br /&gt;
    # runs-on: ${{ inputs.LABELS }}  # this works for single label&lt;br /&gt;
    # runs-on: [ CI, MORE ]  # this works&lt;br /&gt;
    steps:&lt;br /&gt;
      - run: hostname&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dynamic from script:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
name: Dynamic Script&lt;br /&gt;
run-name: Test&lt;br /&gt;
on:&lt;br /&gt;
  workflow_dispatch:&lt;br /&gt;
    inputs:&lt;br /&gt;
      Go:&lt;br /&gt;
        required: false&lt;br /&gt;
        type: string&lt;br /&gt;
&lt;br /&gt;
jobs:&lt;br /&gt;
  job1:&lt;br /&gt;
    runs-on: ubuntu-latest&lt;br /&gt;
    outputs:&lt;br /&gt;
      RUNS: ${{ steps.set-RUNS.outputs.RUNS }}&lt;br /&gt;
    steps:&lt;br /&gt;
    - id: set-RUNS&lt;br /&gt;
      run: echo &amp;quot;RUNS=[\&amp;quot;CI\&amp;quot;,\&amp;quot;MORE\&amp;quot;]&amp;quot; &amp;gt;&amp;gt; $GITHUB_OUTPUT&lt;br /&gt;
  job2:&lt;br /&gt;
    needs: job1&lt;br /&gt;
    runs-on: ${{fromJSON(needs.job1.outputs.RUNS)}}&lt;br /&gt;
    steps:&lt;br /&gt;
    - run: hostname&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ref:&lt;br /&gt;
* How to Dynamically assign the runs-on value in the github actions - Stack Overflow - https://stackoverflow.com/questions/73241812/how-to-dynamically-assign-the-runs-on-value-in-the-github-actions&lt;br /&gt;
* Github Actions: How use strategy/matrix with script - Stack Overflow - https://stackoverflow.com/questions/59977364/github-actions-how-use-strategy-matrix-with-script&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--- todo ---&lt;br /&gt;
&lt;br /&gt;
ideas:&lt;br /&gt;
 runs-on: ${{ fromJson(format(&#039;[{0}]&#039;, github.event.inputs.LABELS)) }}&lt;br /&gt;
&lt;br /&gt;
this will work if labels is a string of quoted labels: &amp;quot;a&amp;quot;,&amp;quot;b&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Sadness - if the actions expressions supported a &amp;quot;replace()&amp;quot; function, could have the comma replace with a &amp;quot;,&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Dynamic Jobs #1 ==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{ &amp;quot;include&amp;quot;: [&lt;br /&gt;
    {&amp;quot;runson&amp;quot;: [&amp;quot;CI&amp;quot;, &amp;quot;MORE&amp;quot;],&lt;br /&gt;
     &amp;quot;task&amp;quot;: &amp;quot;joe&amp;quot;},&lt;br /&gt;
    {&amp;quot;runson&amp;quot;: [&amp;quot;CI&amp;quot;, &amp;quot;LESS&amp;quot;],&lt;br /&gt;
     &amp;quot;task&amp;quot;: &amp;quot;bob&amp;quot;}&lt;br /&gt;
  ]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
name: Dynamic Jobs&lt;br /&gt;
run-name: Test&lt;br /&gt;
on:&lt;br /&gt;
  workflow_dispatch:&lt;br /&gt;
    inputs:&lt;br /&gt;
      Go:&lt;br /&gt;
        required: false&lt;br /&gt;
        type: string&lt;br /&gt;
&lt;br /&gt;
jobs:&lt;br /&gt;
  generate:&lt;br /&gt;
    runs-on: ubuntu-latest&lt;br /&gt;
    outputs:&lt;br /&gt;
      MATRIX: ${{ steps.set-MATRIX.outputs.MATRIX }}&lt;br /&gt;
    steps:&lt;br /&gt;
    - id: set-MATRIX&lt;br /&gt;
      run: echo &amp;quot;MATRIX={\&amp;quot;include\&amp;quot;:[{\&amp;quot;runson\&amp;quot;:[\&amp;quot;CI\&amp;quot;,\&amp;quot;MORE\&amp;quot;],\&amp;quot;task\&amp;quot;:\&amp;quot;joe\&amp;quot;},{\&amp;quot;runson\&amp;quot;:[\&amp;quot;CI\&amp;quot;,\&amp;quot;LESS\&amp;quot;],\&amp;quot;task\&amp;quot;:\&amp;quot;bob\&amp;quot;}]}&amp;quot; &amp;gt;&amp;gt; $GITHUB_OUTPUT&lt;br /&gt;
  jober:&lt;br /&gt;
    needs: generate&lt;br /&gt;
    runs-on: ${{ matrix.runson }}&lt;br /&gt;
    strategy:&lt;br /&gt;
      matrix: ${{fromJson(needs.generate.outputs.matrix)}}&lt;br /&gt;
    steps:&lt;br /&gt;
    - run: hostname&lt;br /&gt;
    - run: echo ${{ matrix.runson }}&lt;br /&gt;
    - run: echo ${{ matrix.task }}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will generate 2 sub jobs:&lt;br /&gt;
* jober (CI, MORE, joe)&lt;br /&gt;
** Requested labels: CI, MORE&lt;br /&gt;
* jober (CI, LESS, bob)&lt;br /&gt;
** Requested labels: CI, LESS&lt;br /&gt;
&lt;br /&gt;
== Dynamic Jobs #2 ==&lt;br /&gt;
&lt;br /&gt;
Matrix Multiplier --- THIS WILL TRY EVERY EVERY EVERY COMBINATION!!!&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
color  = [ &amp;quot;red&amp;quot;,   &amp;quot;blue&amp;quot;,  &amp;quot;yellow&amp;quot; ]&lt;br /&gt;
fruit  = [ &amp;quot;apple&amp;quot;, &amp;quot;berry&amp;quot;,  &amp;quot;banana&amp;quot; ]&lt;br /&gt;
runner = [ &amp;quot;CI&amp;quot;,    &amp;quot;CI&amp;quot;,      [&amp;quot;Linux&amp;quot;, &amp;quot;Automation&amp;quot;]   ]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
jobs will be generated in a matrix multipler like so:&lt;br /&gt;
* ci_red_apple_CI&lt;br /&gt;
** Requested labels: CI&lt;br /&gt;
* ci_red_app_CD&lt;br /&gt;
** Requested labels: CD&lt;br /&gt;
* ci_red_apple_Array&lt;br /&gt;
** Requested labels: Linux, Automation   (note: [&amp;quot;Linux, Automation&amp;quot;] output to the name as &amp;quot;Array&amp;quot;)&lt;br /&gt;
* ci_blue_apple_CI&lt;br /&gt;
* ci_blue_apple_CD&lt;br /&gt;
* ci_blue_apple_Array&lt;br /&gt;
* etc...&lt;br /&gt;
* etc...&lt;br /&gt;
* etc...&lt;br /&gt;
* etc...&lt;br /&gt;
* etc...&lt;br /&gt;
* etc...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
name: Dynamic Jobs&lt;br /&gt;
run-name: Test&lt;br /&gt;
on:&lt;br /&gt;
  workflow_dispatch:&lt;br /&gt;
    inputs:&lt;br /&gt;
      Go:&lt;br /&gt;
        required: false&lt;br /&gt;
        type: string&lt;br /&gt;
&lt;br /&gt;
jobs:&lt;br /&gt;
  generate:&lt;br /&gt;
    runs-on: ubuntu-latest&lt;br /&gt;
    outputs:&lt;br /&gt;
      color: ${{ steps.set-matrix.outputs.color }}&lt;br /&gt;
      fruit: ${{ steps.set-matrix.outputs.fruit }}&lt;br /&gt;
      runner: ${{ steps.set-matrix.outputs.runner }}&lt;br /&gt;
    steps:&lt;br /&gt;
    - id: set-matrix&lt;br /&gt;
      run: &amp;gt;&lt;br /&gt;
        echo &#039;color=[&amp;quot;red&amp;quot;, &amp;quot;berry&amp;quot;, &amp;quot;yellow&amp;quot;]&#039; &amp;gt;&amp;gt; $GITHUB_OUTPUT&lt;br /&gt;
        echo &#039;fruit=[&amp;quot;apple&amp;quot;, &amp;quot;blue&amp;quot;, &amp;quot;banana&amp;quot;]&#039; &amp;gt;&amp;gt; $GITHUB_OUTPUT&lt;br /&gt;
        echo &#039;runner=[&amp;quot;CI&amp;quot;, &amp;quot;CD&amp;quot;, [&amp;quot;Linux&amp;quot;, &amp;quot;Automation&amp;quot;] ]&#039; &amp;gt;&amp;gt; $GITHUB_OUTPUT&lt;br /&gt;
&lt;br /&gt;
  jober:&lt;br /&gt;
    name: ci_${{ matrix.color }}_${{ matrix.fruit }}_${{ matrix.runner }}&lt;br /&gt;
    needs: generate&lt;br /&gt;
    runs-on: ${{ matrix.runner }}&lt;br /&gt;
    strategy:&lt;br /&gt;
      matrix:&lt;br /&gt;
        color: ${{fromJson(needs.generate.outputs.color)}}&lt;br /&gt;
        fruit: ${{fromJson(needs.generate.outputs.fruit)}}&lt;br /&gt;
        runner: ${{fromJson(needs.generate.outputs.runner)}}&lt;br /&gt;
    steps:&lt;br /&gt;
    - run: &amp;gt;&lt;br /&gt;
        echo &amp;quot;FRUIT: ${{ matrix.fruit }}&amp;quot;&lt;br /&gt;
        echo &amp;quot;COLOR: ${{ matrix.color }}&amp;quot;&lt;br /&gt;
        echo &amp;quot;RUNNER: ${{ matrix.runner }}&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Dynamic Jobs #3 ==&lt;br /&gt;
&lt;br /&gt;
Seems like the perfect option&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
include:&lt;br /&gt;
[&lt;br /&gt;
 { &amp;quot;color&amp;quot;:&amp;quot;red&amp;quot;,    &amp;quot;fruit&amp;quot;:&amp;quot;apple&amp;quot;,  &amp;quot;runner&amp;quot;:&amp;quot;CI&amp;quot;                    },&lt;br /&gt;
 { &amp;quot;color&amp;quot;:&amp;quot;blue&amp;quot;,   &amp;quot;fruit&amp;quot;:&amp;quot;berry&amp;quot;,  &amp;quot;runner&amp;quot;:&amp;quot;CD&amp;quot;                    },&lt;br /&gt;
 { &amp;quot;color&amp;quot;:&amp;quot;yellow&amp;quot;, &amp;quot;fruit&amp;quot;:&amp;quot;banana&amp;quot;, &amp;quot;runner&amp;quot;:[&amp;quot;Linux&amp;quot;, &amp;quot;Automation&amp;quot;] }&lt;br /&gt;
]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
jobs will be generated in a matrix multipler like so:&lt;br /&gt;
* ci_red_apple_CI&lt;br /&gt;
** Requested labels: CI&lt;br /&gt;
* ci_blue_berry_CD&lt;br /&gt;
** Requested labels: CD&lt;br /&gt;
* ci_yellow_banana_Array&lt;br /&gt;
** Requested labels: Linux, Automation   (note: [&amp;quot;Linux, Automation&amp;quot;] output to the name as &amp;quot;Array&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
name: Dynamic Jobs&lt;br /&gt;
run-name: Test&lt;br /&gt;
on:&lt;br /&gt;
  workflow_dispatch:&lt;br /&gt;
    inputs:&lt;br /&gt;
      Go:&lt;br /&gt;
        required: false&lt;br /&gt;
        type: string&lt;br /&gt;
&lt;br /&gt;
jobs:&lt;br /&gt;
  # automation-matrix:&lt;br /&gt;
  generate:&lt;br /&gt;
    # name: automation-matrix&lt;br /&gt;
    # needs: [ some-requirements ]&lt;br /&gt;
    runs-on: ubuntu-latest&lt;br /&gt;
    outputs:&lt;br /&gt;
      matrixgen: ${{ steps.set-matrix.outputs.matrixgen }}&lt;br /&gt;
    steps:&lt;br /&gt;
    - id: set-matrix&lt;br /&gt;
      run: |&lt;br /&gt;
        tmp=$(mktemp)&lt;br /&gt;
        echo &amp;quot;[&amp;quot; &amp;gt; $tmp&lt;br /&gt;
        echo &#039;{&amp;quot;color&amp;quot;:&amp;quot;red&amp;quot;,&amp;quot;fruit&amp;quot;:&amp;quot;apple&amp;quot;,&amp;quot;runner&amp;quot;:&amp;quot;CI&amp;quot;},&#039; &amp;gt;&amp;gt; $tmp&lt;br /&gt;
        echo &#039;{&amp;quot;color&amp;quot;:&amp;quot;blue&amp;quot;,&amp;quot;fruit&amp;quot;:&amp;quot;berry&amp;quot;,&amp;quot;runner&amp;quot;:&amp;quot;CD&amp;quot;},&#039; &amp;gt;&amp;gt; $tmp&lt;br /&gt;
        echo &#039;{&amp;quot;color&amp;quot;:&amp;quot;yellow&amp;quot;,&amp;quot;fruit&amp;quot;:&amp;quot;banana&amp;quot;,&amp;quot;runner&amp;quot;:[&amp;quot;Linux&amp;quot;, &amp;quot;Automation&amp;quot;]}&#039; &amp;gt;&amp;gt; $tmp&lt;br /&gt;
        echo &amp;quot;]&amp;quot; &amp;gt;&amp;gt; $tmp&lt;br /&gt;
&lt;br /&gt;
        cat $tmp&lt;br /&gt;
        echo &amp;quot;matrixgen&amp;lt;&amp;lt;EOF&amp;quot; &amp;gt;&amp;gt; $GITHUB_OUTPUT&lt;br /&gt;
        cat $tmp &amp;gt;&amp;gt; $GITHUB_OUTPUT&lt;br /&gt;
        echo &amp;quot;EOF&amp;quot; &amp;gt;&amp;gt; $GITHUB_OUTPUT&lt;br /&gt;
        rm -f $tmp&lt;br /&gt;
&lt;br /&gt;
  automation:&lt;br /&gt;
    # name: ${{ matrix.name }}&lt;br /&gt;
    name: ci_${{ matrix.color }}_${{ matrix.fruit }}_${{ matrix.runner }}&lt;br /&gt;
    needs: generate&lt;br /&gt;
    runs-on: ${{ matrix.runner }}&lt;br /&gt;
    strategy:&lt;br /&gt;
      matrix:&lt;br /&gt;
        include: ${{ fromJson(needs.generate.outputs.matrixgen) }}&lt;br /&gt;
    steps:&lt;br /&gt;
    - run: |&lt;br /&gt;
        echo &amp;quot;FRUIT: ${{ matrix.fruit }}&amp;quot;&lt;br /&gt;
        echo &amp;quot;COLOR: ${{ matrix.color }}&amp;quot;&lt;br /&gt;
        echo &amp;quot;RUNNER: ${{ matrix.runner }}&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The file processor could also be done in-line, but generally it makes more sense to process a file.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    - id: set-matrix&lt;br /&gt;
      run: |&lt;br /&gt;
        echo &amp;quot;matrixgen&amp;lt;&amp;lt;EOF&amp;quot; &amp;gt;&amp;gt; $GITHUB_OUTPUT&lt;br /&gt;
        echo &amp;quot;[&amp;quot; &amp;gt;&amp;gt; $GITHUB_OUTPUT&lt;br /&gt;
        echo &#039;{&amp;quot;color&amp;quot;:&amp;quot;red&amp;quot;,&amp;quot;fruit&amp;quot;:&amp;quot;apple&amp;quot;,&amp;quot;runner&amp;quot;:&amp;quot;CI&amp;quot;},&#039; &amp;gt;&amp;gt; $GITHUB_OUTPUT&lt;br /&gt;
        echo &#039;{&amp;quot;color&amp;quot;:&amp;quot;blue&amp;quot;,&amp;quot;fruit&amp;quot;:&amp;quot;berry&amp;quot;,&amp;quot;runner&amp;quot;:&amp;quot;CD&amp;quot;},&#039; &amp;gt;&amp;gt; $GITHUB_OUTPUT&lt;br /&gt;
        echo &#039;{&amp;quot;color&amp;quot;:&amp;quot;yellow&amp;quot;,&amp;quot;fruit&amp;quot;:&amp;quot;banana&amp;quot;,&amp;quot;runner&amp;quot;:[&amp;quot;Linux&amp;quot;, &amp;quot;Automation&amp;quot;]}&#039; &amp;gt;&amp;gt; $GITHUB_OUTPUT&lt;br /&gt;
        echo &amp;quot;]&amp;quot; &amp;gt;&amp;gt; $GITHUB_OUTPUT&lt;br /&gt;
        echo &amp;quot;EOF&amp;quot; &amp;gt;&amp;gt; $GITHUB_OUTPUT&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Official Dynamic Job Examples ==&lt;br /&gt;
&lt;br /&gt;
Reference: https://docs.github.com/en/actions/learn-github-actions/expressions#example-returning-a-json-object&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
name: build&lt;br /&gt;
on: push&lt;br /&gt;
jobs:&lt;br /&gt;
  job1:&lt;br /&gt;
    runs-on: ubuntu-latest&lt;br /&gt;
    outputs:&lt;br /&gt;
      matrix: ${{ steps.set-matrix.outputs.matrix }}&lt;br /&gt;
    steps:&lt;br /&gt;
      - id: set-matrix&lt;br /&gt;
        run: echo &amp;quot;matrix={\&amp;quot;include\&amp;quot;:[{\&amp;quot;project\&amp;quot;:\&amp;quot;foo\&amp;quot;,\&amp;quot;config\&amp;quot;:\&amp;quot;Debug\&amp;quot;},{\&amp;quot;project\&amp;quot;:\&amp;quot;bar\&amp;quot;,\&amp;quot;config\&amp;quot;:\&amp;quot;Release\&amp;quot;}]}&amp;quot; &amp;gt;&amp;gt; $GITHUB_OUTPUT&lt;br /&gt;
  job2:&lt;br /&gt;
    needs: job1&lt;br /&gt;
    runs-on: ubuntu-latest&lt;br /&gt;
    strategy:&lt;br /&gt;
      matrix: ${{ fromJSON(needs.job1.outputs.matrix) }}&lt;br /&gt;
    steps:&lt;br /&gt;
      - run: echo &amp;quot;Matrix - Project ${{ matrix.project }}, Config ${{ matrix.config }}&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
jobs:&lt;br /&gt;
  example_matrix:&lt;br /&gt;
    strategy:&lt;br /&gt;
      matrix:&lt;br /&gt;
        os: [ubuntu-22.04, ubuntu-20.04]&lt;br /&gt;
        version: [10, 12, 14]&lt;br /&gt;
    runs-on: ${{ matrix.os }}&lt;br /&gt;
    steps:&lt;br /&gt;
      - uses: actions/setup-node@v4&lt;br /&gt;
        with:&lt;br /&gt;
          node-version: ${{ matrix.version }}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Remotely Trigger Workflow - repository_dispatch ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
on:&lt;br /&gt;
  repository_dispatch:&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
on:&lt;br /&gt;
  repository_dispatch:&lt;br /&gt;
    types: [some_event_type]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 curl -X POST https://api.github.com/repos/OWNER/REPO/dispatches -H &amp;quot;Authorization: Bearer ${GH_TOKEN}&amp;quot; -d &#039;{&amp;quot;event_type&amp;quot;:&amp;quot;some_event_type&amp;quot;}&#039;&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
 curl -X POST https://api.github.com/repos/ORG/REPO/dispatches -d &#039;{&amp;quot;event_type&amp;quot;:&amp;quot;some_event_type&amp;quot;}&#039;&lt;br /&gt;
  #  -d or --data, -X or --request&lt;br /&gt;
  #  -H &amp;quot;Accept: application/vnd.github.v3+json&amp;quot;&lt;br /&gt;
  #  -H &amp;quot;Accept: application/vnd.github+json&amp;quot;&lt;br /&gt;
  # You will most likely need to also pass along auth: (unless you are silly and on a publicly executable workflow?)&lt;br /&gt;
  # -H &amp;quot;Authorization: Bearer $GITHUB_TOKEN&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 curl -L \&lt;br /&gt;
  -X POST \&lt;br /&gt;
  -H &amp;quot;Accept: application/vnd.github+json&amp;quot; \&lt;br /&gt;
  -H &amp;quot;Authorization: Bearer &amp;lt;YOUR-TOKEN&amp;gt;&amp;quot; \&lt;br /&gt;
  -H &amp;quot;X-GitHub-Api-Version: 2022-11-28&amp;quot; \&lt;br /&gt;
  https://api.github.com/repos/OWNER/REPO/dispatches \&lt;br /&gt;
  -d &#039;{&amp;quot;event_type&amp;quot;:&amp;quot;on-demand-test&amp;quot;,&amp;quot;client_payload&amp;quot;:{&amp;quot;unit&amp;quot;:false,&amp;quot;integration&amp;quot;:true}}&#039;&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
 if you want to trigger from some other branch:&lt;br /&gt;
  {...,&#039;ref&#039;:&#039;other_branch_or_ref&#039;},...}&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
 repository_dispatch - Events that trigger workflows - GitHub Docs&lt;br /&gt;
 https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#repository_dispatch&lt;br /&gt;
&lt;br /&gt;
 repository_dispatch - Repositories - GitHub Docs&lt;br /&gt;
 https://docs.github.com/rest/repos/repos#create-a-repository-dispatch-event&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
If you pass this payload through, you can limit the workflow, and access it in the workflow:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;event_type&amp;quot;: &amp;quot;test_result&amp;quot;,&lt;br /&gt;
  &amp;quot;client_payload&amp;quot;: {&lt;br /&gt;
    &amp;quot;passed&amp;quot;: false,&lt;br /&gt;
    &amp;quot;message&amp;quot;: &amp;quot;Error: timeout&amp;quot;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
workflow:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
on:&lt;br /&gt;
  repository_dispatch:&lt;br /&gt;
    types: [test_result]&lt;br /&gt;
&lt;br /&gt;
jobs:&lt;br /&gt;
  run_if_failure:&lt;br /&gt;
    if: ${{ !github.event.client_payload.passed }}&lt;br /&gt;
    runs-on: ubuntu-latest&lt;br /&gt;
    steps:&lt;br /&gt;
      - env:&lt;br /&gt;
          MESSAGE: ${{ github.event.client_payload.message }}&lt;br /&gt;
        run: echo $MESSAGE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Job Timeout ==&lt;br /&gt;
&lt;br /&gt;
Workflow syntax - jobs - timeout-minutes https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idtimeout-minutes&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
my-job:&lt;br /&gt;
 runs-on:         ubuntu-latest&lt;br /&gt;
 timeout-minutes: 30&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 jobs.&amp;lt;job_id&amp;gt;.timeout-minutes&lt;br /&gt;
 The maximum number of minutes to let a job run before GitHub automatically cancels it. Default: 360&lt;br /&gt;
&lt;br /&gt;
If the timeout exceeds the job execution time limit for the runner, the job will be canceled when the execution time limit is met instead. For more information about job execution time limits, see &amp;quot;Usage limits, billing, and administration&amp;quot; for GitHub-hosted runners and &amp;quot;About self-hosted runners&amp;quot; for self-hosted runner usage limits.&lt;br /&gt;
&lt;br /&gt;
Usage Limits:&lt;br /&gt;
&lt;br /&gt;
There are some limits on GitHub Actions usage when using GitHub-hosted runners. These limits are subject to change. &amp;lt;ref&amp;gt;https://docs.github.com/en/actions/learn-github-actions/usage-limits-billing-and-administration#usage-limits&amp;lt;/ref&amp;gt;&lt;br /&gt;
* Job execution time - Each job in a workflow can run for up to 6 hours of execution time. If a job reaches this limit, the job is terminated and fails to complete.&lt;br /&gt;
&lt;br /&gt;
There are some limits on GitHub Actions usage when using self-hosted runners. These limits are subject to change. &amp;lt;ref&amp;gt;https://docs.github.com/en/actions/hosting-your-own-runners/managing-self-hosted-runners/about-self-hosted-runners#usage-limits&amp;lt;/ref&amp;gt;&lt;br /&gt;
* Job execution time - Each job in a workflow can run for up to 5 days of execution time. If a job reaches this limit, the job is terminated and fails to complete.&lt;br /&gt;
&lt;br /&gt;
=== Step Timeout ===&lt;br /&gt;
&lt;br /&gt;
 jobs.&amp;lt;job_id&amp;gt;.steps[*].timeout-minutes&lt;br /&gt;
 The maximum number of minutes to run the step before killing the process.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Status Check Functions ==&lt;br /&gt;
&lt;br /&gt;
 Expressions - GitHub Docs&lt;br /&gt;
 https://docs.github.com/en/actions/learn-github-actions/expressions#status-check-functions&lt;br /&gt;
&lt;br /&gt;
 How to run a github-actions step, even if the previous step fails, while still failing the job - Stack Overflow&lt;br /&gt;
 https://stackoverflow.com/questions/58858429/how-to-run-a-github-actions-step-even-if-the-previous-step-fails-while-still-f&lt;br /&gt;
&lt;br /&gt;
=== success ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
steps:&lt;br /&gt;
  ...&lt;br /&gt;
  - name: The job has succeeded&lt;br /&gt;
    if: ${{ success() }}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== failure ===&lt;br /&gt;
&lt;br /&gt;
Returns true when any previous step of a job fails.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
steps:&lt;br /&gt;
  ...&lt;br /&gt;
  - name: The job has failed&lt;br /&gt;
    if: ${{ failure() }}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
with step conclusion check:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
steps:&lt;br /&gt;
  ...&lt;br /&gt;
  - name: Failing step&lt;br /&gt;
    id: demo&lt;br /&gt;
    run: exit 1&lt;br /&gt;
  - name: The demo step has failed&lt;br /&gt;
    if: ${{ failure() &amp;amp;&amp;amp; steps.demo.conclusion == &#039;failure&#039; }}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== always ===&lt;br /&gt;
&lt;br /&gt;
Causes the step to always execute, and returns true, even when canceled. The always expression is best used at the step level or on tasks that you expect to run even when a job is canceled.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if: ${{ always() }}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 if: always()&lt;br /&gt;
&lt;br /&gt;
=== cancelled ===&lt;br /&gt;
&lt;br /&gt;
Returns true if the workflow was canceled.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if: ${{ cancelled() }}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Pass Status to Step ===&lt;br /&gt;
&lt;br /&gt;
Use:&lt;br /&gt;
 steps.&amp;lt;id&amp;gt;.outcome != &#039;success&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
- name: Check status step&lt;br /&gt;
  id: check-step&lt;br /&gt;
  if: success()&lt;br /&gt;
  shell: bash&lt;br /&gt;
  run: |&lt;br /&gt;
    echo &amp;quot;Workflow successful&amp;quot;&lt;br /&gt;
&lt;br /&gt;
- name: The step to call the action&lt;br /&gt;
   if: always()&lt;br /&gt;
   uses: ./path/to/action&lt;br /&gt;
   with:&lt;br /&gt;
    some-token: ${{ inputs.some-token }}&lt;br /&gt;
    some-value: ${{ inputs.some-value }}&lt;br /&gt;
    workflow-status: ${{ steps.check-step.outcome }}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ref: https://stackoverflow.com/questions/75987303/how-to-pass-success-or-failure-to-a-github-action-from-a-workflow&lt;br /&gt;
&lt;br /&gt;
== keywords ==&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
</feed>