Welcome, guest | Sign In | My Account | Store | Cart

This code auto-generates a function that converts a string to bytes only in Python Versions 3.x.x. The function will NOT be generated in Python Versions 1.4.0 to 2.7.x. See the code for all the versions tested on. Inside the code are commented-out lines to show a practical usage for this and WILL be used in future /dev/audio or /dev/dsp access that I may develop...

See the notes right at the bottom and read all the notes inside the code...

This is NOT Public Domain like all my other stuff but is MIT licenced...

Enjoy finding simple solutions to often very difficult problems...

Bazza, G0LCU...

Python, 108 lines
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
# Forwards_Compatibility.py
#
# A DEMO generating a function on the fly...
#
# A DEMO showing how to use "bytes" and "string" classes/types inside the same code to access
# _directly_, say, the sound devices in Linux. The code as it stands runs on the paltforms
# and versions shown below...
#
# Many thanks to Daniel Lepage who showed me the way to change strings to bytes the Python way.
# This opened the door that I was looking for to write to the /dev/dsp device in Linux universally.
# It is NOT possible to use the bytes class and string class in one common Python code, (accessing
# a HW device in Linux), from Python 1.4.0 to 3.3A2, until now.
#
# When this code is run in versions Python 2.7.x down to 1.4.0, (inside Windows Vista 32 bit,
# PCLinuxOS 2009, Debian 6.0.0, Classic AMIGA A1200(HD), WinUAE and E-UAE), the "if" statement
# is completely ignored and the string is just a plain string class/type. HOWEVER when Python
# Versions 3.x.x is encountered the "if" statement comes into play. The "def_string" is a Python
# function in its own right and when executed using the "exec" statement becomes that fuction
# in reality; in ths case as "t2b(some_string)"; t2b(some_string) is then called to convert the
# "byte_string" into a bytes class/type.
#
# If the hashes are removed accessing the audio in Linux then this is a real case scenario for
# its usage. I can now progress using the /dev/dsp universally instead of having two lots of code
# doing the same thing...
#
# $VER: Forwards_Compatibility.py_Version_0.00.10_(C)2012_B.Walker_G0LCU.
#
# Issued under the MIT licence...
#
# =============================================================================
# Python 3.1.3 (r313:86834, Nov 28 2010, 10:01:07) 
# [GCC 4.4.5] on linux2
# Type "help", "copyright", "credits" or "license" for more information.
# >>> exec(open('/home/wisecracker/Desktop/Code/Forwards_Compatibility.py').read())
# b'\x00\x00\x00\x00\xff\xff\xff\xff'
# 8
# <class 'bytes'>
# >>> dir()
# ['__builtins__', '__doc__', '__name__', '__package__', 'byte_string', 'def_string', 'sys', 't2b']
# >>> print(def_string)
# def t2b(some_string):
#	decimals=[ord(char) for char in some_string]
#	return bytes(decimals)
#
# >>> _
# =============================================================================
# Python 2.6.6 (r266:84292, Dec 26 2010, 22:31:48) 
# [GCC 4.4.5] on linux2
# Type "help", "copyright", "credits" or "license" for more information.
# >>> execfile('/home/wisecracker/Desktop/Code/Forwards_Compatibility.py')
# ????
# 8
# <type 'str'>
# >>> dir()
# ['__builtins__', '__doc__', '__name__', '__package__', 'byte_string', 'sys']
# >>> print(def_string)
# Traceback (most recent call last):
#   File "<stdin>", line 1, in <module>
# NameError: name 'def_string' is not defined
# >>> _
# =============================================================================
# Both as predicted...
#
# Finally the Python Versions tested on:-
# AMIGA variants:- 1.4.0, 2.0.1.
# Windows Vista 32 bit:- 2.0.1, 2.1.3, 2.2.3, 2.3.2, 2.4.4, 2.5.4, 2.6.6, 2.7.2,
# 3.0.1, 3.2.1, 3.3A2.
# PCLinuxOS 2009 and Debian 6.0.0:- 2.4.6, 2.5.2, 2.6.2, 2.6.6, 2.7.2, 3.1.3, 3.2.2.

# An important import...
import sys

# Ensure global for all Python versions and platforms under test...
global byte_string

# A simple _square_wave_ string for Linux audio systems...
byte_string=chr(0)+chr(0)+chr(0)+chr(0)+chr(255)+chr(255)+chr(255)+chr(255)

# Ensure forwards compatibility...
if sys.version[0]=="3":
	# The string below is in reality a slightly more friendly version of this function from Daniel Lepage:-
	# def t2b(some_string):
	#	decimals = [ord(c) for c in some_string]
	#	return bytes(decimals)
	def_string="def t2b(some_string):\n\tdecimals=[ord(char) for char in some_string]\n\treturn bytes(decimals)\n"
	# Execute the string to generate the function on the fly...
	exec(def_string)
	# Now call the newly generated function...
	byte_string=t2b(byte_string)

# See above for a printout...
print(byte_string)
# This line should read 8 only.
print(len(byte_string))
# This line should print the string or bytes class/type depending on the runtime.
print(type(byte_string))

# Thses lines are for a physical test inside Linux flavours with /dev/dsp available...
#
# audio=open("/dev/dsp", "wb")
# for n in range(0, 1000, 1):
#	audio.write(byte_string)
# audio.close()
#
# Just remove the hashes for the four lines to have a real world test in Linux...

# End of Forwards_Compatibility.py DEMO...
# Enjoy finding simple solutions to often very difficult problems...

Read the code for more information...

It is NOT possible to directly have a bytes class/type and string class/type in _every_ version of Python. However it is possible to generate a bytes class/type on the fly during runtime IF it is needed. These two conflicting classes/types ARE needed for _direct_ access to say /dev/audio or /dev/dsp in Lunux but will not run at runtime from the versions 1.4.0 to 2.7.x in the code. The string class/type is available to ALL versions but the bytes class/type is only available from version 2.6.x yo 3.x.x.

Hence the DEMO code...

Why a function and not direct conversion? Well this is the reason:-

This DOES work:-

""" Python 3.1.3 (r313:86834, Nov 28 2010, 10:01:07) [GCC 4.4.5] on linux2 Type "help", "copyright", "credits" or "license" for more information.

>>> x="y=b'(C)2012, B.Walker, G0LCU.'"
>>> exec(x)
>>> type(x)
<class 'str'>
>>> type(y)
<class 'bytes'>
>>> dir()
['__builtins__', '__doc__', '__name__', '__package__', 'x', 'y']
>>> print(x)
y=b'(C)2012, B.Walker, G0LCU.'
>>> print(y)
b'(C)2012, B.Walker, G0LCU.'
>>> _
"""

However this does NOT work:-

""" Python 3.1.3 (r313:86834, Nov 28 2010, 10:01:07) [GCC 4.4.5] on linux2 Type "help", "copyright", "credits" or "license" for more information.

>>> x="y=b'\x00(C)2012, B.Walker, G0LCU.\xFF'"
>>> exec(x)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: source code string cannot contain null bytes
>>> type(x)
<class 'str'>
>>> dir()
['__builtins__', '__doc__', '__name__', '__package__', 'x']
>>> _
"""

Hence a function that is self generated ONLY when versions 3.x.x is encountered.

Enjoy finding simple solutions to often very difficult problems... ;o) Bazza, G0LCU...