SEARCH

Enter your search query in the box above ^, or use the forum search tool.

You are not logged in.

#51 2013-06-05 08:25:10

savalaserg
#! Member
Registered: 2013-05-15
Posts: 91

Re: Baby's First Programming, (In Python)

FYI the stringmancing for the lazy example that you gave makes alot more sense .... lol

Offline

Help fund CrunchBang, donate to the project!

#52 2013-06-05 08:39:55

DebianJoe
#! Code Whisperer
From: The Bleeding Edge
Registered: 2013-03-13
Posts: 1,207
Website

Re: Baby's First Programming, (In Python)

I perhaps shouldn't do this, but I "might" (and that means certainly will) do things wrong that will still compile and run to bring up questions.  I'm putting WAY more thought into this than is probably acceptable, but when I took my first class on Python, I had my formatting torn apart.  I would set up equations, x = (11+2+(11*9)) because I came from C++ and I love me some parenthesis.

Ironically (and I had incorrectly banked on it) Zalew caught the fact that I totally went overboard on my "len" function, but didn't catch that I was using an index on a string that is doing nothing at all because of how I called it.  x[-1:-2] should be totally removed from my above code, as it doesn't do anything other than take up space.  Had I called it using x[-2:-1] then it would would have given real output.  As it stands, removing it would still give you the same output.

Look carefully at the string "I am a stringmancer".  Remembering to count spaces and to start with the number 0, let's count what range we pull out at first (I'll use underscores to take the place of spaces). 
0=="I", 1=="_", 2=="a", 3=="m", 4=="_", 5=="a", 6=="_", 7=="s", 8=="t", 9=="r", 10=="i", 11=="n", 12=="g", 13=="m", 14=="a"
15=="n", 16=="c", 17=="e", 18=="r"

So, if the first call to x, which equal "I am a stringmancer", requests numbers 7 up to but NOT INCLUDING 13.  We get "string."  The next part of that statement is what I'm talking about above....it doesn't do a damn thing as far as output, but it ALSO doesn't throw an error.  Then we add str(n) to it, which is just the "!"  So we get "string!"

The next part is cutting out a section INSIDE of our first cut.  We're taking the same "I am a stringmancer" and using a range [7:17] taking numbers 7, 8, 9, 10, 11, 12, 13, 14, 15, 16.  Then the next part of it [10:13] grabs numbers 10, 11, 12 and appends them to the end of our first section.

Use the numbered chart above, we get from the string a section that would read [7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 10, 11, 12].  Then we add the "n-string" back to the end, putting an exclamation point there to let everyone know that we're pumped. big_smile

Is that making sense?  We won't move on until it sinks in, because indexing is too valuable to not get.

Offline

#53 2013-06-05 09:02:15

savalaserg
#! Member
Registered: 2013-05-15
Posts: 91

Re: Baby's First Programming, (In Python)

I guess it makes sence I guess but how does print x + n equal I am a stringmancer ?
Why not just x = " I am a stringmancer" and just index from that ? like IE I just wrote this it makes more sense to me I guess....
x = "I am a stringmancer"
print x[0:1]+ x[2:4] + x[5:6] +x[7:19]

I guess I do not understand why all the characters in defining the variables and how they are pulled ? IE
x = "%s a %s" % (a, m)
or a = "%s am" % i
How does that mean I am a stringmancer ? what does %s mean or the a or the (a, m). Just really confusing to me. When I write it like  I did above it makes more sense to  me granted its more work. Also by all means dont let me hold up the class I have a tendency of banging my head against things and them finally making sense after the 100th time lol.

Last edited by savalaserg (2013-06-05 09:07:58)

Offline

#54 2013-06-05 09:14:04

DebianJoe
#! Code Whisperer
From: The Bleeding Edge
Registered: 2013-03-13
Posts: 1,207
Website

Re: Baby's First Programming, (In Python)

The "n" is the exclamation point.  That's all it is.

The extreme use of nested strings is the reason that I tend to shy away from using substitutions most of the time.  I'll step you through it:

