Snake_Byte[5]: Range

Now… We are going in a loop.

~ Ramakrishna, Springs of Indian Wisdom
1K+ Loop Pictures | Download Free Images on Unsplash
Loops All The Way Down

First, i trust everyone is safe.

Second, i’ll will be moving the frequency of Snake_Bytes [] to every other Wednesday. This is to provide higher quality information and also to allow me space and time to write other blogs. i trust dear reader y’all do not mind.

Third, i noticed i was remiss in explaining a function i used in a previous Snake_Byte [ ] that of the Python built-in function called range.

Range is a very useful function for, well, creating iterations on variables and loops.

# lets see how this works:
range(4)
[0,1,2,3]

How easy can that be?

Four items were returned. Now we can create a range or a for loop over that list – very meta huh?

Please note in the above example the list starts off with 0. So what if you want your range function to start with 1 base index instead of 0? You can specify that in the range function:

# Start with 1 for intial index
range (1,4)
[1,2,3]

Note the last number in the index in order to be inclusive for the entire index.

Lets try something a little more advanced with some eye candy:

%matplotlib inline
x_cords = range(-50,50)
y_cords = [x*x for x in x_cords]

plt.plot(x_cords, y_cords)
plt.show()

X^2 Function aka Parabola

We passed a computation into the loop to compute over the indices of range x in this case.

In one of the previous Snake_Bytes[] i utilized a for loop and range which is extremely powerful to iterate over sequences:

for i in range (3):
    print(i,"Pythons")
0 Pythons
1 Pythons 
2 Pythons

For those that really need power when it comes to indexing, sequencing and iteration you can change the list for instance, as we move across it. For example:

L = [1,2,3,4,5,6]
#no add one to each row 
# or L[1] = L[i] +1 used all 
# the time in matrix operations
for i in range(len(L)): 
    L[i] += 1
print (L)
[2,3,4,5,6,7]

Note there is a more “slick” way to do this with list comprehension without changing the original list in place. However, that’s outside the scope if you will of this Snake_Byte[] . Maybe i should do that for the next one?

Well, i hope you have a slight idea of the power of range.

Also, i think this was more “byte-able” and not tl;dr. Let me know!

Until Then,

#iwshyouwater <- another good one here click!

@tctjr

Muzak To Blog By: Roger Eno & Brian Eno – Mixing Colors (this album is spectacular)

Snake_Byte[4]: Random and PseudoRandom Numbers

Expose yourself to as much randomness as possible.


~ Ben Casnocha
Visualization of the algorithmic random data
A Visualization Of Randomness

First i trust everyone is safe.

Second it is WEDNESDAY and that must mean a Snake_Byte or you are working in a startup because every day is WEDNESDAY in a startup!

i almost didn’t get this one done because well life happens but i want to remain true to the goals herewith to the best of my ability.

So in today’s Snake_Byte we are going to cover Random and PseudoRandom Numbers.  i really liked this one because it was more in line with scientific computing and numerical optimization.

The random module in Python generates what is called pseudorandom numbers.  It is in the vernacular a pseudorandom number generator (PRNG).  This generation includes different types of distributions for said numbers. 

So what is a pseudorandom number:

“A pseudorandom number generator (PRNG), also known as a deterministic random bit generator, is an algorithm for generating a sequence of numbers whose properties approximate the properties of sequences of random numbers.” ~ Wikipedia

The important aspect here is:  the properties approximate sequences of random numbers.  So this means that it is statistically random even though it was generated by a deterministic response.

While i have used the random module and have even generated various random number algorithms i learned something new in this blog.  The pseudorandom number generator in Python uses an algorithm called the Mersenne Twister algorithm.  The period of said algorithm is length 2**19937-1 for the 32 bit version and there is also a 64-bit version.  The underlying implementation in C is both fast and thread-safe. The Mersenne Twister is one of the most extensively tested random number generators in existence. One issue though is that due to the deterministic nature of the algorithm it is not suitable for cryptographic methods.

Let us delve down into some code into the various random module offerings, shall we?

i like using %system in Jupyter Lab to create an interactive session. First we import random. Lets look at random.random() which returns a uniform distribution and when multiplied by a integer bounds it within that distribution range:

%system
import random
for i in range (5):
    x = random.random() * 100
    print (x)
