def return_highest(x): #only used once, for the first number in the answer x = int(x) if x == 1 or x == 0: return x else: x = x ** 0.5 y = str(x) return y[:y.find('.')] def seperate(question_s): # seperates the numbers before the decimal and after the decimal ( if any ) question_string = str(question_s) if '.' in question_string: a = question_string[:question_string.find('.')] b = question_string[question_string.find('.')+1:] return(int(a),int(b)) else: return(question_s,0) def populate_z(a,b,places): # z[] is the array(list) that contains the number to be squarerooted(?) # z[] needs to be correctly populated so that the math can be done # the numbers need to be paired up (unlike in long division numbers are brought down in twos) z = ['00'] * places #fill z[] with the default 0 pairs, only as many as was asked for a = str(a) #one of the many instances of turning an int to str or visa versa b = str(b) if len(a) % 2 != 0: #if there are an odd number of digits before the decimal we need to add #odd number of digits #a zero before it, before they're grouped, so they can be grouped a_n = '0' + a else: a_n = a if len(b) % 2 != 0: #odd number of digits b_n = b + '0' else: b_n = b c = a_n + b_n #variable c is the correctly evened out number (5.7 has become 05.70 and 23.123 has become 23.1230) for G in range(0,(len(c)/2)): #c into z[], they need to be added in pairs so that each item in the array is 2 numbers z[G] = c[G * 2] + c[(G * 2) + 1] if ( len(c) / 2) > places: # they asked for fewer places than they gave while len(z) > len(c) / 2: # while z (the array we use in the math) is bigger than c (evened out number) del z[len(z) - 1] # shave off what's unneccessary return(z) def find_next(x,y): # vital function for finding the next digit in the answer for a in range(0,10): z = int(str(x) + str(a)) * a z2 = int(str(x) + str(a)) if z <= int(y): d = a return d question = float(raw_input("Find the square root of: ")) # do ask? do ask. places = int(raw_input("How many digits will the answer go to? ")) SQ = seperate(question) # call seperate, makes 3.14 into [3,14] and 1234.9001 into [1234,9001] z = populate_z(SQ[0],SQ[1],places) # important step, populate z[] to use it in the math answer = return_highest(z[0]) #call return highest function one and only once, to get the first digit in the answer offnumber = int(answer) * 2 # offnumber is one of the significant differences between this and long division sub = int(z[0]) - (int(answer) ** 2) # do the first subtraction (different because there isn't yet a tosub, because there isn't yes a nextans added = str(sub) + z[len(str(answer))] # this is where we bring down the next pair of numbers in z to tack onto the end of the answer to our subtraction nextans = str(find_next(offnumber,added)) # here we call find_next and send it offnumber and the number it needs to be under to return the next digit in the answer answer = answer + nextans # use that next answer and tack it onto the answer while len(str(answer)) < places: # main loop, do it till the answer is populated to the number given at the beginning # here is the part that gave me the most trouble, the order of these is quite fragile # if you don't quite understand the math, just research how to do square roots by hand, this is simply an automation of exactly that tosub = int(str(offnumber) + str(nextans)) * int(nextans) offnumber = int(answer) * 2 sub = int(added) - tosub added = str(sub) + z[len(str(answer))] nextans = str(find_next(offnumber,added)) answer = answer + nextans dec = 0 if len(str(SQ[0])) % 2 == 0: # need to know where the decimal point goes dec = len(str(SQ[0])) / 2 else: dec = (len(str(SQ[0]))+1) / 2 finalanswer = str(answer[0:dec]) + '.' + str(answer[dec:]) # we need to add the decimal point back in since the math is done print finalanswer