i = "I"  (So now, i = a capital letter I)
n = "!" (n is an exclamation point)
a = "%s am" % i (I've substituted the value of i [which is a capital letter I] into a new string and appended the characters "_am" where the underscore is a space.  Now, "a" is the equivalent of the phrase "I am"
m = "stringmancer" (this one should be obvious)
x = "%s a %s" % (a, m) x = {str(a) + "_a_" str(m)}  Since str(a) == "I am", and str(m) == "stringmancer" we've created the final str(x) to be the entire phrase, "I am a stringmancer". 

If I wrote

cat = "cat"
dog = "dog"

pets = "I have a %s and a %s as pets." % (cat, dog)

   
I'd end up with the string pets being "I have a dog and a cat as pets."  This is the value of str(pets) from now on.  If I call a phrase like

answer = "Since you asked, %s" % pets

I would be setting the string answer to be "Since you asked, I have a dog and a cat as pets."

I would never actually construct nested strings in the manner shown at the beginning of the example, but I personally believe that the concepts are easier to understand when they make sentences rather than holding abstract constructs.  Change the values of the variables to longer strings to see how they're organized.

Check This example out, perhaps it'll help.

Last edited by DebianJoe (2013-06-05 09:17:22)

Offline

#55 2013-06-05 09:14:53

zalew
#! Junkie
From: Warsaw, .PL
Registered: 2012-03-28
Posts: 374

Re: Baby's First Programming, (In Python)

DebianJoe wrote:

Ironically (and I had incorrectly banked on it) Zalew caught the fact that I totally went overboard on my "len" function, but didn't catch that I was using an index on a string that is doing nothing at all because of how I called it.

the string just caught my attention because it was quoted in a shorter post wink

Offline

#56 2013-06-05 09:21:02

DebianJoe
#! Code Whisperer
From: The Bleeding Edge
Registered: 2013-03-13
Posts: 1,207
Website

Re: Baby's First Programming, (In Python)

zalew wrote:
DebianJoe wrote:

Ironically (and I had incorrectly banked on it) Zalew caught the fact that I totally went overboard on my "len" function, but didn't catch that I was using an index on a string that is doing nothing at all because of how I called it.

the string just caught my attention because it was quoted in a shorter post wink

Oh no, python friend, you've volunteered for the "catch Joe's sneaky tricks and correct his formatting"  position now.  You can't get out of it once you've started.  ]:D

Edit: I'd like to add that I most certainly WILL make unintentional mistakes too.  If you see me throw in a "cout>>" PLEASE speak up.  It comes with the job that I often will combine syntax and screw things up.  I will readily admit that I'm human and would rather have corrections made than to lead someone into doing things the wrong way.

That goes for EVERYONE!  If you think I'm doing something wrong, say so.

Last edited by DebianJoe (2013-06-05 09:24:34)

Offline

#57 2013-06-05 10:45:37

DebianJoe
#! Code Whisperer
From: The Bleeding Edge
Registered: 2013-03-13
Posts: 1,207
Website

Re: Baby's First Programming, (In Python)

More Stringmancy, incorporating built in classes.

I'm really nervous about taking this jump because I'm not sure that everyone is totally on board with how nesting strings and pulling ranges in strings works, so if I'm going too fast...then let me know.

My daughter recently got me to play Magic the Gathering with her.  Up until a few days ago, I knew that it existed, but was totally unaware how it worked.  She played a card that had its HP and Atk set by how many other of the same class of card were in play.

That is what caused this tangent to string control.  What if we wanted to know about the specific characters in a string?  Do we have enough power over our strings yet?  Could we really call ourselves stringmancers if we can't make them do EXACTLY what we want?

basic_string = "I am your humble minion."

print "Minion, how many times do you use 'i'?"
print basic_string.count('i')
print "What about 'I'?"
print basic_string.count('I')
print "I don't care about capitalization, give me ALL of them."
#but....'I' doesn't equal 'i' so, let's use a class with another variable:
new_string = basic_string.lower()
print new_string.count('i')

So, I cheated a bit here.  In all honesty, I cheated a lot!  We're using the built in classes for strings to first, start counting how many times a character (or phase, you can use phrases) shows up in a string.  The problem is that I didn't want ONLY the exact letter "i" but rather BOTH of the "i" & "I" characters.  So, I used the ".lower()" which is a call to an included string class (don't worry if that definition doesn't make sense yet...it will later) to change "basic_string" into an all lowercase version of itself now called "new_string" and performed the string.count('i') on our new string.

There is certainly more than one way to do this, so check out the Python 2 Documentation and give me a different way to do the same things. big_smile

Last edited by DebianJoe (2013-06-05 10:46:18)

Offline

#58 2013-06-05 13:48:46

savalaserg
#! Member
Registered: 2013-05-15
Posts: 91

Re: Baby's First Programming, (In Python)

You guys are good I am just gonna spend a little more time on strings lol.... practice makes perfect or perfect practice makes perfect lol.

Last edited by savalaserg (2013-06-05 13:49:31)

Offline

#59 2013-06-05 20:15:01

ze-hobbit
Member
Registered: 2009-07-09
Posts: 13
Website

Re: Baby's First Programming, (In Python)

DebianJoe wrote:

I'm really nervous about taking this jump because I'm not sure that everyone is totally on board with how nesting strings and pulling ranges in strings works, so if I'm going too fast...then let me know.

I'm on board and I'm enjoying the pace. I tried all the examples and cleared all the doubts. I nearly missed one hint though, in

a = "I am"
print a[2:4]

I thought that it included the four, but was out of reach, because

print a[2:2000] 

gave the same result. But the I saw the emphasis saying the its 2 to 4 not including the latter.

DebianJoe wrote:

There is certainly more than one way to do this, so check out the Python 2 Documentation and give me a different way to do the same things.

Sent a solution by private msg  O:)

