def main(path, predict_column): df = pd.read_csv(path) columns = df.columns.values X = [ df[column].values for column in columns if column != predict_column and column != 'Name' ] y = df[predict_column].values swtch = Switcher() sk_X = [] for column in X: converted = np.array(swtch.convert_to(column)) sk_X.append(converted) sk_X = np.array(sk_X).T sk_y = np.array(swtch.convert_to(y)).T decisions = ID3() entropy = decisions.fit(X, y) print(f'Entropies:\t\t\t{entropy}') sk_decisions = DecisionTreeClassifier(random_state=1370) sk_decisions.fit(sk_X, sk_y) print(f'SkLearn Tree Decision accuracy:\t{sk_decisions.score(sk_X, sk_y)}') #print(sk_decisions.predict(['pycharm', 'Java', 'tea'])) return 0
def switcher(self): '''Return switcher object (singleton). This is implemented as a method, so that it can be created only when needed to avoid errors when displaying help.''' if not self._switcher: self._switcher = Switcher() return self._switcher
def run(share_code): scan_timeout = 10 # seconds scanner = Scanner().withDelegate(ScanDelegate()) switcher = None retry = True while (retry): try: print('Scanning...') devices = scanner.scan(scan_timeout) for device in devices: name = None for ad_type, description, value in device.getScanData(): if ad_type == 9: name = value if name is None or 'SWITCHER' not in name: continue print('Device {} ({}), RSSI={}dB'.format( device.addr, device.addrType, device.rssi)) print('Connectable: {}'.format(device.connectable)) if name == 'SWITCHER_M' and device.connectable: print('Connectable switcher is found.') switcher = device retry = False break print('Switcher is not found') except Exception as e: print('Error on scanning') print(e) Switcher(device.addr, device.addrType, share_code)
def main(path, predict_column): df = pd.read_csv(path) columns = df.columns.values X = [ df[column].values for column in columns if column != predict_column and column != 'Name' ] y = df[predict_column].values decisions = ID3() fitted = decisions.fit(X, y) print(f'Entropy of {predict_column}:\t\t\t{fitted[1]}\n') print(f'Information Gains of Xs\n') headers = ' '.join( map( str, list( filter(lambda x: x != predict_column and x != "Name", df.columns.values)))).replace(' ', '\t | ') print(f'{headers}') values = ' '.join(map(lambda x: "{0:.8f}".format(x), fitted[0])).replace(' ', '\t | ') print(values) print('\n\n') swtch = Switcher() sk_X = [] for column in X: converted = np.array(swtch.convert_to(column)) sk_X.append(converted) sk_X = np.array(sk_X).T sk_y = np.array(swtch.convert_to(y)).T x_train, x_test, y_train, y_test = train_test_split(sk_X, sk_y, test_size=0.3) sk_decisions = DecisionTreeClassifier(random_state=1370) sk_decisions.fit(x_train, y_train) print( f'SkLearn Tree Decision accuracy:\t{sk_decisions.score(x_train, y_train)}' ) print(f'SkLearn Tree Decision prediction: {sk_decisions.predict(x_test)}') return 0
def __init__(self): self.log = logging.getLogger("disper") self.log.setLevel(logging.WARNING) self._options_init() self.plugins = Plugins(self) # self.plugins.call('init') # can't really do here since list of plugins isn't read yet self.switcher = Switcher() # add default options # TODO do initial parsing too so errors can be traced to config conffile = os.path.join(os.getenv("HOME"), ".disper", "config") if os.path.exists(conffile): f = open(conffile, "r") opts = "" for l in f.readlines(): opts += l.split("#", 1)[0] + " " f.close() self.options_append(shlex.split(opts))
def __init__(self, add_book, *args, **kwargs): """ initilizer for the main from for the AddressBook app. :param add_book: the address book class to manipulate :type add_book: A address_book_data.AddressBook instance """ kwargs.setdefault('title', "Micro Address Book") wx.Frame.__init__(self, *args, **kwargs) self.add_book = add_book self.current_index = 0 # creae a status bar for messages... self.CreateStatusBar() # create the switcher self.switcher = Switcher(self) # create the entryPanel self.entryPanel = AddBookForm(add_book.book[self.current_index], self) # A new record button: new_record_but = wx.Button(self, label="New Record") new_record_but.Bind(wx.EVT_BUTTON, self.onNewRecord) # put them in a Sizer to lay out S = wx.BoxSizer(wx.VERTICAL) S.Add(self.switcher, 0, wx.ALL|wx.ALIGN_CENTER, 4) S.Add(wx.StaticLine(self,style=wx.LI_HORIZONTAL), 0, wx.EXPAND) S.Add(self.entryPanel, 0, wx.ALL|wx.EXPAND, 4) S.Add((1,5)) S.Add(wx.StaticLine(self,style=wx.LI_HORIZONTAL), 0, wx.EXPAND) S.Add(new_record_but, 0, wx.ALL|wx.ALIGN_RIGHT, 4) self.SetSizerAndFit(S) self.switcher.Fit() # Build up the menu bar: menuBar = wx.MenuBar() fileMenu = wx.Menu() openMenuItem = fileMenu.Append(wx.ID_OPEN, "&Open", "Open a file" ) self.Bind(wx.EVT_MENU, self.onOpen, openMenuItem) closeMenuItem = fileMenu.Append(wx.ID_EXIT, "&Close", "Close a file" ) self.Bind(wx.EVT_MENU, self.onClose, closeMenuItem) saveMenuItem = fileMenu.Append(wx.ID_SAVE, "&Save", "Save the file" ) self.Bind(wx.EVT_MENU, self.onSave, saveMenuItem) exitMenuItem = fileMenu.Append(wx.ID_EXIT, "Exit", "Exit the application") self.Bind(wx.EVT_MENU, self.onExit, exitMenuItem) menuBar.Append(fileMenu, "&File") helpMenu = wx.Menu() helpMenuItem = helpMenu.Append(wx.ID_HELP, "Help", "Get help") menuBar.Append(helpMenu, "&Help") self.SetMenuBar(menuBar)
class AddBookFrame(wx.Frame): def __init__(self, add_book, *args, **kwargs): """ initilizer for the main from for the AddressBook app. :param add_book: the address book class to manipulate :type add_book: A address_book_data.AddressBook instance """ kwargs.setdefault('title', "Micro Address Book") wx.Frame.__init__(self, *args, **kwargs) self.add_book = add_book self.current_index = 0 # creae a status bar for messages... self.CreateStatusBar() # create the switcher self.switcher = Switcher(self) # create the entryPanel self.entryPanel = AddBookForm(add_book.book[self.current_index], self) # A new record button: new_record_but = wx.Button(self, label="New Record") new_record_but.Bind(wx.EVT_BUTTON, self.onNewRecord) # put them in a Sizer to lay out S = wx.BoxSizer(wx.VERTICAL) S.Add(self.switcher, 0, wx.ALL|wx.ALIGN_CENTER, 4) S.Add(wx.StaticLine(self,style=wx.LI_HORIZONTAL), 0, wx.EXPAND) S.Add(self.entryPanel, 0, wx.ALL|wx.EXPAND, 4) S.Add((1,5)) S.Add(wx.StaticLine(self,style=wx.LI_HORIZONTAL), 0, wx.EXPAND) S.Add(new_record_but, 0, wx.ALL|wx.ALIGN_RIGHT, 4) self.SetSizerAndFit(S) self.switcher.Fit() # Build up the menu bar: menuBar = wx.MenuBar() fileMenu = wx.Menu() openMenuItem = fileMenu.Append(wx.ID_OPEN, "&Open", "Open a file" ) self.Bind(wx.EVT_MENU, self.onOpen, openMenuItem) closeMenuItem = fileMenu.Append(wx.ID_EXIT, "&Close", "Close a file" ) self.Bind(wx.EVT_MENU, self.onClose, closeMenuItem) saveMenuItem = fileMenu.Append(wx.ID_SAVE, "&Save", "Save the file" ) self.Bind(wx.EVT_MENU, self.onSave, saveMenuItem) exitMenuItem = fileMenu.Append(wx.ID_EXIT, "Exit", "Exit the application") self.Bind(wx.EVT_MENU, self.onExit, exitMenuItem) menuBar.Append(fileMenu, "&File") helpMenu = wx.Menu() helpMenuItem = helpMenu.Append(wx.ID_HELP, "Help", "Get help") menuBar.Append(helpMenu, "&Help") self.SetMenuBar(menuBar) def next(self): """ move to the next record in the address book """ try: self.entryPanel.entry = self.add_book.book[self.current_index+1] self.current_index+=1 except IndexError: print "At end of records...." def previous(self): """ move to the next record in the address book """ if self.current_index > 0: self.current_index-=1 self.entryPanel.entry = self.add_book.book[self.current_index] def onNewRecord(self, evt=None): index = self.add_book.new_record() self.entryPanel.entry = self.add_book.book[index] def onOpen(self, evt=None): """This method opens an existing file""" dlg = wx.FileDialog( self, message="Choose a file", defaultDir=os.getcwd(), defaultFile="", wildcard="*.json", style=wx.OPEN | wx.CHANGE_DIR ) # Show the dialog and retrieve the user response. If it is the OK response, # process the data. if dlg.ShowModal() == wx.ID_OK: # This returns a Python list of files that were selected. path = dlg.GetPath() print "I'd be opening file in onOpen ", path self.add_book.load_from_file(filename=path) else : print "The file dialog was canceled" dlg.Destroy() def onSave(self, evt=None): print "in onSave" self.SetStatusText("Saving: %s"%self.add_book.filename) self.add_book.save_to_file() def onClose(self, evt=None): print "close menu selected" self.add_book.close() def onExit(self, evt=None): print "Exit the program here" print "The event passed to onExit is type ", type(evt), self.Close()
class Ui_MainWindow(object): switcher = Switcher() def __init__(self): self.switcher.retrieve_settings() def setupUi(self, MainWindow): MainWindow.setObjectName("MainWindow") MainWindow.resize(742, 371) self.centralwidget = QtWidgets.QWidget(MainWindow) self.centralwidget.setObjectName("centralwidget") self.logo = QtWidgets.QLabel(self.centralwidget) self.logo.setGeometry(QtCore.QRect(590, 0, 161, 51)) self.logo.setText("") self.logo.setPixmap(QtGui.QPixmap("sesil_logo.jpg")) self.logo.setScaledContents(True) self.logo.setObjectName("logo") self.label = QtWidgets.QLabel(self.centralwidget) self.label.setGeometry(QtCore.QRect(230, 20, 220, 31)) MainWindow.setWindowIcon(QtGui.QIcon('logo.png')) font = QtGui.QFont() font.setFamily("Verdana") font.setPointSize(16) font.setBold(True) font.setUnderline(True) font.setWeight(75) self.label.setFont(font) self.label.setObjectName("label") self.label_2 = QtWidgets.QLabel(self.centralwidget) self.label_2.setGeometry(QtCore.QRect(500, 340, 230, 20)) font = QtGui.QFont() font.setFamily("Verdana") font.setBold(False) font.setWeight(50) self.label_2.setFont(font) self.label_2.setObjectName("label_2") self.label_3 = QtWidgets.QLabel(self.centralwidget) self.label_3.setGeometry(QtCore.QRect(30, 340, 101, 20)) font = QtGui.QFont() font.setFamily("Verdana") self.label_3.setFont(font) self.label_3.setObjectName("label_3") self.groupBox = QtWidgets.QGroupBox(self.centralwidget) self.groupBox.setGeometry(QtCore.QRect(80, 110, 561, 191)) self.groupBox.setObjectName("groupBox") self.groupBox_2 = QtWidgets.QGroupBox(self.groupBox) self.groupBox_2.setGeometry(QtCore.QRect(40, 30, 230, 130)) self.groupBox_2.setObjectName("groupBox_2") self.start_btn = QtWidgets.QPushButton(self.groupBox_2) self.start_btn.setGeometry(QtCore.QRect(50, 30, 130, 30)) self.start_btn.setObjectName("start_btn") self.exit_btn = QtWidgets.QPushButton(self.groupBox_2) self.exit_btn.setGeometry(QtCore.QRect(50, 80, 130, 30)) self.exit_btn.setObjectName("exit_btn") self.groupBox_3 = QtWidgets.QGroupBox(self.groupBox) self.groupBox_3.setGeometry(QtCore.QRect(330, 30, 190, 130)) self.groupBox_3.setObjectName("groupBox_3") self.check_settings_btn = QtWidgets.QPushButton(self.groupBox_3) self.check_settings_btn.setGeometry(QtCore.QRect(40, 30, 110, 30)) self.check_settings_btn.setObjectName("check_settings_btn") self.reports_folder_btn = QtWidgets.QPushButton(self.groupBox_3) self.reports_folder_btn.setGeometry(QtCore.QRect(40, 80, 110, 30)) self.reports_folder_btn.setObjectName("reports_folder_btn") self.line = QtWidgets.QFrame(self.groupBox) self.line.setGeometry(QtCore.QRect(300, 30, 3, 140)) self.line.setStyleSheet("background-color: rgb(64, 81, 112);") self.line.setFrameShape(QtWidgets.QFrame.VLine) self.line.setFrameShadow(QtWidgets.QFrame.Sunken) self.line.setObjectName("line") MainWindow.setCentralWidget(self.centralwidget) # linking buttons to connnects self.start_btn.clicked.connect(self.start_application) self.exit_btn.clicked.connect(self.exit_application) self.check_settings_btn.clicked.connect(self.check_settings) self.reports_folder_btn.clicked.connect(self.open_reports_folder) # linking ends here self.retranslateUi(MainWindow) QtCore.QMetaObject.connectSlotsByName(MainWindow) def retranslateUi(self, MainWindow): _translate = QtCore.QCoreApplication.translate MainWindow.setWindowTitle(_translate("MainWindow", "Application Switcher SESIL")) self.label.setText(_translate("MainWindow", "Window Switcher")) self.label_2.setText(_translate("MainWindow", "All Rights Reserved To SESIL PVT. LTD.")) self.label_3.setText(_translate("MainWindow", "@mujeebishaque")) self.groupBox.setTitle(_translate("MainWindow", "Switcher")) self.groupBox_2.setTitle(_translate("MainWindow", "Functional")) self.start_btn.setText(_translate("MainWindow", "Start")) self.exit_btn.setText(_translate("MainWindow", "Exit")) self.groupBox_3.setTitle(_translate("MainWindow", "Misc.")) self.check_settings_btn.setText(_translate("MainWindow", "Check Settings")) self.reports_folder_btn.setText(_translate("MainWindow", "Reports Folder")) def start_application(self): self.switcher.starter() def open_reports_folder(self): self.switcher.check_reports() def exit_application(self): sys.exit() def check_settings(self): self.switcher.check_settings()
def __init__(self, r_one=1, r_two=1, r_three=1, r_four=1, r_five=1): #This is a part of code used to check for values entered to be #compatible with the program if not isinstance(r_one, int): raise TypeError('Rotor values should be entered as integers') if not isinstance(r_two, int): raise TypeError('Rotor values should be entered as integers') if not isinstance(r_three, int): raise TypeError('Rotor values should be entered as integers') if not isinstance(r_four, int): raise TypeError('Rotor values should be entered as integers') if not isinstance(r_five, int): raise TypeError('Rotor values should be entered as integers') #Dictionary of all the letters and coresponding to them self.letters = { 'a': 'a', 'b': 'b', 'c': 'c', 'd': 'd', 'e': 'e', 'f': 'f', 'g': 'g', 'h': 'h', 'i': 'i', 'j': 'j', 'k': 'k', 'l': 'l', 'm': 'm', 'n': 'n', 'o': 'o', 'p': 'p', 'q': 'q', 'r': 'r', 's': 's', 't': 't', 'u': 'u', 'v': 'v', 'w': 'w', 'x': 'x', 'y': 'y', 'z': 'z' } #All the rotors are created from the least to first, it is important self.rotor_three = Rotor_One(None, r_three) self.rotor_two = Rotor_Five(self.rotor_three, r_two) self.rotor_one = Rotor_Three(self.rotor_two, r_one) #Swithers are created here self.switcher_one = Switcher() self.switcher_two = Switcher() self.switcher_three = Switcher() self.switcher_four = Switcher() self.switcher_five = Switcher() self.switcher_six = Switcher() self.switcher_seven = Switcher() self.switcher_eight = Switcher() self.switcher_nine = Switcher() self.switcher_ten = Switcher() #Switchers are used self.use_switchers()
class Asfaleia_Machine(): def __init__(self, r_one=1, r_two=1, r_three=1, r_four=1, r_five=1): #This is a part of code used to check for values entered to be #compatible with the program if not isinstance(r_one, int): raise TypeError('Rotor values should be entered as integers') if not isinstance(r_two, int): raise TypeError('Rotor values should be entered as integers') if not isinstance(r_three, int): raise TypeError('Rotor values should be entered as integers') if not isinstance(r_four, int): raise TypeError('Rotor values should be entered as integers') if not isinstance(r_five, int): raise TypeError('Rotor values should be entered as integers') #Dictionary of all the letters and coresponding to them self.letters = { 'a': 'a', 'b': 'b', 'c': 'c', 'd': 'd', 'e': 'e', 'f': 'f', 'g': 'g', 'h': 'h', 'i': 'i', 'j': 'j', 'k': 'k', 'l': 'l', 'm': 'm', 'n': 'n', 'o': 'o', 'p': 'p', 'q': 'q', 'r': 'r', 's': 's', 't': 't', 'u': 'u', 'v': 'v', 'w': 'w', 'x': 'x', 'y': 'y', 'z': 'z' } #All the rotors are created from the least to first, it is important self.rotor_three = Rotor_One(None, r_three) self.rotor_two = Rotor_Five(self.rotor_three, r_two) self.rotor_one = Rotor_Three(self.rotor_two, r_one) #Swithers are created here self.switcher_one = Switcher() self.switcher_two = Switcher() self.switcher_three = Switcher() self.switcher_four = Switcher() self.switcher_five = Switcher() self.switcher_six = Switcher() self.switcher_seven = Switcher() self.switcher_eight = Switcher() self.switcher_nine = Switcher() self.switcher_ten = Switcher() #Switchers are used self.use_switchers() #Function used to use switchers def use_switchers(self): self.switcher_one.switch(self.letters, 'a', 'r') self.switcher_two.switch(self.letters, 'k', 'l') self.switcher_three.switch(self.letters, 't', 'v') self.switcher_four.switch(self.letters, 'm', 'j') self.switcher_five.switch(self.letters, 'g', 'z') self.switcher_six.switch(self.letters, 'b', 'c') self.switcher_seven.switch(self.letters, 'e', 'y') self.switcher_eight.switch(self.letters, 'o', 'n') self.switcher_nine.switch(self.letters, 's', 'k') self.switcher_ten.switch(self.letters, 'w', 'q') #Function used to uncode a sentence def encode(self, sentence): if not isinstance(sentence, str): raise TypeError('You shoud use strings to encode') encoded_message = [] for letter in sentence.lower(): if letter not in self.letters: encoded_message.append(letter) continue # Values of rotors are increased only on one direction # so the values are not increased when the letters are # going all the way back self.rotor_one.shuffle_letters(self.letters) self.rotor_one.increase_current_value() self.rotor_two.shuffle_letters(self.letters) self.rotor_three.shuffle_letters(self.letters) self.rotor_three.shuffle_letters(self.letters) self.rotor_two.shuffle_letters(self.letters) self.rotor_one.shuffle_letters(self.letters) encoded_message.append(self.letters[letter.lower()]) return ''.join(encoded_message) #Function used to decode a sentence def decode(self, sentence): if not isinstance(sentence, str): raise TypeError('You shoud use strings to encode') decoded_message = [] for letter in sentence.lower(): if letter not in self.letters: decoded_message.append(letter) continue # Values of rotors are increased only on one direction # so the values are not increased when the letters are # going all the way back self.rotor_one.shuffle_letters(self.letters) self.rotor_one.increase_current_value() self.rotor_two.shuffle_letters(self.letters) self.rotor_three.shuffle_letters(self.letters) self.rotor_three.shuffle_letters(self.letters) self.rotor_two.shuffle_letters(self.letters) self.rotor_one.shuffle_letters(self.letters) for x, y in self.letters.items(): if y == letter: decoded_message.append(x) return ''.join(decoded_message) #Function used reset the machine to its starting form(init) def _set(self, r_one=1, r_two=1, r_three=1, r_four=1, r_five=1): self.reset_letters() self.use_switchers() if (1 <= r_one <= 26): self.rotor_one.set_current_value(r_one) else: raise ValueError('The value should be in appropriate range') if (1 <= r_two <= 26): self.rotor_two.set_current_value(r_two) else: raise ValueError('The value should be in appropriate range') if (1 <= r_three <= 26): self.rotor_three.set_current_value(r_three) else: raise ValueError('The value should be in appropriate range') #Function used to reset letters def reset_letters(self): self.letters = { 'a': 'a', 'b': 'b', 'c': 'c', 'd': 'd', 'e': 'e', 'f': 'f', 'g': 'g', 'h': 'h', 'i': 'i', 'j': 'j', 'k': 'k', 'l': 'l', 'm': 'm', 'n': 'n', 'o': 'o', 'p': 'p', 'q': 'q', 'r': 'r', 's': 's', 't': 't', 'u': 'u', 'v': 'v', 'w': 'w', 'x': 'x', 'y': 'y', 'z': 'z' } def __str__(self): return 'This is an {self.__class__.__name__} class with properties of {self.rotor_one.__class__.__name__} - {self.rotor_one.current_value}, {self.rotor_two.__class__.__name__} - {self.rotor_two.current_value}, {self.rotor_three.__class__.__name__} - {self.rotor_three.current_value}'.format( self=self) def __repr__(self): return '{self.__class__.__name__}()'.format(self=self)
from switcher import Switcher switcher = Switcher('9.9.9.1', 'Qzxt@1088', 'yanghua') switcher.login() ip, version = switcher.get_version() print(ip+' '+version) #buff = switcher.send_cmd('sh run', 'More', 'test error') #print(buff)b
class Disper: # static information name = "disper" version = "0.3.0" prefix = build.prefix prefix_share = build.prefix_share # option parsing argv = [] parser = None # option parser object options = None # parsed options args = None # parsed arguments # real work switcher = None # switcher object plugins = None # plugins object log = None def __init__(self): self.log = logging.getLogger("disper") self.log.setLevel(logging.WARNING) self._options_init() self.plugins = Plugins(self) # self.plugins.call('init') # can't really do here since list of plugins isn't read yet self.switcher = Switcher() # add default options # TODO do initial parsing too so errors can be traced to config conffile = os.path.join(os.getenv("HOME"), ".disper", "config") if os.path.exists(conffile): f = open(conffile, "r") opts = "" for l in f.readlines(): opts += l.split("#", 1)[0] + " " f.close() self.options_append(shlex.split(opts)) def _options_init(self): """initialize default command-line options""" usage = "usage: %prog [options] (-l|-s|-c|-e|-p|-i)" version = " ".join(map(str, [self.name, self.version])) self.parser = optparse.OptionParser(usage=usage, version=version) self.add_option( "-v", "--verbose", action="store_const", dest="debug", const=logging.INFO, help="show what's happening" ) self.add_option( "-q", "--quiet", action="store_const", dest="debug", const=logging.ERROR, help="be quiet and only show errors", ) self.add_option( "-r", "--resolution", dest="resolution", help='set resolution, e.g. "800x600", or "auto" to detect the display\'s preferred ' + 'resolution, or "max" to use the maximum resolution advertised. For extend it ' + "is possible to enter a single resolution for all displays or a comma-separated " + "list of resolutions (one for each display). Beware that many displays advertise " + 'resolutions they can not fully show, so "max" is not advised.', ) self.add_option( "-d", "--displays", dest="displays", help='comma-separated list of displays to operate on, or "auto" to detect; ' + "the first is the primary display.", ) self.add_option( "-t", "--direction", dest="direction", choices=["left", "right", "top", "bottom"], help='where to extend displays: "left", "right", "top", or "bottom"', ) self.add_option( "", "--scaling", dest="scaling", choices=["default", "native", "scaled", "centered", "aspect-scaled"], help='flat-panel scaling mode: "default", "native", "scaled", "centered", or "aspect-scaled"', ) self.add_option( "", "--plugins", dest="plugins", help='comma-separated list of plugins to enable. Special names: "user" for all user plugins ' + 'in ~/.disper/hooks; "all" for all plugins found; "none" for no plugins.', ) self.add_option( "", "--cycle-stages", dest="cycle_stages", help="colon-separated list command-line arguments to cycle through", ) group = optparse.OptionGroup(self.parser, "Actions", "Select exactly one of the following actions") self._add_option( group, "-l", "--list", action="append_const", const="list", dest="actions", help="list the attached displays", ) self._add_option( group, "-s", "--single", action="append_const", const="single", dest="actions", help="only enable the primary display", ) self._add_option( group, "-S", "--secondary", action="append_const", const="secondary", dest="actions", help="only enable the secondary display", ) self._add_option( group, "-c", "--clone", action="append_const", const="clone", dest="actions", help="clone displays" ) self._add_option( group, "-e", "--extend", action="append_const", const="extend", dest="actions", help="extend displays" ) self._add_option( group, "-p", "--export", action="append_const", const="export", dest="actions", help="export current settings to standard output", ) self._add_option( group, "-i", "--import", action="append_const", const="import", dest="actions", help="import current settings from standard input", ) self._add_option( group, "-C", "--cycle", action="append_const", const="cycle", dest="actions", help="cycle through the list of cycle stages", ) self.parser.add_option_group(group) def add_option(self, *args, **kwargs): """adds an option to the parser. Implements append_const for Python<2.5 too""" return self._add_option(self.parser, *args, **kwargs) def _add_option(self, obj, *args, **kwargs): """portable optarg add_option function that implements the append_const action for Python versions below 2.5; has an extra first argument as the object on which add_option should be called.""" if sys.hexversion < 0x020500F0 and "action" in kwargs and kwargs["action"] == "append_const": # after: http://permalink.gmane.org/gmane.comp.python.optik.user/284 def append_const_cb(const): def cb(opt, opt_str, value, parser): if not getattr(parser.values, opt.dest): setattr(parser.values, opt.dest, list()) getattr(parser.values, opt.dest).append(const) return cb kwargs["action"] = "callback" kwargs["callback"] = append_const_cb(kwargs["const"]) del kwargs["const"] return obj.add_option(*args, **kwargs) def options_append(self, args): """parses command-line options; can be called multiple times""" self.argv += args def options_parse(self, args=None): """parses command-line options given; adds options to current list if set""" if args: self.options_append(args) (self.options, self.args) = self.parser.parse_args(self.argv) # need exactly one action if not self.options.actions: self.options.actions = [] elif len(self.options.actions) > 1: self.parser.error( "conflicting actions, please specify exactly one action: " + ", ".join(self.options.actions) ) raise SystemExit(2) if "import" in self.options.actions or "export" in self.options.actions: if self.options.resolution: self.log.warning("specified resolution ignored for %s" % self.options.actions[0]) if self.options.displays: self.log.warning("specified displays ignored for %s" % self.options.actions[0]) # apply defaults here to be able to detect if they were set explicitly or not if not self.options.direction: self.options.direction = "right" if not self.options.resolution: self.options.resolution = "auto" if not self.options.displays: self.options.displays = "auto" if not self.options.scaling: self.options.scaling = "default" if not self.options.debug: self.options.debug = logging.WARNING if self.options.plugins == None: self.options.plugins = "user" self.log.setLevel(self.options.debug) self.options.plugins = map(lambda x: x.strip(), self.options.plugins.split(",")) if self.options.displays != "auto": self.options.displays = map(lambda x: x.strip(), self.options.displays.split(",")) if self.options.resolution not in ["auto", "max"]: self.options.resolution = map(lambda x: x.strip(), self.options.resolution.split(",")) self.plugins.set_enabled(self.options.plugins) def switch(self): """Switch to configuration as specified in the options""" if len(self.options.actions) == 0: self.log.info("no action specified") # show help if no action specified self.parser.print_help() raise SystemExit(2) if "single" in self.options.actions: if self.options.displays != "auto": self.log.warning("specified displays ignored for single") self.switch_primary() elif "secondary" in self.options.actions: if self.options.displays != "auto": self.log.warning("specified displays ignored for secondary") self.switch_secondary() elif "clone" in self.options.actions: self.switch_clone() elif "extend" in self.options.actions: self.switch_extend() elif "export" in self.options.actions: print self.export_config() elif "import" in self.options.actions: self.import_config("\n".join(sys.stdin)) elif "cycle" in self.options.actions: self._cycle(self.options.cycle_stages.split(":")) elif "list" in self.options.actions: # list displays with resolutions displays = self.options.displays if displays == "auto": displays = self.switcher.get_displays() for disp in displays: res = self.switcher.get_resolutions_display(disp) res.sort() print "display %s: %s" % (disp, self.switcher.get_display_name(disp)) print " resolutions: " + str(res) else: self.log.critical("program error, unrecognised action: " + ", ".join(self.options.actions)) raise SystemExit(2) def switch_primary(self, res=None): """Only enable primary display. @param res resolution to use; or 'auto' for default or None for option""" return self.switch_single(self.switcher.get_primary_display()) def switch_secondary(self, res=None): """Only enable secondary display. @param res resolution to use; or 'auto' for default or None for option""" primary = self.switcher.get_primary_display() try: display = [x for x in self.switcher.get_displays() if x != primary][0] except IndexError: self.log.critical("No secondary display found, falling back to primary.") return self.switch_single(primary, res) return self.switch_single(display, res) def switch_single(self, display=None, res=None): """Only enable one display. @param display display to enable; or 'auto' for primary or None for option @param res resolution to use; or 'auto' for default or None for option""" if not display: display = self.options.displays if display == "auto": display = self.switcher.get_primary_display() elif isinstance(display, list) and len(display) > 1: self.log.warning("single output requested but multiple specified; using first one") display = display[0] if display: display = [display] return self.switch_clone(display, res) def switch_clone(self, displays=None, res=None): """Clone displays. @param displays list of displays; or 'auto' for default or None for option @param res resolution; or 'auto' for default, 'max' for max or None for option""" # figure out displays if not displays: displays = self.options.displays if displays == "auto": displays = self.switcher.get_displays() self.log.info("auto-detected displays: " + ", ".join(displays)) else: self.log.info("using specified displays: " + ", ".join(displays)) # figure out resolutions if not res: res = self.options.resolution if type(res) == list or type(res) == tuple: if len(res) != 1: raise TypeError("need single resolution for clone") res = res[0] if res == "auto" or res == "max": r = self.switcher.get_resolutions(displays).common() if len(r) == 0: self.log.critical("displays share no common resolution") raise SystemExit(1) if res == "max": # ignore any preferred resolution for s in r: s.weight = 0 res = sorted(r)[-1] else: res = Resolution(res) # and switch result = self.switcher.switch_clone(displays, res) self.plugins.set_layout_clone(displays, res) self.plugins.call("switch") return result def switch_extend(self, displays=None, direction=None, ress=None): """Extend displays. @param displays list of displays; or 'auto for default or None for option @param direction direction to extend; or None for option @param ress list of resolutions; or 'auto' for default or 'max' for max or None for option""" # figure out displays if not displays: displays = self.options.displays if displays == "auto": displays = self.switcher.get_displays() self.log.info("auto-detected displays: " + ", ".join(displays)) else: self.log.info("using specified displays: " + ", ".join(displays)) # figure out resolutions if not ress: ress = self.options.resolution if ress == "max": # max resolution for each # override auto-detection weights and get highest resolution ress = self.switcher.get_resolutions(displays) for rl in ress.values(): for r in rl: r.weight = 0 ress = ress.select() self.log.info("maximum resolutions for displays: " + str(ress)) elif ress == "auto": # use preferred resolution for each ress = self.switcher.get_resolutions(displays).select() self.log.info("preferred resolutions for displays: " + str(ress)) else: # list of resolutions specified ress = ResolutionSelection(ress, displays) if len(ress) == 1: ress = ress * len(displays) elif len(ress) != len(displays): self.log.critical( 'resolution: must specify either "auto", "max", a single value, or one for each display' ) raise SystemExit(2) self.log.info("selected resolutions for displays: " + str(ress)) # figure out direction if not direction: direction = self.options.direction # and switch result = self.switcher.switch_extend(displays, direction, ress) self.plugins.set_layout_extend(displays, direction, ress) self.plugins.call("switch") return result def export_config(self): return self.switcher.export_config() def import_config(self, data): result = self.switcher.import_config(data) self.plugins.call("switch") return result def _cycle(self, stages): # read last state stage = 0 disperconf = os.path.join(os.getenv("HOME"), ".disper") statefile = os.path.join(disperconf, "last_cycle_stage") if os.path.exists(statefile): f = open(statefile, "r") stage = int(f.readline()) f.close() # apply next stage += 1 if stage >= len(stages): stage = 0 self.argv = filter(lambda x: x != "-C" and x != "--cycle", self.argv) self.options_parse(shlex.split(stages[stage])) try: self.switch() finally: # write new state to file; do it here to make sure that a # failing configuration doesn't block the cycling if not os.path.exists(disperconf): os.mkdir(disperconf) f = open(statefile, "w") f.write(str(stage) + "\n") f.close()