63.281889167063035
0.13679757425121286
47.697874648329
96.66882808709684
76.63300711554905

Next let us check out random.choice(seq) which returns a random element from the non-empty sequence seq. If seq is empty, raises IndexError:

for z in range (5):
mySurfBoardlist = ["longboard", "shortboard", "boogieboard"]
print(random.choice(mySurfBoardlist))
longboard
boogieboard
boogieboard
longboard
shortboard

Next let us look at random.randrange(startstop[, step]) which returns a randomly selected element from range(start, stop, step). This is equivalent to choice(range(start, stop, step)) but doesn’t actually build a range object.

ParameterDescription
startOptional. An integer specifying at which position to start.
Default 0
stopRequired. An integer specifying at which position to end.
stepOptional. An integer specifying the incrementation.
Default 1
random.ranrange parameters
for i in range (5): 
      print(random.randrange(10, 100,1))
84
21
94
91
87

Now let us move on to some calls that you would use in signal processing, statistics or machine learning. The first one is gauss(). gauss() returns a gaussian distribution using the following mathematics:

\Large f(x) = \frac{1}{\sigma\sqrt{2\pi}}\exp\left(-\frac{1}{2}\left(\frac{x-\mu}{\sigma}\right)^{2}\right)

Gaussian distribution (also known as normal distribution) is a bell-shaped curve (aka the bell curve), and it is assumed that during any measurement values will follow a normal distribution with an equal number of measurements above and below the mean value.

ParameterDescription
muthe mean
sigmathe standard deviation
returns a random gaussian distribution floating number
gauss() parameters
# import the required libraries 
import random 
import matplotlib.pyplot as plt 
#set the inline magic
%matplotlib inline   
# store the random numbers in a list 
nums = [] 
mu = 100
sigma = 50
    
for i in range(100000): 
    temp = random.gauss(mu, sigma) 
    nums.append(temp) 
        
# plot the distribution 
plt.hist(nums, bins = 500, ec="red") 
plt.show()
Gaussian Distribution in Red

There are several more parameters in the random module, setter functions, seed functions and very complex statistical functions. Hit stack overflow and give it a try! Also it doesn’t hurt if you dust off that probability and statistics textbook!

As a last thought which came first the framework of entropy or the framework of randomness? As well as is everything truly random? i would love to hear your thought in the comments!

Until then,

#iwishyouwater <- click here on this one!

tctjr

References:

Python In A Nutshell by Alex Martelli

M. Matsumoto and T. Nishimura, “Mersenne Twister: A 623-dimensionally equidistributed uniform pseudorandom number generator”, ACM Transactions on Modeling and Computer Simulation Vol. 8, No. 1, January pp.3–30 1998

Muzak To Muzak To Blog By:  Black Sabbath  – The End: Live In Birmingham

Snake_Byte[3]: Getting Strung Out

There is geometry in the humming of the strings, there is music in the spacing of the spheres.

Pythagoras
How to Change Those Guitar Strings. | Superprof
We are not talking Guitar Strings

First, i  trust everyone is safe.

Second, this is the SB[3].  We are going to be covering some basics in Python of what constitutes a string, modifying a string, and explaining several string manipulation methods.

I also realized in the last Snake_Byte that i didn’t reference the book that i randomly open and choose the subject for the Snake_Byte.  I will be adding that as a reference at the end of the blog.

Strings can be used to represent just about anything.

They can be binary values of bytes, internet addresses, names, and Unicode for international localization.

They are part of a larger class of objects called sequences.  In fact, python strings are immutable sequences.  Immutability means you cannot change the sequence or the sequence does not change over time.

The most simplistic string is an empty string:

a = “ “ # with either singe or double quotes

There are numerous expression operations, modules, and methods for string manipulations.  

Python also supports much more advanced operations for those familiar with regular expressions (regex) it supports them via reEven more advanced operations are available such as XML parsing and the like.

Python is really into strings.

So let us get literal, shall we?

For String Literals there are countless ways to create and manipulate strings in your code:

Single Quotes:

