Open Side Menu Go to the Top

09-10-2011 , 01:37 AM
I downloaded Python3 the other day, and although I was irritated at first, I find I like it quote a bit. Here's my list of changes, but since I've only converted about 300 lines of code, my list is far from complete.

Here's an interesting thread from stack exchange. Apparently, the transition is following the core developers' predictions.

http://programmers.stackexchange.com...using-python-3

The first thing that is new, and quite interesting, in my opinion, is the change from ASCII to UTF-8. I guess this is a reaction to HTML5. I don't know about the workings, but apparently unicode conversion is no longer handled by Python, so instead of asking if you want to convert, the program implodes? So no dependable copy/paste?

The next thing is the forced implementation of new and not-so-new functions.

--print( );

So, yeah, this is the first shock you'll get when you try to run an old code on Python3. No longer print x and see an output. Not sure why they did this. The only thing I can think of is that they want to allow you to run functions and default arguments through print? Maybe it just looks pretty.

--print 'Hello, {0}, welcome to {1}. My name is {0} also.'.format(arg1, arg2)

I love this. I always felt that string functions were stupid and basically pointless in Python, so I seldom bothered to use them. This time, however, you can easily use multiple values, add default args, and reuse args multiple times in one sentence. Of course this also works in Python2, but I won't miss using %s.

-- input()

raw_input() is no longer valid.

--list()

There's a lot going on here, but 2 main points:

1- the shorthand ([statement]) no longer works.

2- This is more subtle, and a little hard to explain until you see your codes break, but Python3 forces you to use lists in many places you would normally use tuples. While I can ouput tuples, and even tuples in lists, I can't actually use tuples inside of functions any more. I'm not sure how I feel about this. I mean, if they want to add cdr'ing to Python, I'm fine with that, but don't straddle the fence on this stuff. They basically tossed out tuples since you (almost) can't use them in your code. An output is, by definition, immutable, so why would they bother keeping the syntax there?

I guess a fruity example is:

Code:
#this no longer works

def myFun(a, b):
    one = a
    two = b
    myVar = one, two
    return myVar

#so do this:

def myFun(a, b):
    one = a
    two = b
    myVar = list(one, two)
    return myVar
To see the inner working of a function with a print() statement:

Code:
def myFun(a, b):
    a += 1
    b += 1
    return a, b

def fun():
    a = 0
    b = 2
    c, d = myFun(a, b)
    print(c, d)
    return c, d

r = fun()
print(r)

#output:

1 3
(1, 3)

def myFun(a, b):
    a += 1
    b += 1
    return a, b

def fun():
    a = 0
    b = 2
    c = myFun(a, b)
    print (list(c))
    return c

r = fun()
print(r)

#output

[1, 3]
[1, 3]
-- No more default to integer division.

This one is simply confounding to me, and one that will most certainly deter programmers of math-heavy code. Instead of

>> 10/2
5

you get

>>10/2
5.0

Something sort of common:

Code:
#this throws an error because you can't range a float

x = y/z
for i in range(x):

#so....

x = int(y/z)
for i in range(x)
-- .sort no longer valid

use a = sorted(object) instead.

-- dictionary comprehensions went through a massive overhaul, which I'm sure is controversial to some people.

-- .iteritems no longer valid

use .items instead.

If you are observant:

Code:
#this is how it looks now

x = int(x/y)
for i in range(x):
    a = list(dictionary_object.items())
return a
There's many more changes that I haven't came across yet, but that is the gist of it so far. I like many of the changes, since some of the syntax is more explicit and more powerful. Other things seemed unnecessary, as if why not take things out syntactic sugar is gross.

Since I'll likely get asked "why" my only answer is "for the hell of it."
** Python Support Thread ** Quote
** Python Support Thread **
150% up to $2,000 Welcome Bonus on CoinPoker
Join the action now
Daily Rewards • Splash Pots • CoinRaces
** Python Support Thread **
09-19-2011 , 05:54 PM
Short question : Can you put functions inside dictionaries, or are they limited to values like strings and integers?
** Python Support Thread ** Quote
09-19-2011 , 06:28 PM
Yup. The beauty of python is that you can usually just try something and see if it works:


