(Home)
101010
from binary to base 10.# Either prefix with 0b
print(0b101010)
# Or convert from a string with base 2.
print(int('101010', 2))
42 42
2a
from hexidecimal to base 10.# Same with 0x
print(0x2a)
# or base 16.
print(int('2a', 16))
42 42
def hypotenuse(len1, len2) :
'''Calculate the length of the hypotenuse of a right
angle triangle given the length of the other two sides.'''
return (len1**2 + len2**2)**.5
hypotenuse(6, 8)
10.0
True
if all three are integers, else False
.int
(since a float
can have an integer value).def test_pythagorean_triple(len1, len2) :
'''Calculate the hypotenuse of a right angle triangle
given the other two sides and check if they form a
Pythagorean triple'''
len1 = float(len1)
len2 = float(len2)
# We cast to float in order to use float.is_integer
# Since 'and' operations stop at the first experssion
# that evaluates to False, the hypotenuse is only
# evaluated if both len1 and len2 are integers.
return (len1.is_integer() and len2.is_integer()
and hypotenuse(len1, len2).is_integer())
print(test_pythagorean_triple(6, 8))
print(test_pythagorean_triple(32, 46))
print(test_pythagorean_triple(161, 240))
print(test_pythagorean_triple(372, 496))
True False True True
for
loops, find all Pythagorean triples with hypotenuse < 100.tuple
of length 3 and add it to a list containing all the triples.6 8 10
triples = []
for len1 in range(1, 99):
# To get only unique triples, make the second side longer than the
# first (right angle triangles can't be triples).
for len2 in range(len1+1, 99):
hyp = hypotenuse(len1, len2)
# 'or' operations stop at the first expression that
# evaluates to True, so hyp.is_integer is only called
# if hyp < 100.
if hyp >= 100 or not hyp.is_integer():
# Try the next pair of side lengths
continue
triples.append((len1, len2, int(hyp)))
print('Found', len(triples), 'pythagorean triples')
for len1, len2, hyp in triples :
# Print as integers with 'd' suffix, with width 3.
# The 'f' prefix means to take the keyword arguments
# from variables of the same name in the local namespace.
print(f'{len1:3d} {len2:3d} {hyp:3d}')
Found 50 pythagorean triples 3 4 5 5 12 13 6 8 10 7 24 25 8 15 17 9 12 15 9 40 41 10 24 26 11 60 61 12 16 20 12 35 37 13 84 85 14 48 50 15 20 25 15 36 39 16 30 34 16 63 65 18 24 30 18 80 82 20 21 29 20 48 52 21 28 35 21 72 75 24 32 40 24 45 51 24 70 74 25 60 65 27 36 45 28 45 53 30 40 50 30 72 78 32 60 68 33 44 55 33 56 65 35 84 91 36 48 60 36 77 85 39 52 65 39 80 89 40 42 58 40 75 85 42 56 70 45 60 75 48 55 73 48 64 80 51 68 85 54 72 90 57 76 95 60 63 87 65 72 97
list
, int
or str
by making a variable with that name (eg, int = 3
- normally you should avoid doing this).# Make a variable named 'int'
# 'int' isn't a keyword, like 'def' or 'del', so this is allowed
# (but discouraged)
int = 1
# Now we've lost the int constructor.
i = int(3.2)
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-1-c76d6417123b> in <module> 4 int = 1 5 # Now we've lost the int constructor. ----> 6 i = int(3.2) TypeError: 'int' object is not callable
# Delete the local variable with name 'int'
del int
# Then the original 'int' is recovered.
print(int, type(int), int(3.2))
<class 'int'> <class 'type'> 3
int
value, then change the value of one of the variables and check if it changes the value of the other variable.list
instead of an int
. Modify the the list (change/delete/add an element) and check the values of both variables.# Assign a variable to 'a'.
a = 1
# This assigns variable 'b' to refer to the
# same object as 'a'.
b = a
# But this then assigns a different object
# to variable 'a'.
a = 2
# So b is unchanged by the change to a, as
# you might expect.
print(a, b)
2 1
# This also happens with operations on numerical types
a = 1
b = a
a += 2
# Only a is changed
print(a, b)
3 1
# Here we do similarly to above with L1 and L2.
L1 = ['spam', 'eggs']
L2 = L1
# However here, rather than assigning a new object
# to L1 we modify the underlying object.
del L1[0]
# As L1 and L2 refer to the same object the change
# is apparent to both variables
print(L1, L2)
['eggs'] ['eggs']
t1 = ('spam', 'eggs')
t2 = t1
# Again, here the difference is that we declare
# a new object and assign it to variable t1, so
# t1 and t2 no longer refer to the same object.
t1 = t1 + ('spam',)
print(t1, t2)
('spam', 'eggs', 'spam') ('spam', 'eggs')
id
built-in method returns a unique integer for every object (try help(id)
) so you can use it to check if variables refer to the same object, or if an operation has modified an existing object or assigned a new object to the same variable.# The id method returns an integer that's a
# unique identifier of a given object.
L1 = [1,2,3]
L2 = L1
# We see that the id of the objects refered to
# by L1 and L2 are the same, so they're the same
# object.
print(id(L1), id(L1) == id(L2))
4455581184 True
# Modifying the object doesn't affect what L1 and
# L2 refer to.
L1.append('4')
L2.insert(0, '0')
print(L1, L2)
print(id(L1) == id(L2))
['0', 1, 2, 3, '4'] ['0', 1, 2, 3, '4'] True
# But this syntax creates a new list and assigns
# it to L1, so L1 and L2 no longer refer to the
# same object.
L1 = L1 + [5, 6]
print(L1, L2)
print(id(L1) == id(L2))
['0', 1, 2, 3, '4', 5, 6] ['0', 1, 2, 3, '4'] False
# New object creation and assignment is sometimes
# hidden. Eg, you might expect the += operator to
# modify the original object rather than creating
# a new one. For mutable objects this is true:
L1 = [1,2,3]
oldid = id(L1)
L1 += [4, 5, 6]
print(id(L1) == oldid)
True
# But for immutable objects, like strings, +=
# actually creates a new string and assigns it
# to the original variable.
s = 'spam'
oldid = id(s)
# So this is actually like s = s + ' and eggs'.
s += ' and eggs'
print(id(s) == oldid)
False
# We've seen that this just assigns a new
# variable to refer to the same object.
L1 = [1,2,3]
L2 = L1
print(id(L1) == id(L2))
True
# You could create a new, empty list and
# plug in the values of the original one,
# but this is a bit cumbersome.
L2 = []
for elm in L1 :
L2.append(elm)
print(L1, L2)
print(id(L1) == id(L2))
[1, 2, 3] [1, 2, 3] False
# One alternative is to use slicing, but
# take a slice containing every element in the
# list, as a slice of a list returns a new
# list object. This was common in python2,
# but isn't the recommended method in python3.
L2 = L1[:]
print(L1, L2)
print(id(L1) == id(L2))
[1, 2, 3] [1, 2, 3] False
# You can also pass the original list to the
# list constructor. This works for any iterable
# argument, not just other lists.
L2 = list(L1)
print(L1, L2)
print(id(L1) == id(L2))
[1, 2, 3] [1, 2, 3] False
# In python3, the preferred (most readable)
# way is with list.copy
L2 = L1.copy()
print(L1, L2)
print(id(L1) == id(L2))
[1, 2, 3] [1, 2, 3] False
# Eg:
l = [1,2,3,4,5]
print(l[1:4:1])
[2, 3, 4]
# The third int represents the step size when
# selecting elements from the list. So to select
# every other element you can do:
print(l[0:len(l):2])
[1, 3, 5]
# Which is the same as:
print(l[::2])
[1, 3, 5]
# Using a negative value for the step size means
# it steps backwards through the list. However,
# then the first index must be larger than the
# second, else you just get an empty list:
print(l[1:4:-1])
print(l[4:1:-1])
[] [5, 4, 3]
# That means you can easily reverse a list (or
# other sequence that supports slicing) by doing:
print(l[::-1])
[5, 4, 3, 2, 1]
'Brave Sir Robin' => 'nIbOr rIs EvArb'
# Again there are a few options in doing this.
# The main pitfall here is that attempting to
# modify a single character in a string raises
# an exception, as strings are immutable.
name = 'Brave Sir Robin'
name[0] = name[0].lower()
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-1-39850001a950> in <module> 4 # an exception, as strings are immutable. 5 name = 'Brave Sir Robin' ----> 6 name[0] = name[0].lower() TypeError: 'str' object does not support item assignment
# So you need to declare a new string
# to contain your modified string.
newname = ''
# Then you could loop backwards over
# characters in the original string and
# add them to the new string one by one.
vowels = 'aeiou'
for i in range(len(name)-1, -1, -1) :
c = name[i].lower()
if c in vowels :
c = c.upper()
newname += c
# This is effective but requires several
# lines of code.
print(newname)
nIbOr rIs EvArb
# We can use slicing on strings similarly to
# lists.
# Eg, taking every other character over the
# first 5 characters.
print(name[0:5:2])
# Or over the whole string
print(name[::2])
Bae BaeSrRbn
# And to reverse the string:
print(name[::-1])
niboR riS evarB
# Then all that remains is to make the consonants
# lower case and vowels upper case.
# First reverse the string and make everything
# lower case.
newname = name[::-1].lower()
# Then you can loop over the vowels and replace
# them with uppercase versions
for v in vowels:
newname = newname.replace(v, v.upper())
print(newname)
nIbOr rIs EvArb
from functools import reduce
# Alternatively, you can use the reduce builtin
# method for repeated operations, which does
# exactly the same as above.
newname = reduce(lambda name, vowel : name.replace(vowel, vowel.upper()),
'aeiou', name[::-1].lower())
print(newname)
nIbOr rIs EvArb
# The regular expressions module 're' also provides
# very flexible means of replacing expressions in
# strings.
import re
newname = re.sub('a|e|i|o|u', lambda x : x.group().upper(),
name[::-1].lower())
print(newname)
nIbOr rIs EvArb
# Eg:
def arguments(*args) :
print('args =', args)
args
within the function?# args is a tuple
arguments()
args = ()
arguments(1)
args = (1,)
arguments(1,2,3)
args = (1, 2, 3)
arguments([1,2,3])
args = ([1, 2, 3],)
# This fails as the function only expects unnamed (positional)
# arguments, and no named (keyword) arguments
arguments(1,2,3, a=0)
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-1-5c004a9cb602> in <module> 1 # This fails as the function only expects unnamed (positional) 2 # arguments, and no named (keyword) arguments ----> 3 arguments(1,2,3, a=0) TypeError: arguments() got an unexpected keyword argument 'a'
# Eg:
def named_args(**kwargs) :
print('kwargs =', kwargs)
# Eg:
named_args()
named_args(a = 1, b = 2)
named_args(t = ('a', 'b', 'c'), l = [1, 2, 3], f = 3.5)
named_args(1, n = 3)
kwargs = {} kwargs = {'a': 1, 'b': 2} kwargs = {'t': ('a', 'b', 'c'), 'l': [1, 2, 3], 'f': 3.5}
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-1-5a07e324dc60> in <module> 4 named_args(a = 1, b = 2) 5 named_args(t = ('a', 'b', 'c'), l = [1, 2, 3], f = 3.5) ----> 6 named_args(1, n = 3) TypeError: named_args() takes 0 positional arguments but 1 was given
kwargs
within the method?# Eg:
def args_and_keywords(*args, **kwargs) :
print('args =', args)
print('kwargs =', kwargs)
# The jist of this exercise is that 'args'
# is a tuple of unnamed args within the method,
# while 'kwargs' is a dict with keys and values
# defined by the named arguments passed to the
# function.
args_and_keywords(1,2,3, a = 4, b = 5, c = 6)
args = (1, 2, 3) kwargs = {'a': 4, 'b': 5, 'c': 6}
# You can pass only unnamed arguments
args_and_keywords(1,2,3)
args = (1, 2, 3) kwargs = {}
# Or only named arguments
args_and_keywords(v1 = 3, v2 = 1 + 4j)
args = () kwargs = {'v1': 3, 'v2': (1+4j)}
# Or any combination of the two. However,
# the unnamed arguments must always come
# before the named ones.
# This is because the position of the
# unnamed arguments is strictly defined.
args_and_keywords(v1 = 1, 1, 2, 3)
File "<ipython-input-1-7b5a56565bff>", line 6 args_and_keywords(v1 = 1, 1, 2, 3) ^ SyntaxError: positional argument follows keyword argument
# You can also use this syntax when calling
# functions. Eg,
def tuplepair(a, b) :
return a, b
t = (1,2)
# This unpacks the tuple t and passes its
# contents to the method. So this is equivalent
# to calling:
# tuplepair(1, 2)
print(tuplepair(*t))
# Similarly, the ** allows unpacking of a dict,
# and passing its contents as named args. So
# this is equivalent to:
# tuplepair(a = 6, b = 7)
d = {'a' : 6, 'b' : 7}
print(tuplepair(**d))
# This means you can cache the arguments you want to
# pass to any function in tuples, lists or dicts,
# then call the function using them later.
(1, 2) (6, 7)
__init__
member function to take values for x, y & z, with their default values being zero.__add__
member function that returns a new 3-vector that's the sum of the vector with another given as an argument, so you can use the +
operator on instances of your class.+
operator on instances of your class.class ThreeVector :
'''A three component vector.'''
__slots__ = ('x', 'y', 'z')
def __init__(self, x = 0., y = 0., z = 0.) :
'''Initialise with (x, y, z) values.'''
self.x = x
self.y = y
self.z = z
def __add__(self, other) :
'''Get the sum of this vector with another.'''
return ThreeVector(self.x + other.x,
self.y + other.y,
self.z + other.z)
def dot_product(self, other) :
'''Get the dot product of this vector with another.'''
return self.x * other.x + self.y * other.y + self.z * other.z
def is_orthogonal(self, other) :
'''Check if this vector is orthogonal to another.'''
return self.dot_product(other) == 0.
def __str__(self) :
return '({0}, {1}, {2})'.format(self.x, self.y, self.z)
def __repr__(self) :
return 'ThreeVector({0!r}, {1!r}, {2!r})'.format(self.x, self.y, self.z)
v1 = ThreeVector(4, -7, 9)
v2 = ThreeVector(54, -18, -38)
v1.is_orthogonal(v2)
True
v1 = ThreeVector(890, 3254, 6404) + ThreeVector(542, -912, 834)
v2 = ThreeVector(1227, -484, -97) + ThreeVector(-8465, 7722, -813)
v1.is_orthogonal(v2)
True
# For reference, here's an easy way to find a vector
# that's orthogonal to another given two random
# integers.
def orthogonal_vector(v, a, b) :
a *= v.z
b *= v.z
c = int(-(v.x * a + v.y * b)/v.z)
vo = ThreeVector(a, b, c)
print(v, (a, b, c))
print(vo.dot_product(v))
return vo
date
class from the datetime
module to work out how old you are in days.from datetime import date
today = date.today()
# First let's see what a date object can do.
print(dir(today))
['__add__', '__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__ne__', '__new__', '__radd__', '__reduce__', '__reduce_ex__', '__repr__', '__rsub__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', 'ctime', 'day', 'fromisocalendar', 'fromisoformat', 'fromordinal', 'fromtimestamp', 'isocalendar', 'isoformat', 'isoweekday', 'max', 'min', 'month', 'replace', 'resolution', 'strftime', 'timetuple', 'today', 'toordinal', 'weekday', 'year']
# We see it's got a __sub__ method, so
# you can take the difference of date
# objects. Lets see what it returns.
birthday = date(1986, 10, 18)
diff = today - birthday
print(diff, type(diff))
print(dir(diff))
12893 days, 0:00:00 <class 'datetime.timedelta'> ['__abs__', '__add__', '__bool__', '__class__', '__delattr__', '__dir__', '__divmod__', '__doc__', '__eq__', '__floordiv__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__mod__', '__mul__', '__ne__', '__neg__', '__new__', '__pos__', '__radd__', '__rdivmod__', '__reduce__', '__reduce_ex__', '__repr__', '__rfloordiv__', '__rmod__', '__rmul__', '__rsub__', '__rtruediv__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__truediv__', 'days', 'max', 'microseconds', 'min', 'resolution', 'seconds', 'total_seconds']
# So we get a timedelta object, which has
# a 'days' attribute that gives the number
# of days difference between the two dates.
print(diff.days)
12893
# Just to check it handles leap years OK:
(date(2012, 3, 1) - date(2012, 2, 1)).days
29
# So the quickets way of getting your age in
# days is:
birthday = date(1986, 10, 18)
print('I am', (date.today() - birthday).days, 'days old.')
I am 12893 days old.
# Then to get the date on which you are/were 10000
# days old:
from datetime import timedelta, date
birthday = date(1986, 10, 18)
today = date.today()
tenKDelta = timedelta(days=10000)
tenKDate = birthday + tenKDelta
# Note that you can do comparisons on date objects.
if tenKDate < today :
print('I was 10000 days old on', tenKDate)
elif tenKDate == today :
print('I am 10000 days old today! (', tenKDate, ')', sep = '')
else :
print('I will be 10000 days old on', tenKDate)
I was 10000 days old on 2014-03-05
pickle
to save the date on which you're 10000 days old to a file, then load it again and verify that it's the same date you started with.import pickle
# Remember to open the file for writing in binary mode
with open('TenKDate.pkl', 'wb') as fdate :
pickle.dump(tenKDate, fdate)
# Similarly read in binary mode
with open('TenKDate.pkl', 'rb') as fdate :
checkDate = pickle.load(fdate)
checkDate == tenKDate
True
# Get the file.
# Obviously you could just click the link and save it to your working directory
# but here's a way to do it in python
import urllib
import os
url = 'https://raw.githubusercontent.com/MannyMoo/IntroductionToPython/master/vectors.txt'
_url, fname = os.path.split(url)
# Download the file to the given destination with urlretrieve.
urllib.request.urlretrieve(url, fname)
('vectors.txt', <http.client.HTTPMessage at 0x109849820>)
vectors = []
# Read the file
with open('vectors.txt') as fvec :
for line in fvec:
# Split the line by whitespace, convert to an int,
# and pass as arguments to the ThreeVector class
vec = ThreeVector(*[int(val) for val in line.split()])
vectors.append(vec)
north = 0
ntot = 0
# Loop over vectors
for i, v1 in enumerate(vectors) :
# Loop over remaining vectors, to get unique pairs
for v2 in vectors[i+1:] :
ntot += 1
orth = v1.is_orthogonal(v2)
print('v1: {v1:25}, v2: {v2:25}, orthogonal? {orth}'.format(v1=str(v1),
v2=str(v2),
orth=orth))
north += int(orth)
print('N. orthogonal:', north, '/', ntot)
v1: (19700, -12805, 20174) , v2: (932, -118, -985) , orthogonal? True v1: (19700, -12805, 20174) , v2: (-929, 4645, -840) , orthogonal? False v1: (19700, -12805, 20174) , v2: (-19509, 1858, -20318) , orthogonal? False v1: (19700, -12805, 20174) , v2: (-4039, 3462, 1946) , orthogonal? False v1: (19700, -12805, 20174) , v2: (-3940, -7880, -2784) , orthogonal? False v1: (19700, -12805, 20174) , v2: (2885, -9809, -13316) , orthogonal? False v1: (19700, -12805, 20174) , v2: (-8655, -10963, -25712) , orthogonal? False v1: (19700, -12805, 20174) , v2: (-18580, 2787, -19322) , orthogonal? False v1: (19700, -12805, 20174) , v2: (-19700, -20685, -16162) , orthogonal? False v1: (19700, -12805, 20174) , v2: (-970, -26, 929) , orthogonal? False v1: (19700, -12805, 20174) , v2: (-526, -938, 577) , orthogonal? False v1: (932, -118, -985) , v2: (-929, 4645, -840) , orthogonal? False v1: (932, -118, -985) , v2: (-19509, 1858, -20318) , orthogonal? False v1: (932, -118, -985) , v2: (-4039, 3462, 1946) , orthogonal? False v1: (932, -118, -985) , v2: (-3940, -7880, -2784) , orthogonal? True v1: (932, -118, -985) , v2: (2885, -9809, -13316) , orthogonal? False v1: (932, -118, -985) , v2: (-8655, -10963, -25712) , orthogonal? False v1: (932, -118, -985) , v2: (-18580, 2787, -19322) , orthogonal? False v1: (932, -118, -985) , v2: (-19700, -20685, -16162) , orthogonal? True v1: (932, -118, -985) , v2: (-970, -26, 929) , orthogonal? False v1: (932, -118, -985) , v2: (-526, -938, 577) , orthogonal? False v1: (-929, 4645, -840) , v2: (-19509, 1858, -20318) , orthogonal? False v1: (-929, 4645, -840) , v2: (-4039, 3462, 1946) , orthogonal? False v1: (-929, 4645, -840) , v2: (-3940, -7880, -2784) , orthogonal? False v1: (-929, 4645, -840) , v2: (2885, -9809, -13316) , orthogonal? False v1: (-929, 4645, -840) , v2: (-8655, -10963, -25712) , orthogonal? False v1: (-929, 4645, -840) , v2: (-18580, 2787, -19322) , orthogonal? False v1: (-929, 4645, -840) , v2: (-19700, -20685, -16162) , orthogonal? False v1: (-929, 4645, -840) , v2: (-970, -26, 929) , orthogonal? True v1: (-929, 4645, -840) , v2: (-526, -938, 577) , orthogonal? False v1: (-19509, 1858, -20318) , v2: (-4039, 3462, 1946) , orthogonal? False v1: (-19509, 1858, -20318) , v2: (-3940, -7880, -2784) , orthogonal? False v1: (-19509, 1858, -20318) , v2: (2885, -9809, -13316) , orthogonal? False v1: (-19509, 1858, -20318) , v2: (-8655, -10963, -25712) , orthogonal? False v1: (-19509, 1858, -20318) , v2: (-18580, 2787, -19322) , orthogonal? False v1: (-19509, 1858, -20318) , v2: (-19700, -20685, -16162) , orthogonal? False v1: (-19509, 1858, -20318) , v2: (-970, -26, 929) , orthogonal? True v1: (-19509, 1858, -20318) , v2: (-526, -938, 577) , orthogonal? False v1: (-4039, 3462, 1946) , v2: (-3940, -7880, -2784) , orthogonal? False v1: (-4039, 3462, 1946) , v2: (2885, -9809, -13316) , orthogonal? False v1: (-4039, 3462, 1946) , v2: (-8655, -10963, -25712) , orthogonal? False v1: (-4039, 3462, 1946) , v2: (-18580, 2787, -19322) , orthogonal? False v1: (-4039, 3462, 1946) , v2: (-19700, -20685, -16162) , orthogonal? False v1: (-4039, 3462, 1946) , v2: (-970, -26, 929) , orthogonal? False v1: (-4039, 3462, 1946) , v2: (-526, -938, 577) , orthogonal? True v1: (-3940, -7880, -2784) , v2: (2885, -9809, -13316) , orthogonal? False v1: (-3940, -7880, -2784) , v2: (-8655, -10963, -25712) , orthogonal? False v1: (-3940, -7880, -2784) , v2: (-18580, 2787, -19322) , orthogonal? False v1: (-3940, -7880, -2784) , v2: (-19700, -20685, -16162) , orthogonal? False v1: (-3940, -7880, -2784) , v2: (-970, -26, 929) , orthogonal? False v1: (-3940, -7880, -2784) , v2: (-526, -938, 577) , orthogonal? False v1: (2885, -9809, -13316) , v2: (-8655, -10963, -25712) , orthogonal? False v1: (2885, -9809, -13316) , v2: (-18580, 2787, -19322) , orthogonal? False v1: (2885, -9809, -13316) , v2: (-19700, -20685, -16162) , orthogonal? False v1: (2885, -9809, -13316) , v2: (-970, -26, 929) , orthogonal? False v1: (2885, -9809, -13316) , v2: (-526, -938, 577) , orthogonal? True v1: (-8655, -10963, -25712) , v2: (-18580, 2787, -19322) , orthogonal? False v1: (-8655, -10963, -25712) , v2: (-19700, -20685, -16162) , orthogonal? False v1: (-8655, -10963, -25712) , v2: (-970, -26, 929) , orthogonal? False v1: (-8655, -10963, -25712) , v2: (-526, -938, 577) , orthogonal? True v1: (-18580, 2787, -19322) , v2: (-19700, -20685, -16162) , orthogonal? False v1: (-18580, 2787, -19322) , v2: (-970, -26, 929) , orthogonal? True v1: (-18580, 2787, -19322) , v2: (-526, -938, 577) , orthogonal? False v1: (-19700, -20685, -16162) , v2: (-970, -26, 929) , orthogonal? False v1: (-19700, -20685, -16162) , v2: (-526, -938, 577) , orthogonal? False v1: (-970, -26, 929) , v2: (-526, -938, 577) , orthogonal? False N. orthogonal: 9 / 66
# This is how to generate the file with some (pseudo-) random vectors,
# some of which are orthogonal.
import random
# Ensures it always generates the same file.
random.seed(1234)
vals = []
for i in range(3) :
v = ThreeVector(*[int(random.random()*2000 - 1000) for k in range(3)])
vals.append(v)
for j in range(3) :
vo = orthogonal_vector(v, *[int(random.random()*50 - 25) for k in range(2)])
vals.append(vo)
print('ordered')
for v in vals :
print(v)
random.shuffle(vals)
print('shuffled')
with open('vectors.txt', 'w') as fvec :
for v in vals :
valstr = '{0:5d} {1:5d} {2:5d}'.format(v.x, v.y, v.z)
print(valstr)
fvec.write(valstr + '\n')
(932, -118, -985) (-19700, -20685, -16162) 0 (932, -118, -985) (-3940, -7880, -2784) 0 (932, -118, -985) (19700, -12805, 20174) 0 (-526, -938, 577) (-4039, 3462, 1946) 0 (-526, -938, 577) (2885, -9809, -13316) 0 (-526, -938, 577) (-8655, -10963, -25712) 0 (-970, -26, 929) (-19509, 1858, -20318) 0 (-970, -26, 929) (-929, 4645, -840) 0 (-970, -26, 929) (-18580, 2787, -19322) 0 ordered (932, -118, -985) (-19700, -20685, -16162) (-3940, -7880, -2784) (19700, -12805, 20174) (-526, -938, 577) (-4039, 3462, 1946) (2885, -9809, -13316) (-8655, -10963, -25712) (-970, -26, 929) (-19509, 1858, -20318) (-929, 4645, -840) (-18580, 2787, -19322) shuffled 19700 -12805 20174 932 -118 -985 -929 4645 -840 -19509 1858 -20318 -4039 3462 1946 -3940 -7880 -2784 2885 -9809 -13316 -8655 -10963 -25712 -18580 2787 -19322 -19700 -20685 -16162 -970 -26 929 -526 -938 577
(Home)