Pastebin launched a little side project called VERYVIRAL.com, check it out ;-) Want more features on Pastebin? Sign Up, it's FREE!
Guest

Python Babylonian square root automation

By: a guest on Jan 5th, 2013  |  syntax: Python  |  size: 4.82 KB  |  views: 297  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. def return_highest(x):
  2.     #only used once, for the first number in the answer
  3.     x = int(x)
  4.     if x == 1 or x == 0:
  5.         return x
  6.     else:
  7.         x = x ** 0.5
  8.         y = str(x)
  9.         return y[:y.find('.')]
  10.  
  11. def seperate(question_s):
  12.     # seperates the numbers before the decimal and after the decimal ( if any )
  13.     question_string = str(question_s)
  14.     if '.' in question_string:
  15.         a = question_string[:question_string.find('.')]
  16.         b = question_string[question_string.find('.')+1:]
  17.         return(int(a),int(b))
  18.     else:
  19.         return(question_s,0)
  20.  
  21. def populate_z(a,b,places):
  22.     # z[] is the array(list) that contains the number to be squarerooted(?)
  23.     # z[] needs to be correctly populated so that the math can be done
  24.     # the numbers need to be paired up (unlike in long division numbers are brought down in twos)
  25.     z = ['00'] * places                                     #fill z[] with the default 0 pairs, only as many as was asked for
  26.     a = str(a)                                              #one of the many instances of turning an int to str or visa versa
  27.     b = str(b)
  28.     if len(a) % 2 != 0:                                     #if there are an odd number of digits before the decimal we need to add
  29.         #odd number of digits                               #a zero before it, before they're grouped, so they can be grouped
  30.         a_n = '0' + a
  31.     else:
  32.         a_n = a
  33.     if len(b) % 2 != 0:
  34.         #odd number of digits
  35.         b_n = b + '0'
  36.     else:
  37.         b_n = b
  38.     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)
  39.     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
  40.         z[G] = c[G * 2] + c[(G * 2) + 1]
  41.     if ( len(c) / 2) > places:                              # they asked for fewer places than they gave
  42.         while len(z) > len(c) / 2:                          # while z (the array we use in the math) is bigger than c (evened out number)
  43.             del z[len(z) - 1]                               # shave off what's unneccessary
  44.  
  45.     return(z)
  46.  
  47. def find_next(x,y):                                         # vital function for finding the next digit in the answer
  48.     for a in range(0,10):
  49.         z = int(str(x) + str(a)) * a
  50.         z2 = int(str(x) + str(a))
  51.         if z <= int(y):
  52.             d = a
  53.     return d
  54.  
  55. question = float(raw_input("Find the square root of: "))            # do ask? do ask.
  56. places = int(raw_input("How many digits will the answer go to? "))
  57. SQ = seperate(question)                                             # call seperate, makes 3.14 into [3,14] and 1234.9001 into [1234,9001]
  58. z = populate_z(SQ[0],SQ[1],places)                                  # important step, populate z[] to use it in the math
  59.  
  60. answer = return_highest(z[0])                                       #call return highest function one and only once, to get the first digit in the answer
  61.  
  62. offnumber = int(answer) * 2                                         # offnumber is one of the significant differences between this and long division
  63. 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
  64. 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
  65. 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
  66. answer = answer + nextans                                           # use that next answer and tack it onto the answer
  67.  
  68. while len(str(answer)) < places:                                    # main loop, do it till the answer is populated to the number given at the beginning
  69.     # here is the part that gave me the most trouble, the order of these is quite fragile
  70.     # 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
  71.    
  72.     tosub = int(str(offnumber) + str(nextans)) * int(nextans)
  73.     offnumber = int(answer) * 2
  74.     sub = int(added) - tosub
  75.     added = str(sub) + z[len(str(answer))]
  76.     nextans = str(find_next(offnumber,added))
  77.     answer = answer + nextans
  78. dec = 0
  79.  
  80. if len(str(SQ[0])) % 2 == 0:                                        # need to know where the decimal point goes
  81.     dec = len(str(SQ[0])) / 2
  82. else:
  83.     dec = (len(str(SQ[0]))+1) / 2
  84.  
  85.  
  86. finalanswer = str(answer[0:dec]) + '.' + str(answer[dec:])          # we need to add the decimal point back in since the math is done
  87.  
  88. print finalanswer