>>> def foo(a):
... print a
...
>>> d = {'a':foo}
>>> d['a']()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: foo() takes exactly 1 argument (0 given)
>>> d['a'](32)
32
** Python Support Thread ** Quote
09-19-2011 , 09:59 PM
It's python, you can do what ever you want.

Last edited by TheIrishThug; 09-19-2011 at 09:59 PM. Reason: Except use braces
** Python Support Thread ** Quote
09-25-2011 , 01:29 PM
Quote:
Originally Posted by MXdotCH
Hi,

I'm following the MIT course about Python and am trying to write a script that can find the 1000th prime number. I saw that daveT posted his code for it earlier but didn't really read as to end up copying it.

I was wondering if anyone can give me pointers, so far I got this:

primesFound = 0
number = 1

while primesFound < 1000:
int((number/2)*2) = x
if x == x:
primesFound + 1
number + 2

I don't know how to set what numbers I want it to test, 1 to (?). Also, don't know how to make it repeat the process for each number (or is that what the ''while primesFound < 1000 is for?).

Help is appreciated.
Im doing the same course, really good so far, finally taking the steps to learn programming.

Managed to solve the problem after awhile. Nothing seems to be more frustrating than programming, but it is even more satisfying to eventually solve a problem!
** Python Support Thread ** Quote
09-25-2011 , 10:30 PM
Quote:
Originally Posted by JackHighFlop
Short question : Can you put functions inside dictionaries, or are they limited to values like strings and integers?
You bet. Dictionaries are super useful data structures.

Code:
#----------------------------------------------------------------------
def muffins(ingredients):
    #make some muffins...
    return "muffins!"
#----------------------------------------------------------------------
def cake(ingredients):
    #make some cake
    return "cake!"   
#----------------------------------------------------------------------
def pie(ingredients):
    #make some pie...
    return "pie!"


food_functions ={
    'pie': pie,
    'cake':cake,
    'muffins':muffins,
}

def bake(what_to_bake,ingredients):
    return food_functions[what_to_bake](ingredients)


ingredients = ['apples','flour','eggs']
print bake('pie',ingredients)
print bake('muffins',ingredients)
** Python Support Thread ** Quote
10-05-2011 , 08:37 PM
Hey there,

I've just started to try to teach myself a little Python with *very* little previous programming experience (which mainly consisted of trying to program on a C64 about 30 yrs ago!), and to start myself off I decided to try to write a piece of code that could find the square root of a given number. I know there is a function that does this, but I thought it would be a good exercise.

My problem is I don't have a huge number of Python commands under my belt yet, and I don't think I am thinking about program structure correctly given the last language I was kinda familiar with was a very basic BASIC, where I pretty much spent my entire life using the FOR and IF statements.

I know this code is incredibly clumsy, and not in the least elegant, so if anybody could point me in the right direction toward making this leaner, less clumsy, and altogether more graceful, I'd really appreciate it!

Code:
# Successive approximation for finding the square root of variable 'a'

a=1000
b=a/2

print "Searching for the square root of",a,"......"

#iteratively halves variable b until the square is less than a

while b**2>a:
	print b, "is too large"
	b=b/2

if b**2==a:
	print b, "is the square root of", a
else:
	print b, "is too small. Refining......."
	print
	print
	
#stupid long-winded method for refining. I need to learn how to define functions or something. This seems *really* clumsy. This is how I thought about programming when I was 8 yrs old, and I haven't really developed beyond that it would seem. The general idea is once b^2<a then b starts to get incremented by a smaller amount until b^2>a, then it gets reverted to the previous value, and the increments begin again at a more granular level. The problem is that I can't currently figure out how to go about increasing the granularity of the refinement in a more elegant way.

while b**2 < a:
	b=b*1.1
if b**2 > a:
	b=b/1.1

while b**2 < a:
	b=b*1.01
if b**2 > a:
	b=b/1.01

while b**2 < a:
	b=b*1.001
if b**2 > a:
	b=b/1.001

while b**2 < a:
	b=b*1.0001
if b**2 > a:
	b=b/1.0001

while b**2 < a:
	b=b*1.00001

print "To no more than 3 significant digits, the square root of", a,"is", round(b,3)
print
print "*please note, the last digit is always rounded up."
** Python Support Thread ** Quote
10-06-2011 , 01:04 AM
It looks to me like you will find a few numbers that will create infinite loops, though I'm not certain what values would cause this, so I could be wrong.

