Python: Difference between revisions

From indicium
Jump to navigation Jump to search
Stefan (talk | contribs)
No edit summary
 
(One intermediate revision by one other user not shown)
Line 3: Line 3:
http://www.tutorialspoint.com/python/python_multithreading.htm
http://www.tutorialspoint.com/python/python_multithreading.htm


Note however that threading in python is limited due to the GIL. To achieve "true" threading, use the "multiprocess" library (which in fact spawns different processes and uses IPC mechanism for communication etc):
Note however that threading in python is limited due to the GIL. To achieve "true" threading, use the "[https://docs.python.org/2/library/multiprocessing.html multiprocess]" library (which in fact spawns different processes and uses IPC mechanism for communication etc): https://www.quantstart.com/articles/Parallelising-Python-with-Threading-and-Multiprocessing


https://www.quantstart.com/articles/Parallelising-Python-with-Threading-and-Multiprocessing
== Debugging ==
 
Python can be debugged using rpdb2: https://pypi.org/project/rpdb2/
 
Since it is not distributed with any major distributions, you have to install it using pip, preferably in a virtual environment:
 
mkdir ~/pyenv
mkdir ~/pyenv/rpdb2
python -m venv pyenv/rpdb2/
~/pyenv/rpdb2/bin/pip install rpdb2
 
Now you need to hook into rpdb2 from the python program that you want to debug. Add this line to the python code:
 
import rpdb2; rpdb2.start_embedded_debugger("pass")
 
The string "pass" is the password to connect from the debugger. Now start your application (using the same virtual environment so that you can access the rpdb2 library):
 
~/pyenv/rpdb2/bin/python <yourapplication.py>
 
It will halt at startup and wait for debugger to connect. In another terminal, launch the debugger:
 
  ~/pyenv/rpdb2/bin/python -m rpdb2
 
Now issue the following commands to attach to your process and run it:
 
password pass
attach
go
 
Now you can issue command "help" to get more info. Commands such as "thread" and "stack" might be helpful.


== Tkinter and simple GUI programming ==
== Tkinter and simple GUI programming ==

Latest revision as of 09:30, 14 October 2024

Threading

http://www.tutorialspoint.com/python/python_multithreading.htm

Note however that threading in python is limited due to the GIL. To achieve "true" threading, use the "multiprocess" library (which in fact spawns different processes and uses IPC mechanism for communication etc): https://www.quantstart.com/articles/Parallelising-Python-with-Threading-and-Multiprocessing

Debugging

Python can be debugged using rpdb2: https://pypi.org/project/rpdb2/

Since it is not distributed with any major distributions, you have to install it using pip, preferably in a virtual environment:

mkdir ~/pyenv
mkdir ~/pyenv/rpdb2
python -m venv pyenv/rpdb2/
~/pyenv/rpdb2/bin/pip install rpdb2

Now you need to hook into rpdb2 from the python program that you want to debug. Add this line to the python code:

import rpdb2; rpdb2.start_embedded_debugger("pass")

The string "pass" is the password to connect from the debugger. Now start your application (using the same virtual environment so that you can access the rpdb2 library):

~/pyenv/rpdb2/bin/python <yourapplication.py>

It will halt at startup and wait for debugger to connect. In another terminal, launch the debugger:

 ~/pyenv/rpdb2/bin/python -m rpdb2

Now issue the following commands to attach to your process and run it:

password pass
attach
go

Now you can issue command "help" to get more info. Commands such as "thread" and "stack" might be helpful.

Tkinter and simple GUI programming

#!/usr/bin/env python

from Tkinter import *

def drawframe():
	c.delete("all")
	c.create_rectangle(0, 0, 150, 75 + c.steffe_i, fill="blue")
	c.steffe_i += 1
	root.after(10, drawframe)

def mouseclick(event):
	print "Mouse click at", event.x, event.y

def keyclick(event):
	print "Key click", event.keysym

root = Tk()
c = Canvas(root, width=640, height=480)
c.pack()

root.bind("<Key>", keyclick)
root.bind("<Button-1>", mouseclick)

c.config(borderwidth = 10)
c.config(background = "grey15")
c.steffe_i = 0

root.after(10, drawframe)
mainloop()

One function proper hexdump

The following function will convert a byte array to a format like this:

00000000  69 6d 70 6f 72 74 20 73  74 72 69 6e 67 0d 0a 0d  |import.string... |
00000010  0a 64 65 66 20 68 65 78  64 75 6d 70 28 63 76 65  |.def.hexdump(cve |
00000020  63 74 6f 72 2c 20 70 72  65 66 69 78 20 3d 20 22  |ctor,.prefix.=." |
00000030  22 29 3a 0d 0a 09 69 20  3d 20 30 0d 0a 09 73 20  |"):...i.=.0...s. |
00000040  3d 20 22 22 0d 0a 09 61  63 20 3d 20 5b 5d 0d 0a  |=.""...ac.=.[].. |
00000050  09 66 6f 72 20 63 20 69  6e 20 63 76 65 63 74 6f  |.for.c.in.cvecto |
00000060  72 3a 0d 0a 09 09 69 66  20 6e 6f 74 20 69 20 25  |r:....if.not.i.% |
00000070  20 31 36 3a 0d 0a 09 09  09 69 66 20 69 20 21 3d  |.16:.....if.i.!= |

The function is not designed to be memory efficient, fast or good looking, just simple to drop in and get some hex output.

import string

def hexdump(cvector, prefix = ""):
	i = 0
	s = ""
	ac = []
	for c in cvector:
		if not i % 16:
			if i != 0:
				s += " |"
				for cs in ac:
					css = chr(cs)
					s += css if css in string.printable and not css in string.whitespace else "."
				s += " |"
				ac = []
			s += "\n%s%s " % (prefix, "%08x " % i)
		elif not i % 8:
			s += " "
		s += "%02x " % c
		ac.append(c)
		i += 1
	if len(ac) > 0:
		left = 16 - len(ac)
		for k in range(left):
			s += "   "
		if left >= 8:
			s += " "
		s += " |"
		for cs in ac:
			css = chr(cs)
			s += css if css in string.printable and not css in string.whitespace else "."
		for k in range(left):
			s += " "
		s += " |"

		return s

with open("hexdump.py", "rb") as f:
	data = f.read()
	print(hexdump(data))