Last edited by ze-hobbit (2013-06-05 20:23:46)

Offline

#60 2013-06-06 06:04:28

DebianJoe
#! Code Whisperer
From: The Bleeding Edge
Registered: 2013-03-13
Posts: 1,207
Website

Re: Baby's First Programming, (In Python)

Slices with "Ray Guns"

To try to finalize the subject of slicing strings, I've got one more example that might be of some use for what ze-hobbit was doing.  You can slice in what I'd call a "ray gun" style.  If you've ever watched old sci-fi movies, when someone shoots a ray gun, you have a point of origin, but the ray travels until it makes contact with something.  In geometry this is simply referred to  as a "ray."  So, let's use this concept for taking sections of strings:

string_one = "Got me a raygun. Got me an altitude."
print string_one[17:]
print string_one[:16]

This is a cool way to slice our string and grab ranges that we want from a certain point to either the beginning or the end of the string.  In the above example, we're going from position 17 until the end of the string, and then from the beginning to but NOT INCLUDING 16.

String Alchemy


We now know how to grab sections of strings, but could we use python alchemy to make them something totally different?  Sure we could.  Let's make up an example to see how this would work.  Let's say I have a string that holds the numerical data "375" and I am only concerned with the last two numbers of it.  Well, that's "75" and now that I can slice up my string to grab only that...I want to add another number to the "75" I pulled out of it.  The only caveat is that I don't want to simply concatenate the numbers because if I have a string "75" and add "38" if we're dealing with strings, I'll have "7538" as my output.  Well, I actually want to do math with them, so I need to take the "75" out of the string "375" then change it to being an integer so that I can do math with it again.

#First we make sure we're grabbing the right string section.

string_data = str(375)
print string_data[1:]

#Now, we perform string alchemy:
#We can turn that range into integers

integer_data = int(string_data[1:])
print integer_data + 38

So, by using the str(spam_and_eggs) formatting, we're using it as a string.  Assuming that the data fits, we can use int(spam_and_eggs) to treat it as an integer.  We don't have to stop there, though.  Let's make some changes to our test program.

#First we make sure we're grabbing the right string section.

string_data = str(375)
print string_data[1:]

#Now, we perform string alchemy:
#We can turn that range into integers

integer_data = int(string_data[1:])
print integer_data + 38

#Let's nest our string in an integer wrapper for fun
#and then use our "alchemy" to make it a float.
float_data = float(int(string_data[1:]))

print type(integer_data)
print type(string_data)
print float_data
print type(float_data)

#That was a little bit confusing, so let's go
# directly from a string to a float

print float(string_data[1:])
# ^^ that's MUCH cleaner.

The "type" function is useful if you can't remember how you've formatted a variable and need to know how your python compiler is seeing it.  You give the type(foo) to have it tell you if it's seeing the variable "foo" as a str (string), int (integer), float (uhhh....float), etc.

Offline

#61 2013-06-06 06:40:58

DebianJoe
#! Code Whisperer
From: The Bleeding Edge
Registered: 2013-03-13
Posts: 1,207
Website

Re: Baby's First Programming, (In Python)

Numerology

I'm not going to try to convince anyone that there's great power to certain numbers, but rather I want you to understand where we might need to make formatting changes to our number data for the sake of applying it to our needs.  Let's look a bit closer at integers and their behavior first.

#let's make some variables.
x = 2
y = 2
z = 3

print x + y
print type(x+y)
#We know that we're working with integers

print (x + y) / z
#well, that's not very accurate, 

print float((x+y) / z)
#that's not really any better

print float(x+y) / float(z)
#That is science.

Integers are whole numbers.  So, we made (4/3==1), which would end up being a horrible way to attempt to balance your bank account.  So, by using only integers, we sacrifice some accuracy in mathematics.  Assuming that we're looking to be able to handle fractions of whole numbers, floats make for much more precise output.

In the above example, when I used print float((x+y) / z) you should pay special attention to the fact that the math is done BEFORE the conversion.  So, I end up with the INTEGER value of [(x + y) / z] and THEN give the output as a float.  In the bottom line, we turn the variables into floats BEFORE we do the division, which creates much more reliable output.

So, why would we ever need Integers if floats are more accurate?  Take a second to picture a grid that is 100x100 squares.  Assume that we cannot put something at a fraction of a square, but we want to get it relatively close.  This is where integers pay off.  Pixels are a great example of this in practical application.  You cannot make pixel (376.5, 678.25) on a computer screen red.  It doesn't work like that, or else resolution would be irrelevant.  Many GUI modules operate on the same principals.  There are many more reasons to use integers, but application will be the final determining factor for what formats we decide to use.

Offline

