def do_stats_overview(self, *args, **params): """ Show tables with stale or empty statistics. """ self.vw_check_database_ready("Database must be healthy and running in order to get stats overview!"); print >> sys.stdout, "Preparing data:\t\t", roller = Roller() roller.start() stdout, stderr = self.call_scenario('stats', owner=self.config.get('db_user', '').upper()) roller.stop('finished') time.sleep(1) self.to_stderr(stderr) stale = [] empty = [] if stdout: segment = None for line in stdout.strip().split("\n"): if line.find('stale objects') > -1: segment = 'stale' continue elif line.find('empty objects') > -1: segment = 'empty' continue line = line.split(" ")[-1].strip() if segment and segment == 'stale': stale.append(line) elif segment and segment == 'empty': empty.append(line) else: print "Ignoring", repr(line) if stale: print >> sys.stdout, "\nList of stale objects:" for obj in stale: print >> sys.stdout, "\t", obj print >> sys.stdout, "\nFound %s stale objects\n" % len(stale) else: print >> sys.stdout, "No stale objects found" if empty: print >> sys.stdout, "\nList of empty objects:" for obj in empty: print >> sys.stdout, "\t", obj print >> sys.stdout, "\nFound %s objects that currently have no statistics.\n" % len(stale) else: print >> sys.stdout, "No empty objects found." if stderr: print >> sys.stderr, "Error dump:" print >> sys.stderr, stderr
def check(): seed = arg_value('seed', 20, type=int) roller = Roller(seed) dc = arg_value('dc', 0, type=int) roll, beats_dc = roller.check(dc=dc, modifier=arg_value('modifier', 0, type=int), critical=arg_value('critical', 20, type=int)) succeeds = "" if dc == 0 else "Succeeds" if beats_dc else "Fails" return jsonify( {'return': "{roll} {succeeds}".format(roll=roll, succeeds=succeeds)}), 200
def processCommand(self, whole_command): """ Method: processCommand Interpret a command """ command_split = whole_command.split(" ") command_word = command_split[0] if command_word == "roll": if len(command_split) == 2: roller_string = command_split[1] roller = Roller(roller_string) return roller.roll() else: raise ClindException( "Error: roll requires exactly one argument") elif command_word == "exit": pass elif command_word == "name": with open("src/names.txt") as names_file: names = list(names_file) return random.choice(names).strip() + " " + random.choice( names).strip() elif command_word == "info": if len(command_split) == 2: topic = command_split[1] endpoint = Info.topics[topic] return Info(endpoint).listResults() else: return Info.listTopics() else: raise ClindException( "Error: command {} not recognized".format(command_word))
def _rst_replace_new_backup(self, backup_dst): """ Replace new backup. """ # Archive into a tgz backup and place it near the cluster print >> sys.stdout, "Restoring from backup:\t ", sys.stdout.flush() # Remove cluster in general print >> sys.stdout, "Remove broken cluster:\t ", sys.stdout.flush() shutil.rmtree(self.config['pcnf_pg_data']) print >> sys.stdout, "finished" sys.stdout.flush() # Unarchive cluster print >> sys.stdout, "Unarchiving new backup:\t ", sys.stdout.flush() roller = Roller() roller.start() destination_tar = backup_dst + "/base.tar.gz" temp_dir = tempfile.mkdtemp(dir=os.path.join(backup_dst, "tmp")) pguid = pwd.getpwnam('postgres')[2] pggid = grp.getgrnam('postgres')[2] os.chown(temp_dir, pguid, pggid) tar_command = '/bin/tar xf %s --directory=%s 2>/dev/null' % (destination_tar, temp_dir) os.system(tar_command) #print tar_command roller.stop("finished") time.sleep(1) print >> sys.stdout, "Restore cluster:\t ", backup_root = self._rst_get_backup_root(temp_dir) mv_command = '/bin/mv %s %s' % (backup_root, os.path.dirname(self.config['pcnf_pg_data']) + "/data") os.system(mv_command) #print mv_command print >> sys.stdout, "finished" sys.stdout.flush() print >> sys.stdout, "Write recovery.conf:\t ", recovery_conf = os.path.join(self.config['pcnf_pg_data'], "recovery.conf") cfg = open(recovery_conf, 'w') cfg.write("restore_command = 'cp " + backup_dst + "/%f %p'\n") cfg.close() # Set recovery.conf correct ownership (SMDBA is running as root at this moment) data_owner = get_path_owner(self.config.get('pcnf_pg_data', PgBackup.DEFAULT_PG_DATA)) os.chown(recovery_conf, data_owner.uid, data_owner.gid) print >> sys.stdout, "finished" sys.stdout.flush()
def do_db_check(self, *args, **params): """ Check full connection to the database. """ print >> sys.stdout, "Checking connection:\t", sys.stdout.flush() roller = Roller() roller.start() login = '******' % (self.config.get('db_user'), self.config.get('db_password'), self.config.get('db_name')) roller.stop(self.get_db_status(login=login).ready and "ready" or "not available") time.sleep(1)
def attacks(): hit_roller = Roller('d20') dmg_seed = arg_value('dmg_seed', 2) attacker = Attack([ Roller("d{dmg}".format(dmg=dmg_seed)) for _ in range(arg_value('n_dmg_rollers', 1)) ], damage_modifier=arg_value('dmg_modifier', 0)) attacks = attacker.attacks(hit_roller, arg_value('n_attacks', 1), risk_buffer=arg_value('risk_buffer', 0), dc=arg_value('dc', 0), modifier=arg_value('hit_modifier', 0), critical=arg_value('critical', 20)) return jsonify({'return': attacker.html_attacks(attacks)}), 200
def _rst_save_current_cluster(self): """ Save current tablespace """ old_data_dir = os.path.dirname(self.config['pcnf_pg_data']) + '/data.old' if not os.path.exists(old_data_dir): os.mkdir(old_data_dir) print >> sys.stdout, "Created \"%s\" directory." % old_data_dir print >> sys.stdout, "Moving broken cluster:\t ", sys.stdout.flush() roller = Roller() roller.start() suffix = '-'.join([str(el).zfill(2) for el in time.localtime()][:6]) destination_tar = old_data_dir + "/data." + suffix + ".tar.gz" tar_command = '/bin/tar -czPf %s %s 2>/dev/null' % (destination_tar, self.config['pcnf_pg_data']) os.system(tar_command) roller.stop("finished") time.sleep(1) sys.stdout.flush()
def game(): prompt = '' while prompt != 'n': prompt = input('Would you like to roll some dice? y/n ') if (prompt.lower() == 'y'): dice_str = input('Enter a dice value in the format XdY\n' ' where x is the number of die and\n' ' y is the number of sides per die\n') pattern = re.compile(r'\d+d\d+') if pattern.match(dice_str) != None: dice = dice_str.split('d') dice_sides = abs(int(dice[1])) num_dice = abs(int(dice[0])) if (dice_sides < 100 and num_dice < 100): roller = Roller(num_dice, dice_sides) print('Rolling . . .\n') sleep(1) roller.roll() print('Here are your rolls\n') print(roller) else: print('Your values are too big, try again') else: print('Try again. The format is XdY')
def vw_check_database_ready(self, message, output_shift=1): """ Check if database is ready. Otherwise crash with the given message. """ print >> sys.stdout, "Checking the database:" + ("\t" * output_shift), roller = Roller() roller.start() dbstatus = self.get_db_status() if dbstatus.ready: roller.stop("running") time.sleep(1) else: roller.stop("failed") time.sleep(1) raise GateException(message);
def _backup_rotate(self): """ Rotate backup by purging the obsolete/expired backup set. This method is internal and needs to be performed on a healthy, ensured database. """ print >> sys.stdout, "Rotating the backup:\t", roller = Roller() roller.start() stdout, stderr = self.call_scenario('rman-hot-backup-roll', target='rman') if stderr: roller.stop("failed") time.sleep(1) self.to_stderr(stderr) if stdout: roller.stop("finished") time.sleep(1)
def do_stats_refresh(self, *args, **params): """ Gather statistics on SUSE Manager database objects. """ self.vw_check_database_ready("Database must be healthy and running in order to get statistics of it!"); print >> sys.stdout, "Gathering statistics on SUSE Manager database...\t", roller = Roller() roller.start() stdout, stderr = self.call_scenario('gather-stats', owner=self.config.get('db_user', '').upper()) if stdout and stdout.strip() == 'done': roller.stop('finished') else: roller.stop('failed') time.sleep(1) self.to_stderr(stderr)
def set_archivelog_mode(self, status=True): """ Set archive log mode status. """ print >> sys.stdout, ("Turning %s archivelog mode...\t" % (status and 'on' or 'off')), sys.stdout.flush() roller = Roller() roller.start() stdout, stderr = None, None success, failed = "done", "failed" if status: destination = os.environ['ORACLE_BASE'] + "/oradata/" + os.environ['ORACLE_SID'] + "/archive" stdout, stderr = self.call_scenario('ora-archivelog-on', destination=destination) else: stdout, stderr = self.call_scenario('ora-archivelog-off') success, failed = "failed", "done" if self.get_archivelog_mode(): roller.stop(success) else: roller.stop(failed) time.sleep(1)
def do_db_stop(self, *args, **params): """ Stop SUSE Manager database. """ print >> sys.stdout, "Stopping the SUSE Manager database..." sys.stdout.flush() print >> sys.stdout, "Stopping listener:\t", sys.stdout.flush() roller = Roller() roller.start() dbstatus = self.get_status() if dbstatus.ready: self.do_listener_stop(*['quiet']) roller.stop("done") time.sleep(1) else: roller.stop("not running") time.sleep(1) print >> sys.stdout, "Stopping core:\t\t", sys.stdout.flush() roller = Roller() roller.start() dbstatus = self.get_db_status() if not dbstatus.ready: roller.stop("failed") time.sleep(1) raise GateException("Error: database core is already offline.") stdout, stderr = self.syscall("sudo", None, None, "-u", "oracle", self.ora_home + "/bin/dbshut") if stderr: roller.stop("failed") time.sleep(1) else: roller.stop("done") time.sleep(1) if stderr: print >> sys.stderr, "\nError dump:" print >> sys.stderr, stderr + "\n"
def do_db_start(self, *args, **params): """ Start SUSE Manager database. """ print >> sys.stdout, "Starting listener:\t", sys.stdout.flush() roller = Roller() roller.start() dbstatus = self.get_status() if dbstatus.ready: roller.stop('failed') time.sleep(1) raise GateException("Error: listener is already running") else: self.do_listener_start('quiet') roller.stop('done') time.sleep(1) print >> sys.stdout, "Starting core...\t", sys.stdout.flush() roller = Roller() roller.start() stdout, stderr = self.syscall("sudo", None, None, "-u", "oracle", self.ora_home + "/bin/dbstart") roller.stop('done') time.sleep(1) return if stdout and stdout.find("Database opened") > -1 \ and stdout.find("Database mounted") > -1: roller.stop('done') time.sleep(1) else: roller.stop('failed') time.sleep(1) print >> sys.stderr, "Output dump:" print >> sys.stderr, stdout if stderr: print >> sys.stderr, "Error dump:" print >> sys.stderr, stderr
def do_space_reclaim(self, *args, **params): """ Free disk space from unused object in tables and indexes. """ self.vw_check_database_ready("Database must be healthy and running in order to reclaim the used space!"); print >> sys.stdout, "Examining the database...\t", roller = Roller() roller.start() stdout, stderr = self.call_scenario('shrink-segments-advisor') stderr = None if stderr: roller.stop('failed') time.sleep(1) print >> sys.stderr, "Error dump:" print >> sys.stderr, stderr return else: roller.stop('done') time.sleep(1) print >> sys.stdout, "Gathering recommendations...\t", roller = Roller() roller.start() # get the recomendations stdout, stderr = self.call_scenario('recomendations') if not stdout and not stderr: roller.stop("finished") time.sleep(1) print >> sys.stdout, "\nNo space reclamation possible at this time.\n" return elif stdout: roller.stop("done") time.sleep(1) else: roller.stop("failed") time.sleep(1) print >> sys.stderr, "Error dump:" print >> sys.stderr, stderr messages = { 'TABLE' : 'Tables', 'INDEX' : 'Indexes', 'AUTO' : 'Recommended segments', 'MANUAL' : 'Non-shrinkable tablespace', } tree = {} wseg = 0 if stdout: lines = [tuple(filter(None, line.strip().replace("\t", " ").split(" "))) for line in stdout.strip().split("\n")] for ssm, sname, rspace, tsn, stype in lines: tsns = tree.get(tsn, {}) stypes = tsns.get(stype, {}) ssms = stypes.get(ssm, []) ssms.append((sname, int(rspace),)) wseg = len(sname) > wseg and len(sname) or wseg stypes[ssm] = ssms tsns[stype] = stypes tree[tsn] = tsns total = 0 for tsn in tree.keys(): print >> sys.stdout, "\nTablespace:", tsn for obj in tree[tsn].keys(): print >> sys.stdout, "\n\t" + messages.get(obj, "Object: " + obj) for stype in tree[tsn][obj].keys(): typetotal = 0 print >> sys.stdout, "\t" + messages.get(stype, "Type: " + stype) for segment, size in tree[tsn][obj][stype]: print >> sys.stdout, "\t\t", \ (segment + ((wseg - len(segment)) * " ")), \ "\t", '%.2fM' % (size / 1024. / 1024.) total += size typetotal += size total_message = "Total " + messages.get(obj, '').lower() print >> sys.stdout, "\n\t\t", \ (total_message + ((wseg - len(total_message)) * " ")), \ "\t", '%.2fM' % (typetotal / 1024. / 1024.) print >> sys.stdout, "\nTotal reclaimed space: %.2fGB" % (total / 1024. / 1024. / 1024.) # Reclaim space if tree: for tsn in tree.keys(): for obj in tree[tsn].keys(): if tree[tsn][obj].get('AUTO', None): print >> sys.stdout, "\nReclaiming space on %s:" % messages[obj].lower() for segment, size in tree[tsn][obj]['AUTO']: print >> sys.stdout, "\t", segment + "...\t", sys.stdout.flush() stdout, stderr = self.syscall("sudo", self.get_scenario_template().replace('@scenario', self.__get_reclaim_space_statement(segment)), None, "-u", "oracle", "/bin/bash") if stderr: print >> sys.stdout, "failed" print >> sys.stderr, stderr else: print >> sys.stdout, "done" print >> sys.stdout, "Reclaiming space finished"
def do_backup_restore(self, *args, **params): """ Restore the SUSE Manager database from backup. @help force\t\t\tShutdown database prior backup, if running. start\t\t\tAttempt to start a database after restore. --strategy=<value>\tManually force strategry 'full' or 'partial'. Don't do that. """ dbid = self.get_dbid() scenario = { 'full':'rman-recover-ctl', 'partial':'rman-recover', } # Control file still around? strategy = None if params.get("strategy") in ['full', 'partial']: strategy = params.get("strategy") elif params.get("strategy") is not None: raise GateException("Unknown value %s for option 'strategy'. Please read 'help' first." % params.get("strategy")) if not strategy: strategy = "full" db_path = os.environ['ORACLE_BASE'] + "/oradata/" + os.environ['ORACLE_SID'] for fname in os.listdir(db_path): if fname.lower().endswith(".ctl"): strategy = "partial" break print >> sys.stdout, ("Restoring the SUSE Manager Database using %s strategy" % strategy) # Could be database just not cleanly killed # In this case great almighty RMAN won't connect at all and just crashes. :-( self.do_db_start() self.do_db_stop() print >> sys.stdout, "Preparing database:\t", roller = Roller() roller.start() dbstatus = self.get_db_status() if dbstatus.ready: if 'force' in args: roller.stop("running") time.sleep(1) self.do_db_stop() else: roller.stop("failed") time.sleep(1) raise GateException("Database must be put offline. Or use options (run \"help\" for this procedure).") else: roller.stop("success") time.sleep(1) print >> sys.stdout, "Restoring from backup:\t", roller = Roller() roller.start() stdout, stderr = self.call_scenario(scenario[strategy], target='rman', dbid=str(dbid)) if stderr: roller.stop("failed") time.sleep(1) print >> sys.stderr, "Error dump:" print >> sys.stderr, stderr if stdout: roller.stop("finished") time.sleep(1) self.do_db_stop() if 'start' in args: self.do_db_start() self.do_listener_status()
def do_backup_hot(self, *args, **params): """ Perform hot backup on running database. """ #if not params.get('backup-dir'): # raise Exception("\tPlease run this as \"%s backup-hot help\" first." % sys.argv[0]) #if not os.path.exists(params.get('backup-dir')): # print >> sys.stdout, "Creating \"%s\" path" % params.get('backup-dir') # utils.create_dirs(params.get('backup-dir'), "oracle") #owner = utils.get_path_owner(params.get('backup-dir')) #if owner.user != 'oracle': # raise Exception("\tDirectory \"%s\" does not have proper permissions!" % params.get('backup-dir')) self.vw_check_database_ready("Database must be healthy and running in order to take a backup of it!"); # Check DBID is around all the time (when DB is healthy!) self.get_dbid(known_db_status=True) if not self.get_archivelog_mode(): raise GateException("Archivelog is not turned on.\n\tPlease shutdown SUSE Manager and run system-check first!") print >> sys.stdout, "Backing up the database:\t", roller = Roller() roller.start() #stdout, stderr = self.call_scenario('rman-hot-backup', target='rman', backupdir=params.get('backup-dir')) stdout, stderr = self.call_scenario('rman-hot-backup', target='rman') if stderr: roller.stop("failed") time.sleep(1) print >> sys.stderr, "Error dump:" print >> sys.stderr, stderr if stdout: roller.stop("finished") time.sleep(1) files = [] arclogs = [] for line in stdout.split("\n"): line = line.strip() if line.startswith("input") and line.find('datafile') > -1: files.append(line.split("name=")[-1]) elif line.startswith("archived"): arclogs.append(line.split("name=")[-1].split(" ")[0]) print >> sys.stdout, "Data files archived:" for f in files: print >> sys.stdout, "\t" + f print >> sys.stdout print >> sys.stdout, "Archive logs:" for arc in arclogs: print >> sys.stdout, "\t" + arc print >> sys.stdout # Finalize self.autoresolve_backup() hb, fb, ha, fa = self.check_backup_info() print >> sys.stdout, "Backup summary as follows:" if len(hb): print >> sys.stdout, "\tBackups:" for bkp in hb: print >> sys.stdout, "\t\t", bkp.handle print >> sys.stdout if len(ha): print >> sys.stdout, "\tArchive logs:" for bkp in ha: print >> sys.stdout, "\t\t", bkp.handle print >> sys.stdout if len(fb): print >> sys.stderr, "WARNING! Broken backups has been detected:" for bkp in fb: print >> sys.stderr, "\t\t", bkp.handle print >> sys.stderr if len(fa): print >> sys.stderr, "WARNING! Broken archive logs has been detected:" for bkp in fa: print >> sys.stderr, "\t\t", bkp.handle print >> sys.stderr print >> sys.stdout, "\nFinished."
def do_backup_purge(self, *args, **params): """ Purge all backups. Useful after successfull reliable recover from the disaster. """ self.vw_check_database_ready("Database must be healthy and running in order to purge assigned backups of it!"); print >> sys.stdout, "Checking backups:\t", roller = Roller() roller.start() info = self.get_backup_info() if not len(info): roller.stop("failed") time.sleep(1) print >> sys.stderr, "No backup snapshots available." sys.exit(1) roller.stop("finished") time.sleep(1) print >> sys.stdout, "Removing %s backup%s:\t" % (len(info), len(info) > 1 and 's' or ''), roller = Roller() roller.start() stdout, stderr = self.call_scenario('rman-backup-purge', target='rman') if stderr: roller.stop("failed") time.sleep(1) print >> sys.stderr, "Error dump:" print >> sys.stderr, stderr roller.stop("finished") time.sleep(1)
def do_backup_list(self, *args, **params): """ List of available backups. """ self.vw_check_database_ready("Database must be running and ready!", output_shift=2) roller = Roller() roller.start() print >> sys.stdout, "Getting available backups:\t", class InfoNode:pass infoset = [] stdout, stderr = self.call_scenario('rman-list-backups', target='rman') roller.stop("finished") time.sleep(1) if stdout: for chunk in filter(None, [re.sub('=+', '', c).strip() for c in stdout.split("\n=")[-1].split('BS Key')]): try: info = InfoNode() info.files = [] piece_chnk, files_chnk = chunk.split('List of Datafiles') # Get backup place for line in [l.strip() for l in piece_chnk.split("\n")]: if line.lower().startswith('piece name'): info.backup = line.split(" ")[-1] if line.lower().find('status') > -1: status_line = filter(None, line.replace(':', '').split("Status")[-1].split(" ")) if len(status_line) == 5: info.status = status_line[0] info.compression = status_line[2] info.tag = status_line[4] # Get the list of files cutoff = True for line in [l.strip() for l in files_chnk.split("\n")]: if line.startswith('-'): cutoff = None continue else: line = filter(None, line.split(" ")) if len(line) > 4: if line[0] == 'File': continue dbf = InfoNode() dbf.type = line[1] dbf.file = line[-1] dbf.date = line[-2] info.files.append(dbf) infoset.append(info) except: print >> sys.stderr, "No backup snapshots available." sys.exit(1) # Display backup data if (infoset): print >> sys.stdout, "Backups available:\n" for info in infoset: print >> sys.stdout, "Name:\t", info.backup print >> sys.stdout, "Files:" for dbf in info.files: print >> sys.stdout, "\tType:", dbf.type, print >> sys.stdout, "\tDate:", dbf.date, print >> sys.stdout, "\tFile:", dbf.file print >> sys.stdout if stderr: print >> sys.stderr, "Error dump:" print >> sys.stderr, stderr
from random import randint from roller import Roller from attack import Attack x = Attack([Roller('d6'), Roller('d6'), Roller('d6')], damage_modifier=2) hit_roller = Roller('d20') for i in x.attacks(hit_roller, 10, dc=0, modifier=3, critical=18): print(i)
import os import discord import re from roller import Roller PREFIX = "::" # The prefix used for commands client = discord.Client() # The bot client roller = Roller() # The roller @client.event async def on_message(message): """ Handle messages to initialize the roller message - the message that was sent """ # Convert message to lower case and strip whitespace command = message.content.lower() command = re.sub("\\s+", "", command) if command == PREFIX + "roll": # Main command to start the roller await roller.start_roll(message.channel) elif command == PREFIX + "ping": # Ping command to check if the bot is still alive await message.channel.send("Pong!")
def do_backup_hot(self, *args, **params): """ Perform hot backup on running database. """ self.vw_check_database_ready("Database must be healthy and running in order to take a backup of it!"); # Check DBID is around all the time (when DB is healthy!) self.get_dbid(known_db_status=True) if not self.get_archivelog_mode(): raise GateException("Archivelog is not turned on.\n\tPlease shutdown SUSE Manager and run system-check first!") print >> sys.stdout, "Backing up the database:\t", roller = Roller() roller.start() stdout, stderr = self.call_scenario('rman-hot-backup', target='rman') if stderr: roller.stop("failed") time.sleep(1) self.to_stderr(stderr) if stdout: roller.stop("finished") time.sleep(1) files = [] arclogs = [] for line in stdout.split("\n"): line = line.strip() if line.startswith("input") and line.find('datafile') > -1: files.append(line.split("name=")[-1]) elif line.startswith("archived"): arclogs.append(line.split("name=")[-1].split(" ")[0]) print >> sys.stdout, "Data files archived:" for f in files: print >> sys.stdout, "\t" + f print >> sys.stdout print >> sys.stdout, "Archive logs:" for arc in arclogs: print >> sys.stdout, "\t" + arc print >> sys.stdout # Rotate and check self.autoresolve_backup() self._backup_rotate() # Finalize hb, fb, ha, fa = self.check_backup_info() print >> sys.stdout, "Backup summary as follows:" if len(hb): print >> sys.stdout, "\tBackups:" for bkp in hb: print >> sys.stdout, "\t\t", bkp.handle print >> sys.stdout if len(ha): print >> sys.stdout, "\tArchive logs:" for bkp in ha: print >> sys.stdout, "\t\t", bkp.handle print >> sys.stdout if len(fb): print >> sys.stderr, "WARNING! Broken backups has been detected:" for bkp in fb: print >> sys.stderr, "\t\t", bkp.handle print >> sys.stderr if len(fa): print >> sys.stderr, "WARNING! Broken archive logs has been detected:" for bkp in fa: print >> sys.stderr, "\t\t", bkp.handle print >> sys.stderr print >> sys.stdout, "\nFinished."
from parser import Parser from dice_symbols import dice_symbol_table, dice_token_gen from lis import Environment, standard_env, exec from roller import Roller roller = Roller() parser = Parser(dice_token_gen, dice_symbol_table()) def dice_env(): env = Environment((), (), standard_env()) env.update({ 'd': roller.d_roll, 'z': roller.z_roll, '+': lambda left, right: roller.math(left, right, '+'), '-': lambda left, right: roller.math(left, right, '-'), '*': lambda left, right: roller.math(left, right, '*'), '/': lambda left, right: roller.math(left, right, '/'), '/+': lambda left, right: roller.math(left, right, '/+'), '/-': lambda left, right: roller.math(left, right, '/-'), '<': lambda left, right: roller.compare(left, right, '<'), '<=': lambda left, right: roller.compare(left, right, '<='), '>': lambda left, right: roller.compare(left, right, '>'), '>=': lambda left, right: roller.compare(left, right, '>='), '=': lambda left, right: roller.compare(left, right, '='), '==': lambda left, right: roller.compare(left, right, '=='), '!=': lambda left, right: roller.compare(left, right, '!='), "H": roller.highest, "L": roller.lowest, "finalize": roller.finalize }) return env
from roller import Roller print("welcome to the random dice.py emulator\n") roller = Roller() while True: char = input("r: roll, q: quit, m: change the range\n") roller.dispatch(char)