There's a ton of algorithms for square roots. Heron's method is the most common introductory one afaik:

http://en.wikipedia.org/wiki/Methods...g_square_roots
** Python Support Thread ** Quote
10-06-2011 , 06:34 PM
Thanks for the link. I realised before embarking on this that there were probably plenty of effective algorithms for square roots, but as I was trying to get my brain working in a logcal and "programmatical" fashion I deliberately elected to ignore them and to see if I could figure out a way to do it myself

I know what I've come up with is far from optimal - not just the algorithm, but also the code seems somewhat clumsy to me. I think my next goal is to try to make the code better while using the same algorithm. There just *has* to be a better way of doing what I did without using all those "while" statements!

Regarding the infinite loops - I came across a lot of those the first time I tried to do this, but since I changed to this method I've had none so far. I added a variable to count the number of "refinements" that my code went through for any given variable, and I think the max it has needed so far is 40. However, you may well be right about the odd number causing an infinite loop, so I should probably set an upper limit on that count variable and force the code to stop once that limit has been hit!
** Python Support Thread ** Quote
10-07-2011 , 06:54 AM
First step is to acknowledge that your code only works for numbers >= 1. If a = 0.25 things don't work out so well in the first step.

As for the refinement, you can nest two loops to collapse the whiles down. This will also allow you to add an extra 'knob' to determine just how refined you want any given attempt to be.

I don't know python so I'll fake it based on your code. Consider this pseudocode:

Code:
d = 0.1
refinements = 5

for counter = 1 to refinements
    while b**2 < a:
	    b=b*(1 + d)
    if b**2 > a:
	b=b/(1 + d)
    d = d / 10
end for/loop
Hope that helps.
** Python Support Thread ** Quote
10-07-2011 , 07:02 AM
Doh! That's a ton more elegant - thank you!

You're also totally correct in that I should add some checks to ensure that a >= 1.

Thanks a ton for the help.
** Python Support Thread ** Quote
10-07-2011 , 11:53 AM
Tidied the code up a fair bit based on your suggestion - thank you!

Code:
# Successive approximation for finding the square root of variable 'a'

a=1000
b=a/2
count=0

while b**2>a:
	b=b/2
	#print b  #comment out if not needed for testing
	count=count+1

if b**2==a:
	print b
	 
else:
	delta=0.1
	refinements=13

	for count in range (1,refinements):	
		while b**2 < a:
			b=b*(1+delta)
			#print b  #comment out if not needed for testing
			count=count+1
		if b**2 > a:
			b=b/(1+delta)
			delta=delta/10
                        count=count+1

	print "sqrt of",a,"=",b
	#print "To no more than 3 significant digits, the square root of", a,"is", round(b,3)
	#print "This calculation required",count,"refinements." #comment out if not needed for testing
I've found that 13 seems to be the magic number of refinements for getting a 100% accurate sqrt on every number I've tested so far. Any less than that gets a close approximation, but 13 seems to nail it 100% every time.

Quick syntax question: I've been using "count=count+1" to increment that variable, but I know there's a shorthand way of doing this. I thought it was "count++" or "count+=1" but I get errors every time I try those. Am I just fudging the syntax?

Edit: duh, "count+=1" does work. I guess "count++" was where I was going wrong.

Next goal: convert from a stand-alone app to a function that can be called from either the command line or another application. Never done that before so this should be a voyage of discovery.

Last edited by Gazillion; 10-07-2011 at 12:14 PM.
** Python Support Thread ** Quote
10-07-2011 , 08:31 PM
No point trying to reinvent the sqrt wheel when your starting out. Programming offers many more interesting possibilities IMO. I guess you could try to create an individual code for each sqrt algorithm. I would think you'd learn more valuable things that way. I am not a master programmer by any means, but I think learning how to implement multiple solutions to divide and conquer problems is more valuable than trying to think of a sqrt implementation. If you use Newton and Herod, you can compare convergence and accuracy with large numbers where 13 trials is a little small.
** Python Support Thread ** Quote
10-08-2011 , 12:46 AM
Quote:
No point trying to reinvent the sqrt wheel when your starting out.
I strongly disagree with this sentiment.