#62 2013-06-06 07:06:13

DebianJoe
#! Code Whisperer
From: The Bleeding Edge
Registered: 2013-03-13
Posts: 1,207
Website

Re: Baby's First Programming, (In Python)

Counterspells

(You guys have to  excuse the D&D analogies, but I'm having fun with them.)

A wizard that can only deal with certain predefined scenarios isn't a very good wizard at all.  A program that simply executes and ends (although really useful for many purposes) isn't very much fun.  Let's see about adding the most basic form of interaction with the user that we can.  Let's allow some "user input."

x = raw_input("Write me a short phrase! ")
print "That phrase is %s characters long." % len(x)
print "It contains the string: '%s'"  % x
print "The first letter of your string is: '%s'" % x[0]
print "The last letter of your string is: '%s'" % x[-1]

That's pretty cool, but we're still missing some preparation in the counterspell department.  Run this, but simply hit "Return" instead of entering any data at the prompt.  What happened?  We may need some more powerful wizardry to get around some of these issues, but for now, let's look at some other ways to take user input:

#this program won't work
y = raw_input("Give me a simple integer: ")
z = raw_input("Give me another one: ")
print "Adding them together we get %d" % int(y + z)
print "Subtracting them we get %d" % int(y - z)
print "If we multiply them we get %d" % int(y * z)
print "%s raised to the %s power is %d" % int(y, z, (y**z)) 

That sucked.  We are trying to do math with the strings that the user gave us.  So, we need to do some alchemy to make this work.

#An alchemist solution
y = int(raw_input("Give me a simple integer: "))
z = int(raw_input("Give me another one: "))
print "Adding them together we get %d" %  (y + z)
print "Subtracting them we get %d" % (y - z)
print "If we multiply them we get %d" % (y * z)
print "%s raised to the %s power is %d" % (y, z, (y**z)) 

Well, that should have been significantly more successful.  On the other hand, if you enter a letter into one of the prompts, what does the error read?  This is a good start, but we still have a long way to go before we are true masters of counterspells. wink

Offline

#63 2013-06-06 16:39:15

kbmonkey
#! Die Hard
From: South Africa
Registered: 2011-01-14
Posts: 879
Website

Re: Baby's First Programming, (In Python)

@savalaserg if you need more info on how string slicing works, you can read the Python tutorial on this subject. It really helps to enter the steps in your interactive interpreter, to see the values go in and your results come out is quite engaging.

For the rest, I'm going to show off just a little bit with this trick on how to reverse a string or list with slicing ;P

>>> words = 'hello, world!'
>>> words[::-1]
'!dlrow ,olleh'

Offline

#64 2013-06-06 16:53:58

savalaserg
#! Member
Registered: 2013-05-15
Posts: 91

Re: Baby's First Programming, (In Python)

kbmonkey wrote:

@savalaserg if you need more info on how string slicing works, you can read the Python tutorial on this subject. It really helps to enter the steps in your interactive interpreter, to see the values go in and your results come out is quite engaging.

For the rest, I'm going to show off just a little bit with this trick on how to reverse a string or list with slicing ;P

>>> words = 'hello, world!'
>>> words[::-1]
'!dlrow ,olleh'

Will do thanks man....

Offline

#65 2013-06-07 06:08:30

DebianJoe
#! Code Whisperer
From: The Bleeding Edge
Registered: 2013-03-13
Posts: 1,207
Website

Re: Baby's First Programming, (In Python)

Conditional Computation Core Curriculum.

As our stringmancy has evolved into alchemy things went in an expected manner.  The problem is that in order to be successful, the wizard must be able to adapt to their environment.  If we can only do things under perfect conditions, then we quickly find ourselves stuck with unexpected crashes, errors, and users that just won't do what's expected.

We need to be able to at least handle some conditions that we can't predict.

#Basic If/Elif/Else 

x = raw_input("Enter a number from 1 to 3 ")
if x == "1":
	print "You entered the number one"
elif x == "2":
	print "You entered the number two."
elif x == "3":
	print "You entered the number three."
else:
	print "You didn't follow the rules."

So, we've given the user some options...but included a "catch-all" else statement at the end in the case that the user's input doesn't match any of our expected results.  Pretty cool, right?  I'll admit that this is pretty boring at first, but you can honestly take if-elif-else statements and do some very impressive work without getting much more advanced.  Now, there are often MUCH shorter ways to get the final result, but this is the most basic of relay-type logic.  Let's look at nesting conditional statements to catch multiple conditions.

#A bit less Basic If/Elif/Else 

x = raw_input("Enter a number from 1 to 99 ~>")
if int(x) > 50 and int(x) < 99 and int(x) > 0:
	if int(x) % 2 == 0:
		print "Your number is larger than 50 and even."
	else:
		print "Your number is larger than 50 and odd."
elif int(x) <= 50 and int(x) > 0:
	if int(x) % 2 == 0:
		print "Your number is smaller than 50 and even"
	else:
		print "Your number is smaller than 50 and odd."
else:
	print "You didn't follow the rules, again!"

Obviously, with us already having made the statement that we shouldn't exceed 79 characters per line, and since we MUST indent the code to be executed from the conditional statement...we should probably not define our style with nothing but nesting if/elif/else on top of if/elif/else on top of if/elif/else etc.  Pretty soon, our indents would be over 79 characters long.  On the other hand, you will see these little guys used a lot, so get comfortable with how they work.

Bonus Variable Stringmancing Wizardry.

Having our output in the terminal can be boring, so what do we do to "spice it up?"  There's an old-school way to get colors into our terminal programs using "ANSI escape sequences."  I won't go into all of the details of how they work, but it's enough to know that they're a series of characters that aren't printed out as text, even though they can be used in string format.  What they do is set the terminal switches for different behavior ON or OFF and then continue whatever our program is set to do.  In the case of our above program, we could set a few variables tied to strings with the escape sequences inside of them, and then use the string substitution methods we've looked at previously to insert them.  I think that everyone that uses Unix based systems should have at least a few of these memorized (like the basic 16 colors) because they're a nice way to hack out some extra functionality in cli programs as long as your terminal supports ANSI escapes.  Most terminals do.

#ANSI Escape Stringmancing

red = "\033[1;31m"
green = "\033[1;32m"
reset = "\033[1;m"
x = raw_input("Enter a number from 1 to 99 ~>")

if int(x) > 50 and int(x) < 99 and int(x) > 0:
	if int(x) % 2 == 0:
		print "Your number is %slarger%s than 50 and %seven%s." % (
		red, reset, green, reset)
	else:
		print "Your number is %slarger%s than 50 and %sodd%s." % (
		red, reset, green, reset)
elif int(x) <= 50 and int(x) > 0:
	if int(x) % 2 == 0:
		print "Your number is %ssmaller%s than 50 and %seven%s" % (
		red, reset, green, reset)
	else:
		print "Your number is %ssmaller%s than 50 and %sodd%s." % (
		red, reset, green, reset)
else:
	print "%sYou didn't follow the rules, again!%s" % (red, reset)

Edit:  Also, I noticed that I didn't include 99 in the above code.  I should have used "<=" rather than just "<".  Also, if you don't totally get ANSI escapes, don't fret too much.  They're simply icing on the cake that you can use for extra control.  Feel free to read up on them, but realize that I probably won't go into the exact details of "how" they work because I don't want to melt anyone's brain through overloads.  It's far more important for our purposes to understand how we're inserting them and how if/elif/else works.

Last edited by DebianJoe (2013-06-07 06:17:52)

Offline

#66 2013-06-07 18:46:49

ze-hobbit
Member
Registered: 2009-07-09
Posts: 13
Website

Re: Baby's First Programming, (In Python)

kbmonkey wrote:

For the rest, I'm going to show off just a little bit with this trick on how to reverse a string or list with slicing ;P

>>> words = 'hello, world!'
>>> words[::-1]
'!dlrow ,olleh'

Nice! I was trying by trial and error to make a selection of only like the pair values, or all the entries step 2, without success

string[1:2]
string[1:2:10]
string[:2]

And now ith your example I finally could do it by subsitution "-1" with 2

string[::2]

This now returned only the pair values. [0, 2, 4, 6...] smile

Offline

#67 2013-06-07 18:56:48

DebianJoe
#! Code Whisperer
From: The Bleeding Edge
Registered: 2013-03-13
Posts: 1,207
Website

Re: Baby's First Programming, (In Python)

The third figure in the slice we haven't covered yet, but it's a unit of step progression.  Read more here: Extended Slices

Thanks for sharing KBMonkey.

Last edited by DebianJoe (2013-06-07 18:57:11)

Offline

#68 2013-06-07 23:42:07

kbmonkey
#! Die Hard
From: South Africa
Registered: 2011-01-14
Posts: 879
Website

Re: Baby's First Programming, (In Python)

I guess I got excited there DebianJoe, I will wait in the future to avoid spoilers  :8

Offline

#69 2013-06-08 04:07:44

DebianJoe
#! Code Whisperer
From: The Bleeding Edge
Registered: 2013-03-13
Posts: 1,207
Website

Re: Baby's First Programming, (In Python)

Nah, it's perfectly cool.  All I ask is that if you have a cool trick that you explain how it works so that if someone doesn't understand it immediately, that they can hopefully add it to their "spellbook." wink

Offline

#70 2013-06-08 07:59:09

DebianJoe
#! Code Whisperer
From: The Bleeding Edge
Registered: 2013-03-13
Posts: 1,207
Website

Re: Baby's First Programming, (In Python)

A Shortish Discussion on Escapes that Serve Us

In the last of the examples I posted we used escape codes to colorize our text.  While that's a neat way to liven up our regular terminal output, it's not all of what we can do with escapes.  We've looked previously at shifting up single and double quotations for the sake of actually getting quotations in our output, but what do we do if we want both single and double quotes inside of the output strings?  This is one of the things that escape codes can help us with.
What we want to do:

x = "I want to put "all" of the quotations in this line's output"
print x

If you look at this line, it is going to stop reading the string after "put " because the first quotation mark will be matched to the one that we used after 'x =' so our string ends up being "I want to put " and the word 'all' becomes an operator instead of being part of the string.  Expect a syntax error.  If you try to simply use single quotes ( ' ' ) the string closes out after the word "line" because our apostrophe is actually a single quote.  So to fix it we could use escapes:

x = "I want to put \"all\" of the quotations in this line's output"
print x

This one should do exactly what we're after.  Python supports a few different escapes that can really save us a lot of trouble in trying to get formatting of strings to work like we'd want them to.  The ones that I personally use most often are \t \n \" \\ and \', but there is more that's in the python documentation.

Let's see what some of these do by violating normal formatting rules in a string and using escapes to make it look right in the output:

print "\tWe can tab lines\n and \"break\" them\n however we like."
print "If we needed to, we could show a Windows user"
print "how thier directory structure looks\n\t C:\\program_files."

Pay special attention to the use of the double-backslash to get a single one in the output in the last line.  If you're working with echoing some borne-again styled commands and need to output a backslash you don't want python to treat it as the beginning of an escape sequence. 

When I first started out with these, there was a fun little script that was like:

while not False:
    for unit in ["/","-","|","\\","|"]:
        print "%s\r" % unit,

To show the double-backslash in action.  If you try it, use 'Ctrl + c' to interrupt the loop with your keyboard. 

Writing Huge Strings

Every now and again, you'll need to write a novel inside of a string.  Breaking it up into hundreds of (print "this part" print "that part") lines is tedious and annoying.  You can use a triple-single or triple-double quote to get around this little annoyance:

x = """
in a galaxy \nfar\n\tfar\n away

wait a minute....I don't NEED escapes for this:


A long time ago, 
	in a galaxy far, far away

It is a period of civil war. Rebel 
  spaceships, striking from a hidden 
  base, have won their first victory 
  against the evil Galactic Empire. 
During the battle, Rebel spies managed 
  to steal secret plans to the Empire's 
  ultimate weapon, the Death Star, an 
  armored space station with enough 
  power to destroy an entire planet. 
Pursued by the Empire's sinister agents, 
  Princess Leia races home aboard her 
  starship, custodian of the stolen plans 
  that can save her people and restore 
  freedom to the galaxy.... 
"""
print x

Offline

#71 2013-06-08 10:50:13

DebianJoe
#! Code Whisperer
From: The Bleeding Edge
Registered: 2013-03-13
Posts: 1,207
Website

Re: Baby's First Programming, (In Python)

You Spin Me Right 'round Baby Right 'round - Loops

It seems like we've used some loops in examples, but we've not really looked at them in detail.  We should probably do that.  A loop is a section of code that repeats as long as whatever qualifiers define it are true.  That's sounds far worse than it is, so let's just look at a mega-simple example of a "While" loop.

the_variable = 0
while the_variable <= 10:
	print "The current index is %s" % (the_variable)
	the_variable = the_variable + 1
print "We done now."

I would normally write "the_variable = the_variable + 1" as "the_variable += 1" which does the exact same thing, and takes less time to type.  On the other hand, this may make more sense at first.  What we're doing is simply executing the indented code until the statement "the_variable <= 10" is true.  Once the_variable exceeds 10...we roll on with the rest of the code.

That was pretty simple, right?  Let's try a "for" loop.  Which will perform the indented code 1 time "for" each object that we address it to.

x = "CRUNCHBANG"
y = 1
for chr in x:
	print "%s letter" % y
	y += 1

I don't like that example very much.  If someone said to me, "I got 4 letter!"  I'd assume they'd been in the boxing profession for a bit too long.  Let's use some if/else comparison to properly format our grammar.

x = "CRUNCHBANG"
y = 1
for chr in x:
	if y == 1:
		print "%s letter" % y
	else:
		print "%s letters" % y	
	y += 1

That's better, but I bet we can squeeze a bit more functionality out of our very fancy program:

x = "CRUNCHBANG"
y = 1
for chr in x:
	print "Our number %s letter is %s" % (y, x[ y - 1])
	y += 1

Well, that's lots cooler.  Now we've got a counter that reads out our letters and numbers them in a way that we'd traditionally count them.  I want you to pay close attention to the fact that I'm indexing our string "CRUNCHBANG" by our Count - 1.  You remember why, right?  Because we're supposed to start counting with 0, not 1.  So, if I had set it up to print "x[y]" we would have ended up with it starting at position "y", which we set to the number 1 before our loop.  This would have given us "RUNCHBANG....crash" because there isn't a 10th position in our string.

You can also use "While not" to check for the opposite of a condition, or "While + and/or" to check for multiple variables.  We'll certainly get to doing some of that, and I've been known to nest a short program that I want repeated by setting a variable to 1 and then running everything under a "while variable == 0."  That's a shoddy way to do it, but it will technically work in a pinch.

Let's look at the age old "Fizzbuzz" which we should be able to do by now.  The purpose of a Fizzbuzz is that it was (and I guess still is in some places) a technique to determine if someone actually knew what they said on their resume.  (You know, like on mine where it says that I worked from 2000-present as Mr. Olympia and used the proceeds from my sponsorship to fund cancer research and volunteered at a soup-kitchen when I wasn't modeling.)  It's a sad world where employers don't just trust that we told the perfect truth about our credentials, but even as early into the language as we are, we should be able to pull this off.