a = `i w”ish you water’

Double Quotes;

A = “i w’ish you water”

Even triple quotes (made me think of the “tres commas” episode from Silicon Valley)

A = ```... i wish you water ```

Single and double quotes are by far the most used.  I prefer double quotes probably due to the other languages i learned before Python.

Python also supports the liberal use of backslashes aka escape sequences.  I’m sure everyone is familiar with said character `\`.  

Escape sequences let us embed bytecodes into strings that are otherwise difficult to type.

So let’s see here:

s = 't\nc\nt\njr'
print (s)
t
c
t
jr

So here i used ‘\n’ to represent the byte containing the binary value for newline character which is ASCII code 10.  There are several accessible representations:

‘\a\’ # bell

‘\b\’ #backspace

‘\f’ # formfeed for all the dot matrix printers we use 

‘\r’ #carriage return

You can even do different Unicode hex values:

‘\Uhhhhhhhh’ #32 bit hex count the number of h’s

With respect to binary file representations of note in Python 3.0 binary file content is represented by an actual byte string with operations similar to normal strings. 

One big difference between Python and another language like C is that that the zero (null) byte doesn’t terminate and in fact, there are no character string terminations in Python.  Also, the strings length and text reside in memory. 

s = 'a\0b\0c'
print (s)
len (s)
abc
5

So what can we do with strings in Python?

Well, we can concatenate:

a = "i wish"
print(len (a))
b = " you water"
print (len(b))
c = a + b
print (len(c))
print (c)
6
10
16
i wish you water

So adding two strings creates a new string object and a new address in memory.  It is also a form of operator overloading in place.  The ‘ + ‘ sign does the job for strings and can add numerics.  You also don’t have to “pre-declare” and allocate memory which is one of the advantages of Python.  In Python, computational processes are described directly by the programmer. A declarative language abstracts away procedural details however Python isn’t purely declarative which is outside the scope of the blog.  

So what else?  Well, there is indexing and slicing:

Strings are ordered collections of characters ergo we can access the characters by the positions within the ordering.

You access the component by providing a numerical offset via square brackets this is indexing.  

S = "i wish you water"
print (S[0], S[4], S[-1])
i s r

Since we can index we can slice:

S = "i wish you water"
print (S[1:3], S[2:10], S[9:10])
w wish you u

Slicing is a particular form of indexing more akin to parsing where you analyze the structure.

Python once again creates a new object containing the contiguous section identified by the offset pair.  It is important to note the left offset is taken to be the inclusive lower bound and the right is the non-inclusive upper bound. The inclusive definition is important here:  Including the endpoints of an interval. For example, “the interval from 1 to 2, inclusive” means the closed interval written [1, 2].  This means Python fetches all items from the lower bound up to but not including the upper bound. 

What about changing a string?

Let’s try it:

S = "i wish you water"
S[0] = "x"
---------------------------------------------------------------------------
TypeError Traceback (most recent call last) <ipython-input-67-a6fd56571822> 
in <module> 1 S = "i wish you water" ----> 2 S[0] = "x"
TypeError: 'str' object does not support item assignment

Ok, what just happened?  Well, remember the word immutable? You cannot change it in place.

To change a string you need to create a new one through various methods.  In the current case we will use a combination of concatenation, indexing, and slicing to bring it all together:

S = "i wish you water"
S = 'x ' + S[2]  +  S[3:17]
print (S)
x wish you water

This brings us to methods.

Stings in Python provide a set of methods that implements much more complex text processing.  Just like in other languages a method or function takes parameters and returns a value. A “method” is a specific type of function: it must be part of a “class”, so has access to the class’ member variables. A function is usually discrete and all variables must be passed into the function.

Given the previous example there is a replace method:

S = "i wish you water"
S = S.replace ('i wish you water', 'x wish you water')
print (S)
x wish you water

Let’s try some other methods;

# captialize the first letter in a string:
S = "i wish you water"
S.capitalize()
'I wish you water'

# capitalize all the letters in a string:
S = "i wish you water"
S.upper()
'I WISH YOU WATER'

# check if the string is a digit:
S = "i wish you water"
S.isdigit()
False

# check it again:
S = "999"
S.isdigit()
TRUE

# strip trailing spaces in a string:
S = "i wish you water     "
x = S.rstrip()
print("of all fruits", x, "is my favorite") 
of all fruits i wish you water is my favorite

The list is seemingly endless.  

One more caveat emptor you should use stings methods, not the original string module that was deprecated in Python 3.0

We could in fact write multiple chapters on strings by themselves.  However, this is supposed to be a little nibble of what the Snake language can offer.  We have added the reference that we used to make this blog at the end.  I believe it is one of the best books out there for learning Python.

Until Then,

#iwishyouwater

Tctjr

References:

Learning Python by Mark Lutz

Muzak To Blog By:  Mr. Robot Vol1 Original Television Soundtrack

Snake_Byte[2]: Comparisons and Equality

Contrariwise, continued Tweedledee, if it was so, it might be, and if it were so, it would be; but as it isn’t, it ain’t. That’s logic!

TweedleDee
Algebra, trigonometry and mathematical logic lessons by Janetvr | Fiverr
It’s all rational isn’t it?

First, i trust everyone is safe.

Second, i am going to be pushing a blog out every Wednesday called Snake_Bytes.  This is the second one hot off the press.  Snake as in Python and Bytes as in well you get it. Yes, it is a bad pun but hey most are bad. 

i will pick one of the myriads of python based books i have in my library and randomly open it to a page.  No matter how basic or advanced i will start from there and i will create a short concise blog on said subject.  For some possibly many the content will be rather pedantic for others i hope you gain a little insight.  As a former professor told me “to know a subject in many ways is to know it well.”  Just like martial arts or music performing the basics hopefully makes everything else effortless at some point.

Ok so in today’s installment we have Comparison and Equality.

I suppose more philosophically what is the Truth?

All Python objects at some level respond to some form of comparisons such as a test for equality or a magnitude comparison or even binary TRUE and FALSE.

For all comparisons in Python, the language traverses all parts of compound objects until a result can be ascertained and this includes nested objects and data structures.  The traversal for data structures is applied recursively from left to right.  

So let us jump into some simple snippets there starting with lists objects.  

List objects compare all of their components automatically.

%system #command line majik in Jupyterlab
# same value with unique objects
A1 = [2, (‘b’, 3)] 
A2 = [2, (‘b’, 3)]

#Are they equivalent?  Same Objects?
A1 == A2, A1 is A2
(True, False)

 So what happened here?  A1 and A2 are assigned lists which in fact are equivalent but distinct objects.  

So for comparisons how does that work?

  •  The ==  tests value equivalence

Python recursively tests nested comparisons until a result is ascertained.

  • The is operator tests object identity

Python tests whether the two are really the same object and live at the same address in memory.

So let’s compare some strings, shall we?

StringThing1 = "water"
StringThing2 = "water"
StringThing1 == StringThing2, StringThing1 is StringThing2
(True, True)

Ok, what just happened?  We need to be very careful here and i have seen this cause some really ugly bugs when performing long-chained regex stuff with health data.  Python internally caches and reuses some strings as an optimization technique.  Here there is really just a single string ‘water’ in memory shared by S1, S2 thus the identity operator evaluates to True.

The workaround is thus:

StringThing1 = "i wish you water"
StringThing2 = "i wish you water"
StringThing1 == StringThing2,StringThing1 is StringThing2
(True, False)

Given the logic of this lets see how we have conditional logic comparisons.

I believe Python 2.5 introduced ternary operators.  Once again interesting word:

Ternary operators ternary means composed of three parts or three as a base.

The operators are the fabled if/else you see in almost all programming languages.

Whentrue if condition else whenfalse

The condition is evaluated first.  If condition is true the result is whentrue; otherwise the result is whenfalse.  Only one of the two subexpressions whentrue and whenfalse evaluates depending on the truth value of condition.

Stylistically you want to palace parentheses around the whole expression.

Example of operator this was taken directly out the Python docs with a slight change as i thought it was funny:

is_nice = True
state = "nice" if is_nice else "ain’t nice"
print(state)

Which also shows how Python treats True and False.

In most programming languages an integer 0 is FALSE and an integer 1 is TRUE.

However, Python looks at an empty data structure as False.  True and False as illustrated above are inherent properties of every object in Python.

So in general Python compares types as follows:

  • Numbers are compared by the relative magnitude
  • Non-numeric mixed types comparisons where ( 3 < ‘water’) doesn’t fly in Python 3.0  However they are allowed in Python 2.6 where they use a fixed arbitrary rule.  Same with sorts non-numeric mixed type collections cannot be sorted in Python 3.0
  • Strings are compared lexicographically (ok cool word what does it mean?). Iin mathematics, the lexicographic or lexicographical order is a generalization of the alphabetical order of the dictionaries to sequences of ordered symbols or, more generally, of elements of a totally ordered set. In other words like a dictionary. Character by character where (“abc” < “ac”)
  • Lists and tuples are compared component by component left to right
  • Dictionaries are compared as equal if their sorted (key, value) lists are equal.  However relative magnitude comparisons are not supported in Python 3.0

With structured objects as one would think the comparison happens as though you had written the objects as literal and compared all the components one at a time left to right.  

Further, you can chain the comparisons such as:

a < b <= c < d

Which functionally is the same thing as:

a < b and b <= c and c < d

The chain form is more compact and more readable and evaluates each subexpression once at the most.

Being that most reading this should be using Python 3.0 a couple of words on dictionaries per the last commentary.  In Python 2.6 dictionaries supported magnitude comparisons as though you were comparing (key,value) lists.

In Python 3.0 magnitude comparisons for dictionaries are removed because they incur too much overhead when performing equality computations.  Python 3.0 from what i can gather uses an in-optimized scheme for equality comparisons.  So you write loops or compare them manually.  Once again no free lunch. The documentation can be found here: Ordering Comparisons in Python 3.0.

One last thing.  There is a special object called None.  It’s a special data type in Python in fact i think the only special data type.  None is equivalent to a Null pointer in C.  

This comes in handy if your list size is not known:

MyList = [None] * 50
Print (MyList)
[None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None]

The output makes me think of a Monty Python skit. See what I did there? While the comparison to a NULL pointer is correct the way in which it allocates memory and doesn’t limit the size of the list it allocates presets an initial size to allow for future indexing assignments. In this way, it kind of reminds me of malloc in C.  Purist please don’t shoot the messenger. 

Well, i got a little long in the tooth as they say.  See what i did again?  Teeth, Snakes and Python.

See y’all next week.

Until Then,

#iwishyouwater

@tctjr

Muzak To Blog By: various tunes by : Pink Martini, Pixies, Steve Miller.

Snake_Byte[1]_PyForest

The joy of coding Python should be in seeing short, concise, readable classes that express a lot of action in a small amount of clear code — not in reams of trivial code that bores the reader to death.

Guido van Rossum

Hi all first always i trust everyone is doing well and safe.

Second i had started writing another blog on some first principles design issues in machine learning but this morning while i was just browsing i came across a python library called Pyforest. Pyforest claims to have 99% of your import library woes solved.

At one of my previous companies, we created this flow from the time you walk in get your rig and sit down you have access to a superpack.tar.gz with all of the necessary python dependencies in fact even any bash scripts that you might need once you got your rig to start doing PRs the same day you started work.  This was pre-anaconda days so it worked well then most moved over to dependency management via anaconda.  However, this didn’t solve one of the main issues.  What when and how do you import?

i am sure if you are like me i keep the proverbial “untitled.ipynb” sitting around just for a notepad of sorts for the main imports (just don’t click and press X accidentally!).

Which is where pyforest comes into the reptilian purview.

The github is funny it says:

pyforest – feel the bliss of automated imports.”

Then it goes on to say:

“Writing the same imports over and over again is below your capacity. Let pyforest do the job for you.”

Being this isn’t supposed to be tl;dr blog (only a little nibble from a reptile) lets get started.

Installation:

You need to have python version 3.6 or above.  The github is once again funny (we like f-strings).  

So first make sure you are in your venv. 

 python3 --version
 pip install --upgrade pyforest
 python -m pyforest install_extensions 

Low and behold: 

Downloading pyforest-1.0.3.tar.gz

Needless to say i was skeptical.  

Questions – autocomplete? Stomping on variables?  Grinding to a halt because maybe import *?

Nope. Here is proof:

Ok nice parlor trick.

Lets try plotting something because i always space out and just type plt:

Ok now you have my attention.

i then tried a simple linear regression with sklearn

So this library definitely saves you time and the folks over at bamboolib have a great sense of humor which i really appreciate.

You can check to see a list of imported libraries dir(pyforest) kinda like a micro pip freeze.

Here is the github: pyforest github.

+1 for my recommendation.

until then,

#iwishyouwater

@tctjr

Muzak To Blog To: Cold Fact by Rodriguez 

Fwiw if you get a chance watch “Searching For Sugarman” which is a documentary about Rodriguez.  Astounding.