In my opinion, when you are starting out programming, it doesn't matter what you're working on as long as you're working on something and enjoying it. The most important thing is that you are having fun no matter what problem you decide to tackle.

Writing your own square root finding algorithm, no matter how inefficient, seems like a fine choice to me to get your feet wet. You don't have to solve the halting problem in your first week back at coding.
** Python Support Thread ** Quote
10-08-2011 , 03:01 AM
Gazillion, if you're looking for new and interesting programming problems, try working through some of Project Euler. I just started on Project Euler tonight.

It's really cool to come up with an answer and then see how others have solved the same problem in the forum.
** Python Support Thread ** Quote
10-08-2011 , 08:16 AM
Thank you for all the feedback and support!

Flux, that link looks great! However, it's nothing more than a tantalizing promise for me right now as the problem page seems to be down, so I'm refreshing every few minutes in the hope that it's just temporary!

I've further refined my code - if it's against the spirit of the thread to keep posting updates please just tell me to stop and I'll quit with the updates, but I've defined my algorithm as a function and then written a simple user front end for the code. The one problem I'm trying to work out is something that appears when I enter testing mode by un-commenting lines 11, 26 and 34: with many solutions, as it reaches the end of the iteration/refinement cycle it appears to have already been in possession of the correct answer for a number of tries before it eventually stops. I tried to insert some checks in the for/while loops to break upon finding an exact match, but they didn't seem to work.

If anybody is up to the task of figuring out why it may be behaving like this, I'm all ears/eyes! :

Code:
def sqrt(arg):
	"""Successive approximation for finding the square root of a given number"""

	result=arg/2
	count=0

	#iteratively halves "result" until its square < "arg"
	while result**2>arg:
		result=result/2
		count+=1
		#print count, 0, result  #comment out if not needed for testing
		

	if result**2==arg:
		print result

	#refining process	 
	else:
		delta=0.1
		refinements=14

		for loop in range (1,refinements):	
			while result**2 < arg:
				result=result*(1+delta)
				count+=1
				#print count, loop, result  #comment out if not needed for testing				
			if result**2 > arg:
				result=result/(1+delta)
				delta=delta/10
				
		print result
		print
		#print "To no more than 3 significant digits, the square root of", arg,"is", round(result,3)
		#print "This calculation required",count,"refinements." #comment out if not needed for testing


#user interaction
value=1
while value != 0:
	value = float(raw_input("Enter a number to find the square root of (enter 0 to escape): "))
	if value < 0:
		 print "That is a negative number!"
	elif value == 0:
		 break
	else:
		sqrt (value)
** Python Support Thread ** Quote
10-08-2011 , 08:50 AM
+1 for Project Euler, it's full of maths questions to be solved like this: you come up with a brute force approach, find it just takes too long, then try to figure out the clever refinement. The problems page is down for me too but you can look at the problems directly like this: http://projecteuler.net/problem=2 (obviously change the =2 to whatever number you like).

I think your current problem is a good way to get back into coding as well.

Re why your code doesn't always work, perhaps it's because floating point arithmetic (i.e. calculations using numbers that are not integers) doesn't always work the way you expect. In particular, it's rarely a good idea to do a comparison like

Code:
if result**2==arg:
when you have floating-point numbers. When you tell Python to print a floating point number, it rounds it to some number of decimal places, so two numbers that look the same when printed may not compare equal. Here's a site that explains more.
** Python Support Thread ** Quote
10-08-2011 , 08:58 AM
Thanks RoundTower! To be honest, your explanation for why the checks may not be working had occurred to me as the likely culprit. I noticed that floats always seem to get rounded to about 12 decimal places, but when I print the returned value it is often a number of decimal places longer. However, if I test with arg=9 for example and un-comment the testing code, I will see a list of all the iterations it performs, with 3.0 being returned for maybe the last 6 or 7 iterations, which is what has been confusing me. If it was 3.000000000002 or something like that, I could understand what was happening, but as it is settling on 1 decimal place for a number of iterations, I'm getting perplexed.