The basic idea is that you should print all of the numbers from 1 to 100, replacing numbers that are divisible by 3 with the word "fizz" and numbers divisible by 5 with the word "buzz."  If a number is divisible by both 3 & 5, then print out "Fizzbuzz."  Let's do that with some simple loops and if/elif/else statements.

count = 0
while count < 101:
    if count % 5 == 0 and count % 3 == 0:
        print "FizzBuzz"
    elif count % 3 == 0:
        print "Fizz"
    elif count % 5 == 0:
        print "Buzz"
    else:
        print count

    count = count + 1

Pretty easy, right?  If the prospective employer is a manager, you've just proven that you "know" python to them.  On the other hand, let's assume for a second that management has finally forgiven me for telling the last guy that we interviewed that we didn't need him because he made some statement about how "Macs are better than PC's" and they've asked me (or another coder) to see your work.  We're going to comment that you've done fine, but would like to see the same code done in 10 or less "precise" lines.  This comes from the fact that instead of doing real work, we let the Fizzbuzz become a work of philosophy and are always trying to come up with more efficient ways to do the exact same thing.  Let's see how we could do it with 7 lines.

for num in xrange(1,101):
    msg = ''
    if num % 3 == 0:
        msg += 'Fizz'
    if num % 5 == 0:
        msg += 'Buzz'
    print msg or num

