def largest_magnitude(self): "Determine the largest magnitude from adding any two numbers" # 1. Start with nothing result = 0 # 2. Loop for all of the pairs of pairs for pair1 in self.pairs: for pair2 in self.pairs: if pair1 == pair2: continue # 2. Add pair2 to pair1 and check the magnitude test = number.Number(text=str(pair1)) test.add(pair2.pair) mag = test.magnitude() if mag > result: result = mag # 3. Add pair1 to pair2 and check the magnitude test = number.Number(text=str(pair2)) test.add(pair1.pair) mag = test.magnitude() if mag > result: result = mag # 4. Return the largest magnitude return result
def factorial(n): if n.imaginary != 0: raise ArithmeticError("You cannot have imaginary factorial.") if n < number.Number(0): raise ArithmeticError("You cannot have negative factorial.") if n < number.Number(2): return number.Number(1) return n * factorial(n - number.Number(1))
def test_round(): """ This function will only check the changes in special features: - original value - whether the value needs rounding (bool) - rounded value All other test cases should handle the inner workings of the rounder """ # 6 current test cases original = [ "1234", "123,456", "(0.3456)", "(.12345678)", "/123.4567/", "1.2345e-5", "-1234" ] rounded = [ "1200", "123,000", "(0.3456)", "(0.1235) ", "/123.5/ ", "1.234E-05", "-1200" ] needed_rounding = [True, True, False, True, True, True, True, True] for i in range(len(original)): num = number.Number(original[i]) num.round() assert num.original == original[i] assert num.needed_rounding == needed_rounding[i] assert num.rounded == rounded[i]
def test_clean(): # 9 current test cases original = [ "1234", "123,456", "(0.3456)", "(.12345678)", "12/12/1225", "hello world", "/123.4567/", "12345E+06", "-1234" ] original_cleaned = [ "1234", "123456", "0.3456", ".12345678", "12/12/1225", "", "123.4567", "12345000000", "1234" ] leading_text = ["", "", "(", "(", "", "hello world", "/", "", "-"] trailing_text = ["", "", ")", ")", "", "", "/", "", ""] has_commas = [False, True, False, False, False, False, False, False, False] in_scientific_form = [ False, False, False, False, False, False, False, True, False ] for i in range(len(original)): num = number.Number(original[i]) num.clean() assert num.original == original[i] assert num.original_cleaned == original_cleaned[i] assert num.leading_text == leading_text[i] assert num.trailing_text == trailing_text[i] assert num.has_commas == has_commas[i] assert num.in_scientific_form == in_scientific_form[i]
def result(): start_type = flask.request.form['numType'] start_value = flask.request.form['startValue'].upper() user_number = number.Number(start_value, start_type) end_value = '' is_roman_valid = None check_dec_to_roman = None if start_type == 'decimal': end_value = user_number.convert_to_roman() else: end_value = user_number.convert_to_decimal() is_roman_valid = user_number.check_if_valid() check_dec_to_roman = user_number.convert_to_roman() print('is valid roman numeral = ', is_roman_valid) movie = [] movie_info, movies_that_year = user_number.check_for_movies() (actor1, actor2, actor1_title_list, actor2_title_list) = user_number.check_for_actors() print('movieInfo=', movie_info) print('actorInfo=', actor1, actor2, actor1_title_list, actor2_title_list) #this_year = year(today()) return flask.render_template('result.html', startValue=start_value, endValue=end_value, is_roman_valid=is_roman_valid, check_dec_to_roman=check_dec_to_roman, movie=movie_info, movieCount=movies_that_year, actor1=actor1, actor1Titles=actor1_title_list, actor2=actor2, actor2Titles=actor2_title_list, thisYear=datetime.date.today().year)
def __init__(self, text=None, part2=False): # 1. Set the initial values self.part2 = part2 self.text = text self.pairs = [] self.sumation = [] # 2. Process text (if any) if text is not None and len(text) > 0: for line in text: self.pairs.append(number.Number(text=line, part2=part2))
def process_csvfile(self): """Process a tab or comma-delimited file and create a rounded file""" # Open file and set up (basename, ext) = os.path.splitext(self.fname) outfilename = basename + "_rounded" + ext line_number = 0 delimiter = self.args.delimiter # Open infile/outfile and begin performing rounding rules with open(self.fname, "rU") as infile: if exists_notempty(outfilename) and not self.overwrite: logger.error( "ABORT: %s exists. Please delete or specify --zap", outfilename) with open(outfilename, "w") as outfile: for line in infile: stripped_line = line.rstrip() # remove EOL eol_len = len(line) - len(stripped_line) if eol_len != 0: # preserve the EOL characters if needed eol = line[-eol_len:] else: eol = "" line_number += 1 # Check to make sure delimiter is seen if delimiter not in stripped_line: logging.info( "\tNo delimiter found in line {}: {}".format( line_number, stripped_line)) if " " in stripped_line: logging.info( "\tUsing space as delimiter for this line") delimiter = " " # Split by delimiter and round all items fields = stripped_line.split(delimiter) rounded_fields = [] for field in fields: num = number.Number(field) num.round() if args.debug: print("{} -> {}".format(field, num.rounded)) if num.needed_rounding: self.values_logger.info("line %d %s --> %s", line_number, num.original, num.rounded) rounded_fields.append(num.rounded) else: rounded_fields.append(num.original) outfile.write(delimiter.join(rounded_fields)) outfile.write(eol) # output the original eol
def sum_them_up(self): "Sum the homework numbers" # 1. Start with the first one result = number.Number(text=str(self.pairs[0]), part2=self.part2) # 2. Loop for the rest of the numbers for pair in self.pairs[1:]: # 3. Add it in result.add(pair.pair) # 4. Save the sumation self.sumation = result
def test_text_init(self): "Test the Number object creation from text" # 1. Create Number object from text myobj = number.Number(text=EXAMPLE_TEXT) # 2. Make sure it has the expected values self.assertEqual(myobj.part2, False) self.assertEqual(len(myobj.text), 29) self.assertEqual(myobj.pair, [[[[4, 3], 4], 4], [7, [[8, 4], 9]]]) self.assertEqual(str(myobj), EXAMPLE_TEXT) # 3. Check methods self.assertEqual(myobj.add([1, 1]), [[[[0, 7], 4], [[7, 8], [6, 0]]], [8, 1]])
def start_game(): # Load lives and scores from file # if either isn't found, use the default value(2nd arg) lives = counter.Counter.load_from_file( 'Lives', game_session.GameSession.DEFAULT_LIVES) score = counter.Counter.load_from_file( 'Score', game_session.GameSession.DEFAULT_SCORE) # generate the two numbers num = n.Number() first_number = num.gen_number() next_number = num.gen_number() print('Lives:', lives) print('Score:', score) print() print('The first number is', first_number) print("Do you think next number is higher or lower? ") # first we need to get users answer # we are also checking if they want to save and quit # hence we need to pass lives and score here user_answer = get_input.GetInput.user_choice() #print('User answer is', user_answer) # the gamelogic module decides whether the user won or lost outcome = game_logic.GameLogic.decide(first_number, next_number, user_answer) #print('The result is', result) # we pass the result to player manager class that will: # notify user # update lives count # update score count # call gameover module when user is out of lives pm = player_manager.PlayerManager( outcome=outcome, lives=lives, score=score, next_number=next_number, ) pm.process_result() # reset the class instance to generate new numbers and call it again StartApp.start_game()
def test_reconstruct(): """ This function will only test inputs that abide by the following rules: - there are NO alphabetical letters in the cleaned string - the cleaned string is NOT an empty string - there are NO symbols found in the cleaned string The reconstruct function will only be called when those conditions are true """ # 6 current test cases original = [ "1234", "123,456", "(0.3456)", "(.12345678)", "/123.4567/", "1.234+e2" ] original_cleaned = [ "1234", "123456", "0.3456", ".12345678", "123.4567", "123.4" ] rounded_cleaned = [ "1200", "123000", "0.3456", "0.1235", "123.5", "1.234E+02" ] rounded = [ "1200", "123,000", "(0.3456)", "(0.1235) ", "/123.5/ ", "1.234E+02" ] leading_text = ["", "", "(", "(", "/", ""] trailing_text = ["", "", ")", ")", "/", ""] has_commas = [False, True, False, False, False, False] method = [ COUNTS_METHOD, COUNTS_METHOD, ROUND4_METHOD, ROUND4_METHOD, ROUND4_METHOD, ROUND4_METHOD ] in_scientific_form = [False, False, False, False, False, True] for i in range(len(original)): ri = dict(rounding_info) ri['original'] = original[i] ri['original_cleaned'] = original_cleaned[i] ri['rounded_cleaned'] = rounded_cleaned[i] ri['leading_text'] = leading_text[i] ri['trailing_text'] = trailing_text[i] ri['has_commas'] = has_commas[i] ri['method'] = method[i] ri['in_scientific_form'] = in_scientific_form[i] num = number.Number(None) num.init_for_testing(ri) num.reconstruct() assert num.rounded == rounded[i]
def process_csvfile(self): """Process a tab or comma-delimited file and create a rounded file""" # Open file and set up (basename, ext) = os.path.splitext(self.fname) outfilename = basename + "_rounded" + ext line_number = 0 delimiter = self.args.delimiter # Open infile/outfile and begin performing rounding rules with open(self.fname, "rU") as infile: with helpers.safe_open(outfilename, "w", zap=self.args.zap) as outfile: for line in infile: stripped_line = line.rstrip() # remove EOL eol_len = len(line) - len(stripped_line) if eol_len != 0: # preserve the EOL characters if needed eol = line[-eol_len:] else: eol = "" line_number += 1 # Check to make sure delimiter is seen if delimiter not in stripped_line: rounder_logger.info("\tNo delimiter found in line {}: " "{}".format( line_number, stripped_line)) if " " in stripped_line: rounder_logger.info( "\tUsing space as delimiter for" " this line") delimiter = " " # Split by delimiter and round all items fields = stripped_line.split(delimiter) rounded_fields = [] for field in fields: num = number.Number(field) num.round(self.fname) if num.needs_rounding: rounded_fields.append(num.rounded) else: rounded_fields.append(num.original) outfile.write(delimiter.join(rounded_fields)) outfile.write(eol) # output the original eol
def test_sumation(self): "Test the Number object sumatation" # 1. Create Number object from text myobj = number.Number(text="[[[0,[4,5]],[0,0]],[[[4,5],[2,6]],[9,5]]]") # 2. Make sure it has the expected values self.assertEqual(myobj.part2, False) self.assertEqual(myobj.pair, [[[0, [4, 5]], [0, 0]], [[[4, 5], [2, 6]], [9, 5]]]) # 3. Check methods self.assertEqual(myobj.add([7, [[[3, 7], [4, 3]], [[6, 3], [8, 8]]]]), [[[[4, 0], [5, 4]], [[7, 7], [6, 0]]], [[8, [7, 7]], [[7, 9], [5, 0]]]]) self.assertEqual( myobj.add([[2, [[0, 8], [3, 4]]], [[[6, 7], 1], [7, [1, 6]]]]), [[[[6, 7], [6, 7]], [[7, 7], [0, 7]]], [[[8, 7], [7, 7]], [[8, 8], [8, 0]]]]) self.assertEqual( myobj.add([[[[2, 4], 7], [6, [0, 5]]], [[[6, 8], [2, 8]], [[2, 1], [4, 5]]]]), [[[[7, 0], [7, 7]], [[7, 7], [7, 8]]], [[[7, 7], [8, 8]], [[7, 7], [8, 7]]]]) self.assertEqual(myobj.add([7, [5, [[3, 8], [1, 4]]]]), [[[[7, 7], [7, 8]], [[9, 5], [8, 7]]], [[[6, 8], [0, 8]], [[9, 9], [9, 0]]]]) self.assertEqual(myobj.add([[2, [2, 2]], [8, [8, 1]]]), [[[[6, 6], [6, 6]], [[6, 0], [6, 7]]], [[[7, 7], [8, 9]], [8, [8, 1]]]]) self.assertEqual( myobj.add([2, 9]), [[[[6, 6], [7, 7]], [[0, 7], [7, 7]]], [[[5, 5], [5, 6]], 9]]) self.assertEqual(myobj.add([1, [[[9, 3], 9], [[9, 0], [0, 7]]]]), [[[[7, 8], [6, 7]], [[6, 8], [0, 8]]], [[[7, 7], [5, 0]], [[5, 5], [5, 6]]]]) self.assertEqual( myobj.add([[[5, [7, 4]], 7], 1]), [[[[7, 7], [7, 7]], [[8, 7], [8, 7]]], [[[7, 0], [7, 7]], 9]]) self.assertEqual( myobj.add([[[[4, 2], 2], 6], [8, 7]]), [[[[8, 7], [7, 7]], [[8, 6], [7, 7]]], [[[0, 7], [6, 6]], [8, 7]]])
import number my_number = number.Number(5) print(my_number.is_even())
def result(): start_value = request.form['startValue'].upper() start_type = request.form['numType'] user_number = number.Number(str(start_value), start_type) end_value = '' is_roman_valid = None check_dec_to_roman = None if start_type == 'decimal': end_value = user_number.convert_to_roman() else: end_value = user_number.convert_to_decimal() is_roman_valid = user_number.check_if_valid() check_dec_to_roman = user_number.convert_to_roman() movie_info = None movies_that_year = 0 actor1 = None actor1_title_list = None actor2 = None actor2_title_list = None if 1888 <= user_number.decimal <= datetime.date.today().year: db = LocalProxy(get_db) cur = db.cursor() try: query = 'SELECT tconst, primaryTitle, genres FROM movies WHERE isAdult = 0 AND titleType = "movie" AND startYear = ?;' cur.execute(query, (int(user_number.decimal), )) movie_list = cur.fetchall() except sqlite3.Error as e: app.logger.error('DB call failed. Query = ', query, ' error = ', e) print(e) try: (movie_info, movies_that_year) = user_number.get_random_movie(movie_list) except: (movie_info, movies_that_year) = (None, 0) actor_list = [] try: query = 'SELECT nconst, primaryName, knownForTitles FROM actors WHERE birthYear = ?' cur.execute(query, (int(user_number.decimal), )) actor_list = cur.fetchall() except sqlite3.Error as e: print(e) if len(actor_list): actor1 = list(user_number.get_random_actor2(actor_list)) print('actor1=', actor1) title_IDs = actor1[2].split(',') movie_titles = [] for title_ID in title_IDs: try: query = 'select primaryTitle from movies where tconst=?' cur.execute(query, (title_ID, )) db_listing = cur.fetchone() if db_listing: movie_titles.append((title_ID, db_listing)) except: pass actor1.append(movie_titles) actor_list = [] try: query = 'SELECT nconst, primaryName, knownForTitles FROM actors WHERE deathYear = ?' cur.execute(query, (int(user_number.decimal), )) actor_list = cur.fetchall() except sqlite3.Error as e: print(e) finally: pass #conn.close() if len(actor_list): #(actor2, actor2_title_list) = user_number.get_random_actor2(actor_list) actor2 = list(user_number.get_random_actor2(actor_list)) print('actor2=', actor2) title_IDs = actor2[2].split(',') movie_titles = [] for title_ID in title_IDs: try: query = 'select primaryTitle from movies where tconst=?' cur.execute(query, (title_ID, )) db_listing = cur.fetchone() if db_listing: movie_titles.append((title_ID, db_listing)) except: pass actor2.append(movie_titles) ''' (movie_info, movies_that_year) = user_number.check_for_movies() (actor1, actor2) = user_number.check_for_actors() ''' return render_template('result.html', startValue = start_value, \ endValue = end_value, movie = movie_info, movieCount = movies_that_year, \ actor1 = actor1, actor2 = actor2, thisYear = datetime.date.today().year)
def process_logfile(self): # Make sure that our intended output files do not exist (name, ext) = os.path.splitext(self.fname) fname_rounded = name + "_rounded" + ext fname_before = name + "_0.html" fname_after = name + "_1.html" if not self.overwrite: abort = False for fn in [fname_rounded, fname_before, fname_after]: if exists_notempty(fn): logger.error("%s exists. Please delete file and continue", fn) abort = True if abort: logger.error("ABORT") exit(1) frounded = open(fname_rounded, "w") fbefore = open(fname_before, "w") fafter = open(fname_after, "w") fbefore.write(self.HTML_HEADER) fafter.write(self.HTML_HEADER) # Note that the output was rounded ROUNDING_RULES_MESSAGE = "*** DRB ROUNDING RULES HAVE {}BEEN APPLIED ***" frounded.write(ROUNDING_RULES_MESSAGE + "\n") fbefore.write("<p><b>" + ROUNDING_RULES_MESSAGE.format("NOT ") + "</b></p>\n") fafter.write("<p><b>" + ROUNDING_RULES_MESSAGE.format("") + "</b></p>\n") # Count the number of lines linecount = open(self.fname).read().count("\n") # Add the rounding rules for what in [fbefore, fafter]: what.write("<div id='line_numbers'>\n<pre>\n") what.write("".join([ "{:}\n".format(line_number) for line_number in range(1, linecount + 1) ])) what.write("</pre>\n</div><div id='content'>\n<pre>\n") with open(self.fname) as fin: linenumber = 0 for line in fin: linenumber += 1 pos = 0 # where we are on the line spans = helpers.numbers_in_line(line) for span in spans: (col0, col1) = (span[0], span[1] ) # the columns where the number appears num = number.Number(line[col0:col1]) num.round() if num.needed_rounding: self.values_logger.info("line %s %s --> %s", linenumber, num.original, num.rounded) if num.method == ROUND4_METHOD: kind = 'float' else: kind = 'count' if num.rounded == LESS_THAN_15: extra_spaces = len(LESS_THAN_15) - len( num.original) if helpers.all_spaces(line[col1:col1 + extra_spaces]): col1 = col1 + extra_spaces fbefore.write(line[pos:col0] ) # part of line before span in question fbefore.write("<span class='b{}'>".format(kind)) fbefore.write(line[col0:col1]) # span in question fbefore.write("</span>") fafter.write(line[pos:col0] ) # part of line after span in question fafter.write("<span class='r{}'>".format(kind)) fafter.write(num.rounded) # span in question fafter.write("</span>") frounded.write(line[pos:col0]) frounded.write(num.rounded) pos = col1 # next character on line to process is col1 # get end of line (or entire line, if not spans) fbefore.write(line[pos:]) fafter.write(line[pos:]) frounded.write(line[pos:]) for what in [fbefore, fafter]: what.write("</div></body></html>\n") frounded.close() fbefore.close() fafter.close()
def test_number_9_comes_after_8(): n8 = number.Number(8) n9 = n8.next() assert n9.value() == 9
def process_logfile(self): # Make sure that our intended output files do not exist (name, ext) = os.path.splitext(self.fname) fname_rounded = name + "_rounded" + ext frounded = helpers.safe_open(fname_rounded, "w", return_none=True, zap=args.zap) # before - highlight items that need rounding fname_before = name + "_0.html" fbefore = helpers.safe_open(fname_before, "w", return_none=True, zap=args.zap) # after - show it rounded fname_after = name + "_1.html" fafter = helpers.safe_open(fname_after, "w", return_none=True, zap=args.zap) if (not frounded) or (not fbefore) or (not fafter): rounder_logger.error('ABORT: Could not open log and html files') sys.exit(1) fbefore.write(self.HTML_HEADER) fafter.write(self.HTML_HEADER) # Note that the output was rounded ROUNDING_RULES_MESSAGE = "*** DRB ROUNDING RULES HAVE {}BEEN APPLIED ***" frounded.write(ROUNDING_RULES_MESSAGE + "\n") fbefore.write("<p><b>" + ROUNDING_RULES_MESSAGE.format("NOT ") + "</b></p>\n") fafter.write("<p><b>" + ROUNDING_RULES_MESSAGE.format("") + "</b></p>\n") # Count the number of lines linecount = open(self.fname).read().count("\n") # Add the rounding rules for what in [fbefore, fafter]: what.write("<div id='line_numbers'>\n<pre>\n") what.write("".join([ "{:}\n".format(line_number) for line_number in range(1, linecount + 1) ])) what.write("</pre>\n</div><div id='content'>\n<pre>\n") with open(self.fname) as fin: for line in fin: pos = 0 # where we are on the line spans = helpers.numbers_in_line(line) for span in spans: (col0, col1) = (span[0], span[1] ) # the columns where the number appears num = number.Number(line[col0:col1]) num.round(self.fname) if num.needs_rounding: if num.method == ROUND4_METHOD: kind = 'float' else: kind = 'count' if num.rounded == LESS_THAN_15: extra_spaces = len(LESS_THAN_15) - len( num.original) if helpers.all_spaces(line[col1:col1 + extra_spaces]): col1 = col1 + extra_spaces fbefore.write(line[pos:col0] ) # part of line before span in question fbefore.write("<span class='b{}'>".format(kind)) fbefore.write(line[col0:col1]) # span in question fbefore.write("</span>") fafter.write(line[pos:col0] ) # part of line after span in question fafter.write("<span class='r{}'>".format(kind)) fafter.write(num.rounded) # span in question fafter.write("</span>") frounded.write(line[pos:col0]) frounded.write(num.rounded) pos = col1 # next character on line to process is col1 # get end of line (or entire line, if not spans) fbefore.write(line[pos:]) fafter.write(line[pos:]) frounded.write(line[pos:]) for what in [fbefore, fafter]: what.write("</div></body></html>\n") frounded.close() fbefore.close() fafter.close()
def main(): parser = argparse.ArgumentParser( description='Self-Descriptive Sentence Generator', formatter_class=argparse.ArgumentDefaultsHelpFormatter, version=__version__) parser.add_argument('text', nargs='?', default='', help='a text will be included in the sentence') parser.add_argument('-l', '--language', default='chinese', choices=('chinese', 'number'), help='choose a language to generate sentence') parser.add_argument('-a', '--attempts', type=int, default=SentenceGenerator.MAX_ATTEMPTS, help='the maximum number of attempts') parser.add_argument( '-i', '--iterations', type=int, default=SentenceGenerator.MAX_ITERATIONS, help='the maximum number of iterations in each attempt') parser.add_argument('-V', '--no-verbose', action='store_true', help='disable debug messages') group = parser.add_mutually_exclusive_group() group.add_argument( '-0', '--down-to-zero', action='store_true', help= 'prefer zero when performing a decrease operation on a count=2 character' ) group.add_argument( '-1', '--down-to-one', action='store_true', help= 'prefer one when performing a decrease operation on a count=2 character' ) group.add_argument( '-s', '--seed', type=int, help='use a seeded Random object to randomly choose between zero and one' ' when performing a decrease operation on a count=2 character') unicode_args = map(lambda s: unicode(s, sys.getfilesystemencoding()), sys.argv) args = parser.parse_args(unicode_args[1:]) if args.down_to_zero: down_to_zero = True elif args.down_to_one: down_to_zero = False else: down_to_zero = args.seed if args.language == 'chinese': language = chinese.Chinese() elif args.language == 'number': language = number.Number() else: raise ValueError('unknown language {}'.format(args.language)) counts = SentenceGenerator.generate(language, user_text=args.text, attempts=args.attempts, iterations=args.iterations, down_to_zero=down_to_zero, verbose=not args.no_verbose) if counts: print( language.compose_sentence(counts.total, counts, user_text=args.text)) if not SentenceGenerator.verify(language, args.text, counts): raise Exception( 'Oops, something is wrong, we got an incorrect sentence!') else: print('Generation failed.')
def process_xlsx(self, is_xlsx): """Process an excel spreadsheet and create a rounded spreadsheet""" from openpyxl import load_workbook from openpyxl.styles import PatternFill from openpyxl.comments import Comment FILL_ORANGE = PatternFill(start_color='FFA500', end_color='FFA500', fill_type='solid') FILL_BLUE = PatternFill(start_color='00b8ff', end_color='00b8ff', fill_type='solid') COMMENT_FLOAT = Comment( 'Orange: rounder identified a FLOAT that needed to be rounded', 'DRB_ROUNDER') COMMENT_INTEGER = Comment( 'Blue: rounder identified a COUNT that needed to be rounded', 'DRB_ROUNDER') first_float_flag = True first_integer_flag = True fname = self.fname # Self.args will only be None when running tests if self.args == None: highlight = False else: highlight = self.args.highlight # Make sure the excel spreadsheet exists if not os.path.exists(fname): logging.error('ABORT: Excel spreadsheet does not exist') sys.exit(1) # Convert the workbook if needed if is_xlsx == False: helpers.convert_to_xlsx(fname) (base, ext) = os.path.splitext(fname) fname = base + ".xlsx" # Make sure no formulas exist in the spreadsheet if helpers.check_for_excel_formulas(fname): logging.error( 'ABORT: Excel spreadsheet contains formulas. ' 'Please remove the formulas in the highlighted cells') sys.exit(1) # Apply rounding rules to all cells in spreadsheet wb = load_workbook(fname, data_only=True) # Open the workbook import openpyxl openpyxl.writer.excel.save_workbook(wb, self.new_fname) values_seen = 0 values_rounded = 0 for sheetname in wb.sheetnames: ws = wb[sheetname] for row in ws.iter_rows(): for cell in row: values_seen += 1 # Windows stores excel flaots as single precision sometimes, # which cased a value 0.004237 to be read by Python as 0.0042369999999999994. # The following code checks to see if a float is stored and, if it is, it is rounded # to 15 significant figures first. IEEE floating point gives imprecision after 17 digits if type(cell.value) == float: value = format(cell.value, '.15') num = number.Number(value, method=ROUND4_METHOD) else: num = number.Number(str(cell.value)) num.round() if num.needed_rounding == True: self.values_logger.info("cell %s!%s%s %s --> %s", sheetname, cell.column, cell.row, num.original, num.rounded) if num.method == ROUND4_METHOD: if not highlight: # argument passed to only highlight spreadsheet try: # Successful typecast if no special characters cell.value = float(num.rounded) except ValueError: cell.value = num.rounded cell.fill = FILL_ORANGE if first_float_flag: cell.comment = COMMENT_FLOAT first_float_flag = False elif num.method == COUNTS_METHOD: if not highlight: # argument passed to only highlight spreadsheet if num.rounded == LESS_THAN_15: cell.value = LESS_THAN_15 else: try: # Successful typecast if no special characters cell.value = int(num.rounded) except ValueError: cell.value = num.rounded cell.fill = FILL_BLUE if first_integer_flag: cell.comment = COMMENT_INTEGER first_integer_flag = False # Save the rounded calculations to a new file try: wb.save(self.new_fname) logging.info("STATUS: New spreadsheet written to %s", self.new_fname) except PermissionError: logging.error( 'ABORT: Could not save. Please close rounded spreadsheet') exit(1)
def degree(n): return n * number.Number(180) / number.Number(constant.constants["pi"])
def radian(n): return n * number.Number(constant.constants["pi"]) / number.Number(180)
def sqrt(n): return n**number.Number(0.5)
def computeEquation(m, modes=""): if "the meaning of life" in m: return number.Number(42) #Replace the constants for c in constant.constants: m = m.replace(c, constant.constants[c]) m = m.replace("^", "**") m = m.replace("_", "").replace("import", "").replace("decode", "").replace("encode", "").replace("open", "") #Change double factorials, ie 5!! -> double_fact(5) p = re.compile(ur'(-?\d+)!!') subst = r"double_fact(\1)" m = re.sub(p, subst, m) p = re.compile(ur'\((.?)\)!!') subst = r"double_fact(\1)" m = re.sub(p, subst, m) #Change factorials, ie 5! -> fact(5) p = re.compile(ur'(-?\d+)!') subst = r"factorial(\1)" m = re.sub(p, subst, m) p = re.compile(ur'\((.?)\)!') subst = r"factorial(\1)" m = re.sub(p, subst, m) m = m.replace("||", " or ").replace("|", " or ") m = m.replace("&&", " and ").replace("&", " and ") #Converts e notation, ie 2e9 to 2 * 10**9, because errors and stuff p = re.compile(ur'([:]?\d*\.\d+|\d+)e([-+]?)([-+]?\d*\.\d+|\d+)') subst = r"\1 * 10**\2\3" m = re.sub(p, subst, m) #Converts all remaining numbers into numbers p = re.compile(ur'([:]?\d*\.\d+|\d+)') subst = r"number.Number('\1')" m = re.sub(p, subst, m) #Fix up i m = m.replace(")i", ")*number.Number(0,1)") m = m.replace('in', '@') p = re.compile(ur'(?<![a-zA-Z])i') subst = u"number.Number(0,1)" m = re.sub(p, subst, m) m = m.replace("@", "in") safe_dict = {} safe_dict["sin"] = sin safe_dict["cos"] = cos safe_dict["tan"] = tan safe_dict["asin"] = asin safe_dict["acos"] = acos safe_dict["atan"] = atan safe_dict["sinh"] = sinh safe_dict["cosh"] = cosh safe_dict["tanh"] = tanh safe_dict["asinh"] = asinh safe_dict["acosh"] = acosh safe_dict["atanh"] = atanh safe_dict["sqrt"] = sqrt safe_dict["abs"] = abs safe_dict["log"] = log safe_dict["fact"] = factorial safe_dict["factorial"] = factorial safe_dict["double_fact"] = double_fact safe_dict["ceil"] = ceil safe_dict["floor"] = floor safe_dict["exp"] = exp safe_dict["log10"] = log10 safe_dict["deg"] = degree safe_dict["rad"] = radian safe_dict["degrees"] = degree safe_dict["radians"] = radian safe_dict["number"] = number result = eval(m, {"__builtins__": None}, safe_dict) return result
def test_empty_init(self): "Test the default Number creation" # 1. Create default Number object myobj = number.Number() # 2. Make sure it has the default values self.assertEqual(myobj.part2, False) self.assertEqual(myobj.text, None) self.assertEqual(myobj.pair, []) # 3. Check methods self.assertEqual(myobj.find_comma("1,2"), 1) self.assertEqual(myobj.find_comma("[1,2],3"), 5) self.assertEqual(myobj.find_comma("9,[8,7]"), 1) self.assertEqual(myobj.find_comma("[1,9],[8,5]"), 5) self.assertEqual(myobj.split_text("[1,2]"), ['1', '2']) self.assertEqual(myobj.split_text("[[1,2],3]"), ['[1,2]', '3']) self.assertEqual(myobj.split_text("[9,[8,7]]"), ['9', '[8,7]']) self.assertEqual(myobj.split_text("[[1,9],[8,5]]"), ['[1,9]', '[8,5]']) self.assertEqual(myobj.text_to_num("[1,2]"), [1, 2]) self.assertEqual(myobj.text_to_num("[[1,2],3]"), [[1, 2], 3]) self.assertEqual(myobj.text_to_num("[9,[8,7]]"), [9, [8, 7]]) self.assertEqual(myobj.text_to_num("[[1,9],[8,5]]"), [[1, 9], [8, 5]]) self.assertEqual(myobj.explode_left("[[[[", "1"), "[[[[") self.assertEqual(myobj.explode_left("[7,[6,[5,[4,", "3"), "[7,[6,[5,[7,") self.assertEqual(myobj.explode_right("8", ",1],2],3],4]"), ",9],2],3],4]") self.assertEqual(myobj.explode_right("2", "]]]]"), "]]]]") myobj.pair = [[[[[9, 8], 1], 2], 3], 4] self.assertEqual(myobj.explode(), True) self.assertEqual(myobj.pair, [[[[0, 9], 2], 3], 4]) myobj.pair = [7, [6, [5, [4, [3, 2]]]]] self.assertEqual(myobj.explode(), True) self.assertEqual(myobj.pair, [7, [6, [5, [7, 0]]]]) myobj.pair = [[6, [5, [4, [3, 2]]]], 1] self.assertEqual(myobj.explode(), True) self.assertEqual(myobj.pair, [[6, [5, [7, 0]]], 3]) myobj.pair = [[3, [2, [1, [7, 3]]]], [6, [5, [4, [3, 2]]]]] self.assertEqual(myobj.explode(), True) self.assertEqual(myobj.pair, [[3, [2, [8, 0]]], [9, [5, [4, [3, 2]]]]]) self.assertEqual(myobj.explode(), True) self.assertEqual(myobj.pair, [[3, [2, [8, 0]]], [9, [5, [7, 0]]]]) myobj.pair = [[[[0, 7], 4], [15, [0, 13]]], [1, 1]] self.assertEqual(myobj.split(), True) self.assertEqual(myobj.pair, [[[[0, 7], 4], [[7, 8], [0, 13]]], [1, 1]]) self.assertEqual(myobj.split(), True) self.assertEqual(myobj.pair, [[[[0, 7], 4], [[7, 8], [0, [6, 7]]]], [1, 1]]) myobj.pair = [[[[[4, 3], 4], 4], [7, [[8, 4], 9]]], [1, 1]] self.assertEqual(myobj.reduce(), [[[[0, 7], 4], [[7, 8], [6, 0]]], [8, 1]]) myobj.pair = [[[[4, 3], 4], 4], [7, [[8, 4], 9]]] self.assertEqual(myobj.add([1, 1]), [[[[0, 7], 4], [[7, 8], [6, 0]]], [8, 1]]) self.assertEqual(myobj.recursive_magnitude([9, 1]), 29) self.assertEqual(myobj.recursive_magnitude([1, 9]), 21) self.assertEqual(myobj.recursive_magnitude([[9, 1], [1, 9]]), 129) self.assertEqual(myobj.recursive_magnitude([[1, 2], [[3, 4], 5]]), 143) self.assertEqual( myobj.recursive_magnitude([[[[8, 7], [7, 7]], [[8, 6], [7, 7]]], [[[0, 7], [6, 6]], [8, 7]]]), 3488)
def test_number_8_has_value_8(): n = number.Number(8) assert n.value() == 8
def present_operation(self, op1, op2, symbol): n1 = number.Number(int(op1)) n2 = number.Number(int(op2)) if symbol == '+': op = operation.Plus(n1, n2) return op.result()
def process_xlsx(self, is_xlsx): """Process an excel spreadsheet and create a rounded spreadsheet""" import os from openpyxl import load_workbook from openpyxl.styles import PatternFill from openpyxl.comments import Comment FILL_ORANGE = PatternFill(start_color='FFA500', end_color='FFA500', fill_type='solid') FILL_BLUE = PatternFill(start_color='00b8ff', end_color='00b8ff', fill_type='solid') COMMENT_FLOAT = Comment( 'Orange: rounder identified a FLOAT that needed to be rounded', 'DRB_ROUNDER') COMMENT_INTEGER = Comment( 'Blue: rounder identified an INT that needed to be rounded', 'DRB_ROUNDER') first_float_flag = True first_integer_flag = True fname = self.fname # Self.args will only be None when running tests if self.args == None: highlight = False else: highlight = self.args.highlight # Make sure the excel spreadsheet exists if not os.path.exists(fname): rounder_logger.error('ABORT: Excel spreadsheet does not exist') sys.exit(1) # Convert the workbook if needed if is_xlsx == False: helpers.convert_to_xlsx(fname) (base, ext) = os.path.splitext(fname) fname = base + ".xlsx" # Make sure no formulas exist in the spreadsheet if helpers.check_for_excel_formulas(fname): rounder_logger.error( 'ABORT: Excel spreadsheet contains formulas. ' 'Please remove the formulas in the highlighted cells') sys.exit(1) # Apply rounding rules to all cells in spreadsheet wb = load_workbook(fname, data_only=True) # Open the workbook for sheetname in wb.sheetnames: sheet = wb.get_sheet_by_name(sheetname) for cell in sheet.get_cell_collection( ): # reads left to right from top to bottom num = number.Number(str(cell.value)) num.round(fname) if num.needs_rounding == True: if num.method == ROUND4_METHOD: if not highlight: # argument passed to only highlight spreadsheet try: # Successful typecast if no special characters cell.value = float(num.rounded) except ValueError: cell.value = num.rounded cell.fill = FILL_ORANGE if first_float_flag: cell.comment = COMMENT_FLOAT first_float_flag = False elif num.method == COUNTS_METHOD: if not highlight: # argument passed to only highlight spreadsheet if num.rounded == LESS_THAN_15: cell.value = LESS_THAN_15 else: try: # Successful typecast if no special characters cell.value = int(num.rounded) except ValueError: cell.value = num.rounded cell.fill = FILL_BLUE if first_integer_flag: cell.comment = COMMENT_INTEGER first_integer_flag = False # Save the rounded calculations to a new file (base, ext) = os.path.splitext(fname) new_fname = base + "_rounded.xlsx" try: wb.save(new_fname) except PermissionError: rounder_logger.error('ABORT: Could not save. Please close rounded ' 'spreadsheet') sys.exit(1)