def friendlyNameEdit(self): option = input("\nType in your chosen friendly name for the pin (max 10 characters) ") # If friendly name is within character limit, set it. Otherwise, show error if len(option) <= 10: self.friendlyName = option else: common.other()
def init(): # Create instance of process class data = Process() # Only continue if valid data has been selected if data.valid is True: try: while True: # Print Current Data data.currentData() option = input( "\nPost Process Menu: \nChoose a Option (based on the corresponding number): " "\n1. Filter (Work in Progress)\n2. Compress\n3. Plot\n4. Save File" "\n----------------\n5. Back\n\nOption Chosen: ") if option == "1": data.filter() elif option == "2": data.compress() elif option == "3": data.plotSettings() elif option == "4": data.pandasExit() elif option == "5": common.back() else: common.other() except StopIteration: pass
def hostnameSelect(self): # Print Title print("Logger Hostnames Available (set in progConf.ini):") # Print Hostnames in dict for no in self.hostnamesList: print("{}. {}".format(no, self.hostnamesList[no])) # Hostname Selection while self.host is None: option = input( "\nSelect the Hostname (by its corresponding number) of the Logger you wish to Use: " ) try: # Check to see value can be chosen - note the numbers listed start at 1 but lists in python start at 0 if 0 < int(option) <= len(self.hostnamesList): self.host = self.hostnamesList[option] print( "Success! - Hostname Set to: '{}' - To change hostname, restart this program" .format(self.host)) # Update window title with the hostname ctypes.windll.kernel32.SetConsoleTitleW("{} - {}".format( self.welcomeMessage, self.host)) # When Integer is out of Range else: common.other() # If someone does not put in an integer except ValueError: common.other()
def plotSettings(self): # Menu for selecting options for user to choose what the grap1h Looks Like try: while True: # Print options and current settings option = input( "\nPlot Options - Current Settings: \nChoose a Option to change a setting" " (based on the corresponding number): " "\n1. Select Data\n2. Plot Title: '{}'\n3. Primary Y Axis Title: '{}'" "\n4. Secondary Y Axis Title: '{}'\n5. Plot " "\n----------------\n6. Back\n\nOption Chosen: ".format( self.plotTitle, self.plotYPrimaryTitle, self.plotYSecondaryTitle)) if option == "1": self.plotSelectData() elif option == "2": # Change Title of Graph self.plotTitle = input("\nInput the Graph Title: ") elif option == "3": # Change Primary Y Axis Title self.plotYPrimaryTitle = input( "\nInput the Primary Y Axis Title: ") elif option == "4": # Change Secondary Y Axis Title self.plotYSecondaryTitle = input( "\nInput the Secondary Y Axis Title: ") elif option == "5": self.plotGraph() elif option == "6": common.back() else: common.other() except StopIteration: pass
def compress(self): try: # Find out what user wants the compression time num = float( input("Type in the new logging interval desired in Seconds: ")) # Set Index to column with time interval (By getting heading name of second column in process) self.df.set_index(self.df.columns[1], inplace=True) # Resample Date/Time, then the rest. Do this on two separate dataframes dfComp1 = self.df.iloc[:, 0].resample(str(num) + 'S').first() # Change '.mean' to whatever function you wish from the following URL: # (http://pandas.pydata.org/pandas-docs/stable/groupby.html#groupby-dispatch) dfComp2 = self.df.iloc[:, 1:].resample(str(num) + 'S').mean() # Combine the dataframes and set equal to the original one self.df = pd.concat([dfComp1, dfComp2], axis=1) # Remove Index self.df.reset_index(inplace=True) # Reset Column Positioning (move Time-Interval back to position 2) cols = list(self.df.columns.values) cols[0], cols[1] = cols[1], cols[0] self.df = self.df[cols] except ValueError: common.other()
def menu(): try: while True: option = input( "\nLogger Config Menu: \nChoose a Option (based on the corresponding number): " "\n1. General Settings\n2. Input Setup\n3. Save and Upload Config\n4. Save Config (Don't Upload)" "\n5. Import Stored Config\n6. Back\n\nOption Chosen: ") # Set Menu Names if option == "1": generalMenu() elif option == "2": inputSetup() elif option == "3": # Runs save function - and returns 'True' if the save failed for some reason # Used so it doesn't upload a file if the save was unsuccessful saveFailed = save() if saveFailed is True: print("ERROR - Save Upload Failed") else: upload() elif option == "4": save() elif option == "5": configImportSelect() elif option == "6": # Warn users that unsaved changes will be lost print("\nWARNING: Any unsaved changes will be lost on program close!\n") common.back() else: common.other() except StopIteration: pass
def pvs(self, p, game, depth, alpha, beta, color): if game.gamewon(other(p), game.prev_playing_subboard()): return 0, color * -1000 # p has lost elif game.gamewon(p, game.prev_playing_subboard()): return 0, color * 1000 if depth == 0: total_score = 0 for i in range(1, 10): total_score += self.eval(p, game.board[i]) #print(f'total val: {total_val}') return 0, total_score best_move = 0 moves = self.legal(game.curr_playing_subboard()) for i in range(len(moves)): game.place_move(p, moves[i]) if i == 0: _, score = self.pvs(other(p), game, depth - 1, -beta, -alpha, -color) score *= -1 else: _, score = self.pvs(other(p), game, depth - 1, -alpha - 1, -alpha, -color) score *= -1 if alpha < score < beta: _, score = self.pvs(other(p), game, depth - 1, -beta, -score, -color) score *= -1 game.retract_prev_move() if score > alpha: alpha = score best_move = moves[i] if alpha >= beta: break return best_move, alpha
def scaleEdit(self): # Set the high and low end of the scale try: option = float(input("\nWhat is the Low end of the Scale (Excluding Units)? ")) self.scaleLow = option option = float(input("What is the High end of the Scale (Excluding Units)? ")) self.scaleHigh = option except ValueError: common.other()
def inputTypeEdit(self): # List of input Types (this can be updated and the code will continue to work) print("\nAvailable Input Types:") for pos, value in enumerate(inputTypes, start=1): print("{}. {}".format(pos, value)) option = input("\n(Note - To change available input types please edit 'progConf.ini'" "\nSelect an option by its corresponding number: ") try: # Check to see value can be chosen - note the numbers listed start at 1 but lists in python start at 0 if 0 < int(option) <= len(inputTypes): self.inputType = inputTypes[int(option) - 1] print("Success!") else: common.other() # If someone does not put in an integer except ValueError: common.other()
def negamax(self, p, game, depth, alpha, beta): curr_subboard_num = game.last_move() alpha_orig = alpha # See if this state is present in the transpoition table state_tuple = tuple(map(tuple, game.board)) entry = (state_tuple, curr_subboard_num) ttEntry = self.table.get(entry) if ttEntry is not None: entryDepth, flag, entryValue, entryMove = ttEntry if entryDepth >= depth: if flag == self.EXACT: return entryValue, entryMove elif flag == self.LOWERBOUND: alpha = self.max(alpha, entryValue) elif flag == self.UPPERBOUND: beta = self.min(beta, entryValue) if alpha >= beta: return entryValue, entryMove # continue with normal negamax if game.won(p): return 1000, 0 elif game.won(other(p)): return -1000, 0 if depth == 0: return self.eval_board(p, game) curr_subboard = game.curr_playing_subboard() possibleMoves = self.legal(curr_subboard) if len(possibleMoves) == 0: return 0 v = -self.INF best_move = 0 for move in possibleMoves: game.place_move(game.whose_turn(), move) currValue, _ = self.negamax(p, game, depth - 1, -beta, -alpha) currValue *= -1 if currValue > v: v = currValue m[0] = move game.retract_prev_move() alpha = max(alpha, v) if alpha >= beta: break # Add this state entry to the table if alpha <= alphaOrig: flag = self.UPPERBOUND elif alpha >= beta: flag = self.LOWERBOUND else: flag = self.EXACT # [state, curr_subboard_num] = (depth, flag, value, bestMove) self.table[stateTuple] = (depth, flag, alpha, m[0]) return alpha
def generalTime(): # Print Current time Interval print("\nCurrent Time Interval is: {} second(s)\n".format(generalSettings["timeinterval"])) # Get user to input new time interval and check it's valid try: interval = float(input("Enter New Time Interval (min 0.1): ")) # Only change time interval if a valid int above 0.1 seconds # (note this will not stop users editing the config for time intervals less than 0.1 seconds if interval >= 0.1: generalSettings["timeinterval"] = interval print("Success!\n") else: common.other() print("NOTE: Time intervals less than 0.1 seconds can be configured by manually editing logConf.ini " "before importing.\nThis is beyond the specification of the logger so do so at your own risk!") except ValueError: common.other()
def alphabeta(self, p, game, depth, alpha, beta): #print(f'player {p}: depth {depth}, alpha {alpha}, beta {beta}') prev_state = game.prev_playing_subboard() #if game.gamewon(p,prev_state): return game.last_move(), 1000 # p has won if game.gamewon(other(p), prev_state): return 0, -1000 # p has lost if depth == 0: return 0, self.eval_board(p, game) best_move = 0 for move in self.legal(game.curr_playing_subboard()): game.place_move(p, move) _, v = self.alphabeta(other(p), game, depth - 1, -beta, -alpha) game.retract_prev_move() val = -v if val >= beta: return move, val elif alpha < val and val < beta: alpha = val best_move = move return best_move, alpha
def init(): try: while True: # Set Menu Names option = input( "\nLogger Control Menu: \nChoose a Option (based on the corresponding number): " "\n1. Change Logger Configuration" "\n2. Back\n3. Quit" "\n\nOption Chosen: ") if option == "1": config.init() elif option == "2": common.back() elif option == "3": common.quit() else: common.other() except StopIteration: pass
def fileSelect(self): # Create list of CSV files with 'converted' in name self.csvList = [ fileName for fileName in self.csvDirContents if fileName.endswith('.csv') and fileName.startswith('converted') ] # Dealing with cases where there are no matching files in directory if len(self.csvList) <= 0: print( "\nNo Data Found - Please ensure there is at least 1 'convertedXXX.csv' file in the folder" ) # Setting the var false makes the self.fileSelect function not run and stops the program self.valid = False else: try: # Data Selection List print("\nData Found in '{}' - Current Files:".format( self.csvDirectory)) # Print Output in nice format for pos, fileName in enumerate(self.csvList, start=1): print("{}. {}".format(pos, fileName)) # User Selection option = int( input( "Please select a file (by its corresponding number): " )) # If number valid on list, choose that CSV file if 0 < option <= len(self.csvList): # Set filepath to open and with it the filepath/directories for processed data self.convertedCsvFile = self.csvList[option - 1] self.convertedCsvFilePath = self.csvDirectory + "/" + self.convertedCsvFile self.processedCsvFile = self.convertedCsvFile.replace( "converted", "processed") self.processedCsvFilePath = self.csvDirectory + "/" + self.processedCsvFile # If a number is typed in out of range else: common.other() self.valid = False # If a user doesn't type in an integer except ValueError: common.other() self.valid = False
def configImportSelect(): # Set Directory of config files directory = 'files/storedConfigs/' # Create list of all files in directory directoryFiles = os.listdir(directory) configList = [fileName for fileName in directoryFiles if fileName.endswith('.ini')] # Dealing with cases where there are no matching files in directory if len(configList) <= 0: print("\nNo Config Files found - " "Please ensure there is at least 1 file ending in '.ini' in '{}'".format(directory)) else: try: # List config files found print("\nFiles ending in '.ini' found in '{}':".format(directory)) # Print Output in nice format for pos, fileName in enumerate(configList, start=1): print("{}. {}".format(pos, fileName)) # User file selection configFile = int(input("Please select a file (by its corresponding number): ")) # If number valid on list, choose that config file if 0 < configFile <= len(configList): # Warn users of risk of importing a new file option = input("\nWARNING: Importing a new config will erase currently imported Settings!" " - Make sure you save your current configuration before importing new settings" "\nDo You Wish to Continue? (Y/N): ") if option == "Y" or option == "y": # Call function to import config at new directory # Placing the function inside print will print a success message at the end print(importConfInit(directory + fileName)) elif option == "N" or option == "n": print("Import Cancelled") else: print("Invalid Option: Import Cancelled") # If a number is typed in out of range else: common.other() # If a user doesn't type in an integer except ValueError: common.other()
def generalMenu(): try: while True: print("\nConfig: General Settings: \nChoose a Option to edit a Setting (based on the corresponding number)") x = 0 for key in generalSettings: x += 1 print("{}. {}: {}".format(x, key.title(), generalSettings[key])) print("----------------\n{}. Back".format(x + 1)) option = input("\nOption Chosen: ") if option == "1": generalTime() elif option == "2": generalName() elif option == "3": common.back() else: common.other() except StopIteration: pass
def gainEdit(self): # Values for Gain can be changed below although this should not need to happen # Users are instructed to type a number which corresponds to the value of gain they want gainSettings = [1, 2, 4, 8, 16] print("\nAvailable Gain Settings (See User Manual for More Info):") print("|Gain|Full Scale Voltage|") print("-" * 25) print("|1 | 4.096V |\n|2 | 2.048V |\n|4 " "| 1.024V |\n|8 | 0.512V |\n|16 | 0.256V |") option = input("\nPlease type in the gain setting you want: ") try: # Check to see value can be chosen - note the numbers listed start at 1 but lists in python start at 0 if option in gainSettings: self.gain = option print("Success!") else: common.other() # If someone does not put in an integer except ValueError: common.other()
def init(): try: while True: option = input("\nProcess Data Menu: \nChoose a Option (based on the corresponding number): " "\n1. Download Data\n2. Convert Data\n3. Post Process Data" "\n4. Back\n5. Quit \n\nOption Chosen: ") # Set Menu Names if option == "1": download.init() elif option == "2": process.init() elif option == "3": postProcess.init() elif option == "4": common.back() elif option == "5": common.quit() else: common.other() except StopIteration: pass
def unitEdit(self): # List of Unit Types (from progConf.ini) print("\nAvailable Unit Types:") for pos, value in enumerate(unitTypes, start=1): print("{}. {}".format(pos, value)) # Print one more option using list length for custom input print("{}\n{}. Custom Input".format("-" * 15, len(unitTypes) + 1)) option = input("\nSelect an option by its corresponding number: ") try: # Check to see value can be chosen - note the numbers listed start at 1 but lists in python start at 0 if 0 < int(option) <= len(unitTypes): self.unit = unitTypes[int(option) - 1] print("Success!") elif int(option) == len(unitTypes) + 1: entry = input("\nPlease type in the unit you want to use (Max 7 Characters)" "\n(Note: If you want to add your unit to the default list, " "please edit 'progConf.ini')" "\nUnit: ") # If unit is within character limit, set it. Otherwise, show error if len(entry) <= 9: self.unit = entry print("Success!") else: common.other() # When Integer is out of Range else: common.other() # If someone does not put in an integer except ValueError: common.other()
def fileSelect(self): # Dealing with cases where there are no matching files in directory if len(self.fileSelection) <= 0: print( "\nNo Data Found - Please ensure there is at least 1 matching raw.csv and logConf.ini file " "inside the inbox directory.") # Setting the var false prevents self.filePathLinker from running and exists the process module self.valid = False else: # Print the data found in the folder print( "\nData Found in '{}' - The Datestamps of the files are shown Below:" .format(self.inboxDirectory)) for pos, value in enumerate(self.fileSelection, start=1): print("{}. {}".format(pos, value[0])) # Option Selection try: option = int( input( "\nPlease select a file (by its corresponding number): " )) # Check to see value can be chosen - note the numbers listed start at 1 but lists in python start at 0 if 0 < option <= len(self.fileSelection): # Allow user to put in custom name customName = str(input("Chosen Name for the CSV file: ")) # Get timestamp of filename and combine with customName to create new filename timeStamp = self.fileSelection[option - 1][0] self.chosenID = "-{}-{}".format(timeStamp, customName) # Setting the filenames - note these are not the complete file paths self.rawCsvFile = self.fileSelection[option - 1][1] self.configFile = self.fileSelection[option - 1][2] # Works out filename for converted CSV file self.convertedCsvFile = "converted" + self.chosenID + ".csv" else: common.other() self.valid = False # If someone does not put in an integer except ValueError: common.other() self.valid = False
def main(): try: while True: option = input( "\nMain Menu: \nChoose a Option (based on the corresponding number):" "\n1. Logger Control & Config\n2. Download & Process Data \n3. General Settings \n4. About \n5. Quit" "\n\nOption Chosen: ") # Set Menu Names if option == "1": logCtrl.init() elif option == "2": processData.init() elif option == "3": generalSettings.init() elif option == "4": about.init() elif option == "5": common.quit() else: common.other() # Used to break the loop if someone selects a back option. # No back option as this is root menu: this is left here for sake of consistency with other menus. except StopIteration: pass
def inputSetup(): try: # Stay in input selection until user leaves pressing 'Enter' while True: try: # Current Settings Print Out inputCurrentSettings() userInput = input("\nType the number corresponding to the pin you wish to Edit " "or press 'Enter' to go back: ") if str(userInput) == '': print("Going Back") common.back() # Find on adcDict if number is in adcDict, else throw an error # If Found in adcDict, set the device to adcDict and continue elif int(userInput) > 0 and int(userInput) - 1 < len(adcDict): chosenNum = int(userInput) chosenPin = list(adcDict.items())[chosenNum - 1][0] # Input Selection Menu try: while True: print( "\nCurrent Pin Settings for: {}" "\nChoose a Option to edit a Setting (based on the corresponding number)" "\n1. Pin Enabled: {}\n2. Friendly Name: {}\n3. Input Type: {}\n4. Gain: {}\n" "5. Scale: {} - {}\n6. Unit: {}" "\n----------------\n7. Back".format( chosenPin, adcDict[chosenPin].enabled, adcDict[chosenPin].friendlyName, adcDict[chosenPin].inputType, adcDict[chosenPin].gain, adcDict[chosenPin].scaleLow, adcDict[chosenPin].scaleHigh, adcDict[chosenPin].unit)) option = input("\nOption Chosen: ") if option == "1": adcDict[chosenPin].enabledEdit() elif option == "2": adcDict[chosenPin].friendlyNameEdit() elif option == "3": adcDict[chosenPin].inputTypeEdit() elif option == "4": adcDict[chosenPin].gainEdit() elif option == "5": adcDict[chosenPin].scaleEdit() elif option == "6": adcDict[chosenPin].unitEdit() elif option == "7": common.back() else: common.other() except StopIteration: pass else: common.other() # If someone doesn't type in an integer or press Enter except ValueError: common.other() # Used to break the loop if someone selects a back option. except StopIteration: pass
def parse(self, string): if "(" in string: command, args = string.split("(") args = args.split(")")[0] args = args.split(",") else: command, args = string, [] if command == "start": if args[0] == "x" or args[0] == "X": self.player = CROSS else: self.player = NAUGHT elif command == "second_move": self.game.place_move(CROSS, int(args[1]), int(args[0])) move = self.agent.play(NAUGHT, self.game) self.game.place_move(NAUGHT, move) return move elif command == "third_move": # place the move that was generated for us self.game.place_move(CROSS, int(args[1]), int(args[0])) # place their last move self.game.place_move(NAUGHT, int(args[2])) # search & place next move move = self.agent.play(CROSS, self.game) self.game.place_move(CROSS, move) return move elif command == "next_move": #print(f'player {other(self.player)}: {int(args[0])}') self.game.place_move(other(self.player), int(args[0])) #self.game.print_board() move = self.agent.play(self.player, self.game) self.game.place_move(self.player, move) return move elif command == "win": print("Yay!! We win!! :)") return -1 elif command == "loss": print("We lost :(") return -1 return 0
def eval(self, p, sb): opp = other(p) slices = [ slice(1, 4), slice(4, 7), slice(7, 10), slice(1, 8, 3), slice(2, 9, 3), slice(3, 10, 3), slice(1, 10, 4), slice(3, 8, 2) ] p1 = 0 p2 = 0 p3 = 0 pattern1 = [EMPTY, EMPTY, p] otherpattern1 = [EMPTY, EMPTY, opp] pattern2 = [EMPTY, p, p] otherpattern2 = [EMPTY, opp, opp] empty = [EMPTY, EMPTY, EMPTY] for s in slices: arr = sorted(sb[s]) if arr == empty: continue elif arr == pattern1: p1 += 1 elif arr == pattern2: p2 += 1 elif arr == otherpattern1: p1 -= 1 elif arr == otherpattern1: p2 -= 1 return 30 * p2 + 10 * p1
def plotSelectData(self): # Choose Primary Y axis Data try: while True: print("\nPrimary Y Axis: Columns Selected for Plotting ") # Counter used for options x = 1 # Print Output in nice format for item in self.yDataPrimary: print("{}. {:>24} : {}".format(x, item, self.yDataPrimary[item])) x += 1 print("{} \n{}. Save & Next".format("-" * 35, x)) # User Selection option = int(input("Choose a number to toggle selection: ")) # If number is in list index if 0 < option <= len(self.yDataPrimary): # Get name of column and toggle visibility on graph colName = self.df.columns[option - 1] self.yDataPrimary[colName] = not self.yDataPrimary[colName] # End loop if next option is selected elif option == x: common.back() # If a number is typed in out of range else: common.other() except StopIteration: pass # If someone does not put in an integer except ValueError: common.other() # Choose Secondary Y axis Data try: while True: print("\nSecondary Y Axis: Columns Selected for Plotting ") # Counter used for options x = 1 # Print Output in nice format for item in self.yDataSecondary: print("{}. {:>24} : {}".format(x, item, self.yDataSecondary[item])) x += 1 print("{} \n{}. Save & Next".format("-" * 35, x)) # User Selection option = int(input("Choose a number to toggle selection: ")) # If number is in list index if 0 < option <= len(self.yDataSecondary): # Get name of column and toggle visibility on graph colName = self.df.columns[option - 1] self.yDataSecondary[ colName] = not self.yDataSecondary[colName] # End loop if next option is selected elif option == x: common.back() # If a number is typed in out of range else: common.other() except StopIteration: pass # If someone does not put in an integer except ValueError: common.other() # X Axis Selection try: while True: print("\nX Axis: Currently Selected: {} ".format(self.xData)) # Counter used for options x = 1 # Print Output in nice format for item in self.yDataPrimary: print("{}. {}".format(x, item)) x += 1 print("{} \n{}. Save & Finish".format("-" * 30, x)) # User Selection option = int(input("Choose a number to select column: ")) # If valid number on the list then toggle it # Get name of column if 0 < option <= len(self.yDataPrimary): colName = self.df.columns[option - 1] self.xData = colName # End loop if next option is selected elif option == x: print("Success! - Plot Settings Updated") common.back() # If a number is typed in out of range else: common.other() except StopIteration: pass # If someone does not put in an integer except ValueError: common.other()
def negamax(self, p, game, depth, alpha, beta): # try: # return self.table[tuple(map(tuple,game.board))], 0 # except: # pass if game.won(p): return 1000, 0 if game.won(other(p)): return -1000, 0 if depth == 0: return self.eval_board(p, game), 0 state_tuple = tuple(map(tuple, game.board)) # check stored best moves try: p1, m1, v1 = self.table.get((depth, state_tuple)) return v1, m1 except: pass # try: # p1, m1, board1, val1 = self.table.get((depth,1)) # if m1 == game.last_move() and board1 == game.prev_board(): # return val1, 0 # except: # pass # try: # p2, m2, board2, val2 = self.table.get((depth,2)) # if m2 == game.last_move() and board2 == game.prev_board(): # return val2, 0 # except: # pass #possible_moves = self.legal_sorted(p, game) #possible_moves = self.legal(curr_state) possible_moves = self.legal_sorted(p, game, depth) value = -2000 best_move = 0 for move in possible_moves: game.place_move(p, move) v, _ = self.negamax(other(p), game, depth - 1, -beta, -alpha) v *= -1 if v > value: value = v best_move = move if value > alpha: alpha = value state_tuple = tuple(map(tuple, game.board)) game.retract_prev_move() if alpha >= beta: entry = self.table.get((depth, state_tuple)) if entry is None: self.table[(depth, state_tuple)] = (p, best_move, alpha) # entry1 = self.table.get((depth,1)) # entry2 = self.table.get((depth,2)) # if entry1 is None and entry2 is None: # #print(f'New killer move') # self.table[(depth,1)] = (p, game.last_move(), best_move, alpha) # elif entry1 is not None and entry2 is None and entry1 != (p, game.last_move(), best_move, alpha): # #print(f'add new killer 2') # self.table[(depth,2)] = (p, game.last_move(), best_move, alpha) # elif entry2 is not None and entry2 != (p, game.last_move(), best_move, alpha): # #print(f'replace killer {self.table[(depth,1)]}') # self.table[(depth,1)] = (p, game.last_move(), best_move, alpha) break return value, best_move