Now, that's nice.  It can be done in less, but we won't go into that yet.  I used a new trick here, the "xrange" function.  Read more about it in (you guessed it) The Python Documentation.

Offline

#72 2013-06-08 11:03:09

DebianJoe
#! Code Whisperer
From: The Bleeding Edge
Registered: 2013-03-13
Posts: 1,207
Website

Re: Baby's First Programming, (In Python)

Also, before I let KBMonkey get away with showing 1 more cool way to use the same functions (I want him to have to work harder to show off cool stuff.)  Let's do the above Fizzbuzz backwards but only with odd numbers.  ]:D

for num in xrange(101,1,-2):
    msg = ''
    if num % 3 == 0:
        msg += 'Fizz'
    if num % 5 == 0:
        msg += 'Buzz'
    print msg or num

Offline

#73 2013-06-08 18:48:49

kbmonkey
#! Die Hard
From: South Africa
Registered: 2011-01-14
Posts: 879
Website

Re: Baby's First Programming, (In Python)

^ Is that a challenge DebianJoe?  lol  not to worry, I will wait until you get to <spoiler redacted> 8o

I never used ANSI escape codes in python to output color before - thanks for that!

I'm going to have to start keeping a spell book of scripts, after all what is a wizard without something to cast!

Offline

#74 2013-06-08 19:23:53