Code:
if result**2==arg:
Was indeed the exact check I was using at 2 separate points within the nested loop, and I eneded up removing them as they basically did nothing, and I really think it is because I am dealing with floats. I tried to think of a way around it using my currently limited code vocabulary, and the only way I could think of doing so would be to temporarily convert the float to a different type like an int, but that way I would no doubt just end up with a ridiculous number of false positives.

It's not imperative that I use these checks given the speed of modern processors and how many computational cycles I have available to me, but I thought it would be good practise to try to make the algorithm as efficient as possible in advance of such a time when I'm doing things that are more computationally demanding.

I'll be scratching my head over that one for a while. In the mean time, the good news is Project Euler appears to be back up, so I'm going to start getting stuck into some of those problems

Last edited by Gazillion; 10-08-2011 at 09:05 AM.
** Python Support Thread ** Quote
10-08-2011 , 09:07 AM
Here's an example of what I mean:

Code:
Enter a number to find the square root of (enter 0 to escape): 9
1 0 2.25
2 1 2.475
3 1 2.7225
4 1 2.99475
5 1 3.294225
6 2 3.0246975
7 3 2.99774475
8 3 3.00074249475
9 4 2.99804452448
10 4 2.99834432893
11 4 2.99864416336
12 4 2.99894402778
13 4 2.99924392218
14 4 2.99954384657
15 4 2.99984380096
16 4 3.00014378534
17 5 2.99987379939
18 5 2.99990379813
19 5 2.99993379717
20 5 2.99996379651
21 5 2.99999379615
22 5 3.00002379608
23 6 2.99999679614
24 6 2.99999979614
25 6 3.00000279614
26 7 3.00000009614
27 8 2.99999982614
28 8 2.99999985614
29 8 2.99999988614
30 8 2.99999991614
31 8 2.99999994614
32 8 2.99999997614
33 8 3.00000000614
34 9 2.99999997914
35 9 2.99999998214
36 9 2.99999998514
37 9 2.99999998814
38 9 2.99999999114
39 9 2.99999999414
40 9 2.99999999714
41 9 3.00000000014
42 10 2.99999999744
43 10 2.99999999774
44 10 2.99999999804
45 10 2.99999999834
46 10 2.99999999864
47 10 2.99999999894
48 10 2.99999999924
49 10 2.99999999954
50 10 2.99999999984
51 10 3.00000000014
52 11 2.99999999987
53 11 2.9999999999
54 11 2.99999999993
55 11 2.99999999996
56 11 2.99999999999
57 11 3.00000000002
58 12 2.99999999999
59 12 2.99999999999
60 12 3.0
61 12 3.0
62 12 3.0
63 13 3.0
64 13 3.0
65 13 3.0
66 13 3.0
Would it still be the case that a number of those "3.0" results are actually something like 3.000000000000143 in the code, but I'm just not seeing them?
** Python Support Thread ** Quote
10-08-2011 , 09:23 AM
Quote:
Originally Posted by Gazillion
Was indeed the exact check I was using at 2 separate points within the nested loop, and I eneded up removing them as they basically did nothing, and I really think it is because I am dealing with floats. I tried to think of a way around it using my currently limited code vocabulary, and the only way I could think of doing so would be to temporarily convert the float to a different type like an int, but that way I would no doubt just end up with a ridiculous number of false positives.
yeah, this is one reason why this wasn't the best problem to dive into. (though it's fine). Floating point arithmetic really is hard. Check the site I linked to for some suggested ways of dealing with it.

Quote:
Originally Posted by Gazillion
Would it still be the case that a number of those "3.0" results are actually something like 3.000000000000143 in the code, but I'm just not seeing them?
yes, I believe so (I forget exactly how this is handled by Python). Try something like
Code:
print "{0:.30f}".format(result)
to print the number to an arbitrary precision, in this case 30 decimal places.
** Python Support Thread ** Quote
10-08-2011 , 09:48 AM
Yes, comparing floating point numbers with == and != is always a bad idea. I once spent a week tracking down a bug due to a comparison like this.

If you're testing to floating point numbers for equality then you should do:
Code:
epsilon =  1E-7

if abs(num1-num2)< epsilon:
    print "nubmers are equal!"
