diff --git a/classes/private/Confidential.java b/classes/private/Confidential.java index 99eeefd..6dc740d 100644 --- a/classes/private/Confidential.java +++ b/classes/private/Confidential.java @@ -1,9 +1,8 @@ public class Confidential { - private String secret = ""; - private String hidden = "burn after reading"; + private String secret = ""; - public Confidential(String text) { - this.secret = text.toUpperCase(); - } + public Confidential(String text) { + secret = text.toUpperCase(); + } } diff --git a/classes/private/Expose.java b/classes/private/Expose.java index 8a52bb3..dac57fe 100644 --- a/classes/private/Expose.java +++ b/classes/private/Expose.java @@ -2,24 +2,24 @@ import java.lang.reflect.Field; public class Expose { - public static void main(String[] args) { - Confidential message = new Confidential("top secret text"); - Field secretField = null; - try { - secretField = Confidential.class.getDeclaredField("secret"); - } - catch (NoSuchFieldException e) { - System.err.println(e); - System.exit(1); - } - secretField.setAccessible(true); // break the lock! - try { - String wasHidden = (String) secretField.get(message); - System.out.println("message.secret = " + wasHidden); - } - catch (IllegalAccessException e) { - // this will not happen after setAcessible(true) - System.err.println(e); - } - } + public static void main(String[] args) { + Confidential message = new Confidential("top secret text"); + Field secretField = null; + try { + secretField = Confidential.class.getDeclaredField("secret"); + } + catch (NoSuchFieldException e) { + System.err.println(e); + System.exit(1); + } + secretField.setAccessible(true); // break the lock! + try { + String wasHidden = (String) secretField.get(message); + System.out.println("message.secret = " + wasHidden); + } + catch (IllegalAccessException e) { + // this will not happen after setAcessible(true) + System.err.println(e); + } + } } diff --git a/classes/vector2d_v3_prophash.py b/classes/vector2d_v3_prophash.py new file mode 100644 index 0000000..2eca4ec --- /dev/null +++ b/classes/vector2d_v3_prophash.py @@ -0,0 +1,161 @@ +""" +A 2-dimensional vector class + + >>> v1 = Vector2d(3, 4) + >>> print(v1.x, v1.y) + 3.0 4.0 + >>> x, y = v1 + >>> x, y + (3.0, 4.0) + >>> v1 + Vector2d(3.0, 4.0) + >>> v1_clone = eval(repr(v1)) + >>> v1 == v1_clone + True + >>> print(v1) + (3.0, 4.0) + >>> octets = bytes(v1) + >>> octets + b'd\\x00\\x00\\x00\\x00\\x00\\x00\\x08@\\x00\\x00\\x00\\x00\\x00\\x00\\x10@' + >>> abs(v1) + 5.0 + >>> bool(v1), bool(Vector2d(0, 0)) + (True, False) + + +Test of ``.frombytes()`` class method: + + >>> v1_clone = Vector2d.frombytes(bytes(v1)) + >>> v1_clone + Vector2d(3.0, 4.0) + >>> v1 == v1_clone + True + + +Tests of ``format()`` with Cartesian coordinates: + + >>> format(v1) + '(3.0, 4.0)' + >>> format(v1, '.2f') + '(3.00, 4.00)' + >>> format(v1, '.3e') + '(3.000e+00, 4.000e+00)' + + +Tests of the ``angle`` method:: + + >>> Vector2d(0, 0).angle() + 0.0 + >>> Vector2d(1, 0).angle() + 0.0 + >>> epsilon = 10**-8 + >>> abs(Vector2d(0, 1).angle() - math.pi/2) < epsilon + True + >>> abs(Vector2d(1, 1).angle() - math.pi/4) < epsilon + True + + +Tests of ``format()`` with polar coordinates: + + >>> format(Vector2d(1, 1), 'p') # doctest:+ELLIPSIS + '<1.414213..., 0.785398...>' + >>> format(Vector2d(1, 1), '.3ep') + '<1.414e+00, 7.854e-01>' + >>> format(Vector2d(1, 1), '0.5fp') + '<1.41421, 0.78540>' + +# BEGIN VECTOR2D_V3_DEMO +Tests of `x` and `y` read-only properties: + + >>> v1.x, v1.y + (3.0, 4.0) + >>> v1.x = 123 + Traceback (most recent call last): + ... + AttributeError: can't set attribute + +# END VECTOR2D_V3_HASH_DEMO + +Tests of hashing: +# BEGIN VECTOR2D_V3_HASH_DEMO + + >>> v1 = Vector2d(3, 4) + >>> v2 = Vector2d(3.1, 4.2) + >>> hash(v1), hash(v2) + (7, 384307168202284039) + >>> len(set([v1, v2])) + 2 + +# END VECTOR2D_V3_DEMO + +""" + +from array import array +import math + +# BEGIN VECTOR2D_V3_PROP +class Vector2d: + typecode = 'd' + + def __init__(self, x, y): + self.__x = float(x) # <1> + self.__y = float(y) + + @property # <2> + def x(self): # <3> + return self.__x # <4> + + @property # <5> + def y(self): + return self.__y + + def __iter__(self): + return (i for i in (self.x, self.y)) # <6> + + # remaining methods follow (omitted in book listing) +# END VECTOR2D_V3_PROP + + def __repr__(self): + class_name = type(self).__name__ + return '{}({!r}, {!r})'.format(class_name, *self) + + def __str__(self): + return str(tuple(self)) + + def __bytes__(self): + return (bytes([ord(self.typecode)]) + + bytes(array(self.typecode, self))) + + def __eq__(self, other): + return tuple(self) == tuple(other) + +# BEGIN VECTOR_V3_HASH + def __hash__(self): + return hash(self.x) ^ hash(self.y) +# END VECTOR_V3_HASH + + def __abs__(self): + return math.hypot(self.x, self.y) + + def __bool__(self): + return bool(abs(self)) + + def angle(self): + return math.atan2(self.y, self.x) + + def __format__(self, fmt_spec=''): + if fmt_spec.endswith('p'): + fmt_spec = fmt_spec[:-1] + coords = (abs(self), self.angle()) + outer_fmt = '<{}, {}>' + else: + coords = self + outer_fmt = '({}, {})' + components = (format(c, fmt_spec) for c in coords) + return outer_fmt.format(*components) + + @classmethod + def frombytes(cls, octets): + typecode = chr(octets[0]) + memv = memoryview(octets[1:]).cast(typecode) + return cls(*memv)