DebianJoe
#! Code Whisperer
From: The Bleeding Edge
Registered: 2013-03-13
Posts: 1,207
Website

Re: Baby's First Programming, (In Python)

I've really appreciated your input and tricks!  Break out that spell-book so that we can all benefit from it.  We may have wizard duels later on, but for now it's all about everyone learning from everyone else.

If that's not the spirit of "free and open" then I don't know what would be.  Glad to see you picked up anything at all.

Offline

Help fund CrunchBang, donate to the project!

#75 2013-06-09 06:41:46

DebianJoe
#! Code Whisperer
From: The Bleeding Edge
Registered: 2013-03-13
Posts: 1,207
Website

Re: Baby's First Programming, (In Python)

Repetitive Spell Management - Functions

I watched the Harry Potter movies, and even though I don't really consider that the kind of wizard I'd picture when we talk about wizards (all wizards should have long beard or be girls) there are some concepts there that apply to what we're doing very well.

When someone in the Harry Potter world wants to pick something up, they have a "Wingardium Leviosa" spell that picks stuff up.  That's what it does, and that's all it does.  In the class, they use it to levitate feathers.  Later, I believe that it was Ron who did it, it was used on the club of a big troll.  I just looked it up because the internet is filled with people who REALLY care about Harry Potter spells, and it seems to also be used by Harry to hold himself up on a motorcycle, and to pick up a stick to poke a knot on a magical tree.