edit: this can be a bad strategy if the numbers you're dealing with are on the order of epsilon obviously. Another possible way to do it is if abs(1-num1/num2)<eps so you look at the percent difference between the two numbers. In that case though, you have to be careful that num2 never = 0 and gives you a divide by zero error.
** Python Support Thread ** Quote
10-08-2011 , 11:57 PM
Quote:
Originally Posted by Neko
Yes, comparing floating point numbers with == and != is always a bad idea. I once spent a week tracking down a bug due to a comparison like this.

If you're testing to floating point numbers for equality then you should do:
Code:
epsilon =  1E-7

if abs(num1-num2)< epsilon:
    print "nubmers are equal!"
edit: this can be a bad strategy if the numbers you're dealing with are on the order of epsilon obviously. Another possible way to do it is if abs(1-num1/num2)<eps so you look at the percent difference between the two numbers. In that case though, you have to be careful that num2 never = 0 and gives you a divide by zero error.
yeah, the latter is much better.
Code:
num1 - num2 < epsilon
is just waiting for some choice of num1 where epsilon is way too big or too small
** Python Support Thread ** Quote
10-11-2011 , 10:00 AM
Hey guys,

I've been getting my teeth into Project Euler (great site!) but I'm having some troubles with problem 3. Without trying to give away too many spoilers for those who may want to try this and haven't already, I am basically trying to do the following:

1) find all the factorials of the number, and add them to list 'fact[]'
2) I then want to take that list and, starting from fact[-1] and working backwards, check each of these values for primacy until I find the first value that returns true.

(1) I have accomplished fairly quickly and easily, but I'm having troubles with (2). I was hoping I could maybe take all the values in the list and use those in a FOR loop (ideally in reverse order), in order to then check each of them, but it's not proving easy.

Is there a way to use the contents of a list to act as a range for a loop, and have that loop only iterate for each value stored within a list? Is this the wrong way to go about it, and if so, is there a more preferable option to something like the FOR statement for iterating through this list?

Sorry for the questions - I'm a list newb so still know very little about them.


BTW, Neko, I though I had thanked you for your post the other day. I see for some reason it didn't show up in-thread, so thank you for that explanation. It'll take a while for that to become second nature for me but thanks a lot for showing me how it can be done.
** Python Support Thread ** Quote
10-11-2011 , 10:55 AM
Usually the way you will iterate through a list of values is like this:
Code:
>>> values = [1,3,5,7,11,13,17,19]
>>> for value in values:
... 	print value 
1
3
...
17
19
>>> for value in reversed(values):
... 	print value 
19
17
...
3
1
>>> 
>>> for value in values[::-1]:
... 	print value
19
17
...
3
1
>>>
So in your case you could do:

Code:
>>> for value in reversed(values):
...     if is_prime(value):
... 	    print value
where you have defined is_prime as a function somewhere else.
** Python Support Thread ** Quote
10-11-2011 , 11:25 AM
Awesome, thank you!! It was the reversed(value) bit that was throwing me the most. I think that's nailed it for me.

My algorithm must be super ineffecient because it's taking a looonnnnnnng time to find all the factors (I'll have to fine tune this), but thanks a lot - your code really helped:

Spoiler:

Code:
#The prime factors of 13195 are 5, 7, 13 and 29.
#What is the largest prime factor of the number 600851475143 ?

def isprime(f):
	if f == 1:
		return False
	for x in range(2, f):
		if f % x == 0:
			return False
	else:
		return True

def prmfct(arg):
	fact= []
	loop = 1
		
	#check all numbers in range 'arg/2+1' to see if they are factorials and add any factorials to list 'fact'
	while loop <= arg/2+1:
		if arg % loop == 0:
			fact += [loop]
			#print fact #comment out unless testing
		loop += 1
		
	print
	print 'Factorial check complete. Now checking for primes'
	print
	
	#check all items in reversed list 'fact' for primacy and return the final value
	
	for fa in reversed(fact):
		if isprime(fa):
			print fa

prmfct(123456789)
I should probably start checking for factorials from the end, and not from 1, and then checking them for primacy there and then rather than adding to a list, and stopping as soon as I find the first prime.
** Python Support Thread ** Quote
** Python Support Thread **
150% up to $2,000 Welcome Bonus on CoinPoker
Join the action now
Daily Rewards • Splash Pots • CoinRaces
** Python Support Thread **

      
m