(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)