The spell is not important, and how many uses there are in the movies also aren't important, but what is important is that there is a spell that's designed to pick things up.  If you needed to pick things up a lot, this would be a spell that you'd be using all of the time.  If you were a noseless snake-wizard bent on ruling the world, you'd probably not use this as often as you would a spell that just kills people.  On the other hand, if you're killing people often, you don't want to have to think about each little step over and over: Use green lightning magic to take control of heart, use a squeeze technique, squeeze heart until it stops....I don't know how these things are supposed to work physically.  What I want to focus on is that if you're needing to go through a complicated procedure over and over, you'd probably want to sum it up in a simple "Avada Kedavra" and reuse this spell as often as needed.

The thing that my analogy isn't covering is that someone had to first figure out how to kill people with magic, or levitate objects.  Once it was done, though, he/she probably wanted to make it easily reusable.  This is how functions work.  We make a block of code that's reusable for whatever we may need it for.  Let's look at a mathmatical example instead of discussing theoretical applications in the wizard world.

Let's say we had a program where we needed to regularly tell the area of a triangle (the math function for this is .5*base*height...for those who've slept since Geometry 101.)  The problem is that we've got to figure LOTS of triangles, and we don't want to constantly go through and have to keep doing substitutions for numbers into a math equation for every instance.  Let's use a function to handle this.

def triangle_area(base, height): #header (colon at the end)
    area = (1 / 2) * base * height #body (must be indented)
    return area				#body (also indented)

This function is a simple way for us to take 2 arguments and use them repeatedly to figure the area of a triangle.  Note that I "define" the function with the call to "def" and then I give it a name.  Anything that's an acceptable variable name can also be used to name a function.  After defining "triangle_area" as a function, I put the two arguments that it will be using in parenthesis next to it.  When I go to call the function "triangle_area" I must pass these two variables to it or I'll end up with an error.  The section below the definition of my function is where I put the code that I want to be executed, and then at the end I put a "return" for what output I want to send back after the function is called.  Let's pass a few values into it to see how it works.

# computes the area of a triangle
def triangle_area(base, height):
	area = .5 * base * height
	return area					

print "Triangle areas"
print triangle_area(3, 8)
a2 = triangle_area(14, 2)
print a2

I did change my initial code a bit because there is something not quite right about "1/2" and I'll give you a hint (it's related to integers and floats.)  This example shows 2 different ways to get in information out of our function, but notice that both calls to it use the same syntax format <function_foo(spam , eggs)>, because that's what I told the function to expect.

Now that we've hopefully got a basic grasp of how a function should work, I want to go back and look at why the format for the first example is wrong.  It looks right at first glance: < (1/2) * base * height> SHOULD be equal to <.5 * base * height> right?  Well, we can use python to explain why it doesn't give you the same output.  I will go over this again and again because these are the things that will destroy you in troubleshooting a script if you miss them. 

# Python treats our function with Integers
def triangle_area(base, height):
	area = (1 / 2) * base * height
	return area					

a1 = triangle_area(3, 8)
print a1
print type(a1)

Notice that with the function that I used for the very first example, our output shows up as an integer.  Since a triangle with a (base, height) ratio of (3, 8) comes out as an even number, this might seem like an acceptable way to do it.  You'll see quickly from the output, though, that our function doesn't work at all.  What happens is that the (1/2) is in parenthesis and due to order of operations is the first thing that's done.  This is what we'd normally want, as we're using it to make a fraction BUT since python defaults to using integers we run across a stack-up of bad math.

print (1/2)

This equation gives us a value of "0" because 1 divided by two in integer format has the 0.5 dropped off and python says, "Meh, close enough" and gives us the 0 back.  Then, we multiply our base by zero, which is zero...and then we multiply our height by zero...which is zero.  So, now we've got a "0" for the answer to how much area is in our triangle.  Obviously, this cannot be right.

There are a few ways to correct this, and I'll give examples that will hopefully be self-explanatory.  If not, just ask.  This has been a really long entry and I should probably wrap it up:

def triangle_area(base, height):
    area = (float(1) / float(2)) * base * height
    return area

a1 = triangle_area (3, 8)
print a1
print type(a1)

or

def triangle_area(base, height):
    area = 0.5 * base * height
    return area

a1 = triangle_area (3, 8)
print a1
print type(a1)

Until later, happy spell casting. big_smile

Last edited by DebianJoe (2013-06-09 06:45:23)

Offline

Board footer

Powered by FluxBB

Copyright © 2012 CrunchBang Linux.
Proudly powered by Debian. Hosted by Linode.
Debian is a registered trademark of Software in the Public Interest, Inc.
Server: acrobat

Debian Logo