Looping through multiple regex efficiently












4












$begingroup$


I'm writing a program that adds all network interfaces with multiple parameters to a list.



I have written the following code, which should work out of the box on any Linux system with Python and ethtool installed:



import imp
import os
import subprocess
import re
from enum import Enum


class interface_type(Enum):

OPTIC = 1
TWISTED_PAIR = 2


class NetworkInterface:

def set_indentifier(self, id):
self.id = id

def set_mac_address(self, mac):
self.mac = mac

def set_interface_type(self, interface_type):
self.interface_type = interface_type


def findNetworkInterfaces(ignoredInterface):

filteredList = netifaces.interfaces()
network_interfaces =

for interface in filteredList:
for regex in ignoredInterface:
if re.search(regex, interface):
break
else:
nwi = NetworkInterface()
nwi.set_indentifier(interface)
nwi.set_mac_address(setMAC(interface))
nwi.set_interface_type(setInterfaceType(interface))
network_interfaces.append(nwi)
filteredList.remove(interface)
break
return network_interfaces


def setMAC(identifier):

addrs = netifaces.ifaddresses(identifier)
mac_address = addrs[netifaces.AF_LINK][0].get("addr")

return mac_address


def setInterfaceType(identifier):

bashCommand1 = "ethtool " + identifier
bashCommand2 = "grep ports"

try:
process1 = subprocess.Popen(bashCommand1.split(),
stdout=subprocess.PIPE)
process2 = subprocess.Popen(bashCommand2.split(),
stdin=process1.stdout, stdout=subprocess.PIPE)
output, error = process2.communicate()

except:
print ("Error determining interface type: " + error + "n")
print ("Interface will be treated as Optical n")

if "TP" in output:
return interface_type.TWISTED_PAIR
else:
return interface_type.OPTIC


if __name__ == "__main__":

ignored_interface = ["lo", "wlp2s0"]

try:
imp.find_module("netifaces")
netifaces_status = True
import netifaces

except ImportError as e:
print ("netifaces not found: " + str(e))
os.sys.exit(-1)

network_identifiers = findNetworkInterfaces(ignored_interface)

#print network_identifiers

for iface in network_identifiers:
print iface.id
print iface.mac
print iface.interface_type


I'm mainly concerned with the findNetworkInterfaces function, as I feel I'm doing this in a very ineffecient way (basically copying the list and removing interfaces as to not have doubles). In this special case, I'm not concerned with PEP8 - this is something I'll do later. Any other suggestions to improve the code are very welcome.










share|improve this question











$endgroup$

















    4












    $begingroup$


    I'm writing a program that adds all network interfaces with multiple parameters to a list.



    I have written the following code, which should work out of the box on any Linux system with Python and ethtool installed:



    import imp
    import os
    import subprocess
    import re
    from enum import Enum


    class interface_type(Enum):

    OPTIC = 1
    TWISTED_PAIR = 2


    class NetworkInterface:

    def set_indentifier(self, id):
    self.id = id

    def set_mac_address(self, mac):
    self.mac = mac

    def set_interface_type(self, interface_type):
    self.interface_type = interface_type


    def findNetworkInterfaces(ignoredInterface):

    filteredList = netifaces.interfaces()
    network_interfaces =

    for interface in filteredList:
    for regex in ignoredInterface:
    if re.search(regex, interface):
    break
    else:
    nwi = NetworkInterface()
    nwi.set_indentifier(interface)
    nwi.set_mac_address(setMAC(interface))
    nwi.set_interface_type(setInterfaceType(interface))
    network_interfaces.append(nwi)
    filteredList.remove(interface)
    break
    return network_interfaces


    def setMAC(identifier):

    addrs = netifaces.ifaddresses(identifier)
    mac_address = addrs[netifaces.AF_LINK][0].get("addr")

    return mac_address


    def setInterfaceType(identifier):

    bashCommand1 = "ethtool " + identifier
    bashCommand2 = "grep ports"

    try:
    process1 = subprocess.Popen(bashCommand1.split(),
    stdout=subprocess.PIPE)
    process2 = subprocess.Popen(bashCommand2.split(),
    stdin=process1.stdout, stdout=subprocess.PIPE)
    output, error = process2.communicate()

    except:
    print ("Error determining interface type: " + error + "n")
    print ("Interface will be treated as Optical n")

    if "TP" in output:
    return interface_type.TWISTED_PAIR
    else:
    return interface_type.OPTIC


    if __name__ == "__main__":

    ignored_interface = ["lo", "wlp2s0"]

    try:
    imp.find_module("netifaces")
    netifaces_status = True
    import netifaces

    except ImportError as e:
    print ("netifaces not found: " + str(e))
    os.sys.exit(-1)

    network_identifiers = findNetworkInterfaces(ignored_interface)

    #print network_identifiers

    for iface in network_identifiers:
    print iface.id
    print iface.mac
    print iface.interface_type


    I'm mainly concerned with the findNetworkInterfaces function, as I feel I'm doing this in a very ineffecient way (basically copying the list and removing interfaces as to not have doubles). In this special case, I'm not concerned with PEP8 - this is something I'll do later. Any other suggestions to improve the code are very welcome.










    share|improve this question











    $endgroup$















      4












      4








      4





      $begingroup$


      I'm writing a program that adds all network interfaces with multiple parameters to a list.



      I have written the following code, which should work out of the box on any Linux system with Python and ethtool installed:



      import imp
      import os
      import subprocess
      import re
      from enum import Enum


      class interface_type(Enum):

      OPTIC = 1
      TWISTED_PAIR = 2


      class NetworkInterface:

      def set_indentifier(self, id):
      self.id = id

      def set_mac_address(self, mac):
      self.mac = mac

      def set_interface_type(self, interface_type):
      self.interface_type = interface_type


      def findNetworkInterfaces(ignoredInterface):

      filteredList = netifaces.interfaces()
      network_interfaces =

      for interface in filteredList:
      for regex in ignoredInterface:
      if re.search(regex, interface):
      break
      else:
      nwi = NetworkInterface()
      nwi.set_indentifier(interface)
      nwi.set_mac_address(setMAC(interface))
      nwi.set_interface_type(setInterfaceType(interface))
      network_interfaces.append(nwi)
      filteredList.remove(interface)
      break
      return network_interfaces


      def setMAC(identifier):

      addrs = netifaces.ifaddresses(identifier)
      mac_address = addrs[netifaces.AF_LINK][0].get("addr")

      return mac_address


      def setInterfaceType(identifier):

      bashCommand1 = "ethtool " + identifier
      bashCommand2 = "grep ports"

      try:
      process1 = subprocess.Popen(bashCommand1.split(),
      stdout=subprocess.PIPE)
      process2 = subprocess.Popen(bashCommand2.split(),
      stdin=process1.stdout, stdout=subprocess.PIPE)
      output, error = process2.communicate()

      except:
      print ("Error determining interface type: " + error + "n")
      print ("Interface will be treated as Optical n")

      if "TP" in output:
      return interface_type.TWISTED_PAIR
      else:
      return interface_type.OPTIC


      if __name__ == "__main__":

      ignored_interface = ["lo", "wlp2s0"]

      try:
      imp.find_module("netifaces")
      netifaces_status = True
      import netifaces

      except ImportError as e:
      print ("netifaces not found: " + str(e))
      os.sys.exit(-1)

      network_identifiers = findNetworkInterfaces(ignored_interface)

      #print network_identifiers

      for iface in network_identifiers:
      print iface.id
      print iface.mac
      print iface.interface_type


      I'm mainly concerned with the findNetworkInterfaces function, as I feel I'm doing this in a very ineffecient way (basically copying the list and removing interfaces as to not have doubles). In this special case, I'm not concerned with PEP8 - this is something I'll do later. Any other suggestions to improve the code are very welcome.










      share|improve this question











      $endgroup$




      I'm writing a program that adds all network interfaces with multiple parameters to a list.



      I have written the following code, which should work out of the box on any Linux system with Python and ethtool installed:



      import imp
      import os
      import subprocess
      import re
      from enum import Enum


      class interface_type(Enum):

      OPTIC = 1
      TWISTED_PAIR = 2


      class NetworkInterface:

      def set_indentifier(self, id):
      self.id = id

      def set_mac_address(self, mac):
      self.mac = mac

      def set_interface_type(self, interface_type):
      self.interface_type = interface_type


      def findNetworkInterfaces(ignoredInterface):

      filteredList = netifaces.interfaces()
      network_interfaces =

      for interface in filteredList:
      for regex in ignoredInterface:
      if re.search(regex, interface):
      break
      else:
      nwi = NetworkInterface()
      nwi.set_indentifier(interface)
      nwi.set_mac_address(setMAC(interface))
      nwi.set_interface_type(setInterfaceType(interface))
      network_interfaces.append(nwi)
      filteredList.remove(interface)
      break
      return network_interfaces


      def setMAC(identifier):

      addrs = netifaces.ifaddresses(identifier)
      mac_address = addrs[netifaces.AF_LINK][0].get("addr")

      return mac_address


      def setInterfaceType(identifier):

      bashCommand1 = "ethtool " + identifier
      bashCommand2 = "grep ports"

      try:
      process1 = subprocess.Popen(bashCommand1.split(),
      stdout=subprocess.PIPE)
      process2 = subprocess.Popen(bashCommand2.split(),
      stdin=process1.stdout, stdout=subprocess.PIPE)
      output, error = process2.communicate()

      except:
      print ("Error determining interface type: " + error + "n")
      print ("Interface will be treated as Optical n")

      if "TP" in output:
      return interface_type.TWISTED_PAIR
      else:
      return interface_type.OPTIC


      if __name__ == "__main__":

      ignored_interface = ["lo", "wlp2s0"]

      try:
      imp.find_module("netifaces")
      netifaces_status = True
      import netifaces

      except ImportError as e:
      print ("netifaces not found: " + str(e))
      os.sys.exit(-1)

      network_identifiers = findNetworkInterfaces(ignored_interface)

      #print network_identifiers

      for iface in network_identifiers:
      print iface.id
      print iface.mac
      print iface.interface_type


      I'm mainly concerned with the findNetworkInterfaces function, as I feel I'm doing this in a very ineffecient way (basically copying the list and removing interfaces as to not have doubles). In this special case, I'm not concerned with PEP8 - this is something I'll do later. Any other suggestions to improve the code are very welcome.







      python python-2.x linux networking






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Jan 21 at 15:50









      Ludisposed

      8,43722164




      8,43722164










      asked Jan 21 at 15:31









      FangFang

      237211




      237211






















          1 Answer
          1






          active

          oldest

          votes


















          5












          $begingroup$



          • Start writing in python3.x ;)



            End of Life for python2.x will happen pretty soon 1




          • One regex to rule them all



            Instead of looping over a the list to create a regex,



            you could use the | char which will work as an or so it can handle multiple outputs



            REGEX_FILTER = re.conmpile('lo|wlp2s0')




          • If you only need the parameters, a simple namedtuple will suffice



            You could create a namedtuple that will get rid of the empty looking class




          • IMHO setting the variables outside of the init is bad style



            I would get the different variables needed before, and only then create the NetworkInterface object.




          Note I will not review getting the interface type, since I am nowhere near a linux atm



          Code



          from collections import namedtuple
          import re

          import netifaces

          FILTER_REGEX = re.compile(r'lo|wlp2s0')
          NetworkInterface = namedtuple('NetworkInterface', ['iface', 'mac', 'type'])

          def get_mac(iface):
          addresses = netifaces.ifaddresses(iface)
          return addresses[netifaces.AF_LINK][0].get("addr")

          def get_type(iface):
          """Just return TP for testing"""
          return "TP"

          def find_network_interfaces():
          for iface in netifaces.interfaces():
          if FILTER_REGEX.search(iface):
          continue
          yield NetworkInterface(iface, get_mac(iface), get_type(iface))

          if __name__ == '__main__':
          for nwi in find_network_interfaces():
          print(nwi.iface)
          print(nwi.mac)
          print(nwi.type)





          share|improve this answer











          $endgroup$









          • 1




            $begingroup$
            Since you saved the compiled regexes to a variable, you could do FILTER_REGEX.search(iface).
            $endgroup$
            – Graipher
            Jan 21 at 18:58











          Your Answer





          StackExchange.ifUsing("editor", function () {
          return StackExchange.using("mathjaxEditing", function () {
          StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
          StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
          });
          });
          }, "mathjax-editing");

          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "196"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: false,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: null,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f211915%2flooping-through-multiple-regex-efficiently%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          5












          $begingroup$



          • Start writing in python3.x ;)



            End of Life for python2.x will happen pretty soon 1




          • One regex to rule them all



            Instead of looping over a the list to create a regex,



            you could use the | char which will work as an or so it can handle multiple outputs



            REGEX_FILTER = re.conmpile('lo|wlp2s0')




          • If you only need the parameters, a simple namedtuple will suffice



            You could create a namedtuple that will get rid of the empty looking class




          • IMHO setting the variables outside of the init is bad style



            I would get the different variables needed before, and only then create the NetworkInterface object.




          Note I will not review getting the interface type, since I am nowhere near a linux atm



          Code



          from collections import namedtuple
          import re

          import netifaces

          FILTER_REGEX = re.compile(r'lo|wlp2s0')
          NetworkInterface = namedtuple('NetworkInterface', ['iface', 'mac', 'type'])

          def get_mac(iface):
          addresses = netifaces.ifaddresses(iface)
          return addresses[netifaces.AF_LINK][0].get("addr")

          def get_type(iface):
          """Just return TP for testing"""
          return "TP"

          def find_network_interfaces():
          for iface in netifaces.interfaces():
          if FILTER_REGEX.search(iface):
          continue
          yield NetworkInterface(iface, get_mac(iface), get_type(iface))

          if __name__ == '__main__':
          for nwi in find_network_interfaces():
          print(nwi.iface)
          print(nwi.mac)
          print(nwi.type)





          share|improve this answer











          $endgroup$









          • 1




            $begingroup$
            Since you saved the compiled regexes to a variable, you could do FILTER_REGEX.search(iface).
            $endgroup$
            – Graipher
            Jan 21 at 18:58
















          5












          $begingroup$



          • Start writing in python3.x ;)



            End of Life for python2.x will happen pretty soon 1




          • One regex to rule them all



            Instead of looping over a the list to create a regex,



            you could use the | char which will work as an or so it can handle multiple outputs



            REGEX_FILTER = re.conmpile('lo|wlp2s0')




          • If you only need the parameters, a simple namedtuple will suffice



            You could create a namedtuple that will get rid of the empty looking class




          • IMHO setting the variables outside of the init is bad style



            I would get the different variables needed before, and only then create the NetworkInterface object.




          Note I will not review getting the interface type, since I am nowhere near a linux atm



          Code



          from collections import namedtuple
          import re

          import netifaces

          FILTER_REGEX = re.compile(r'lo|wlp2s0')
          NetworkInterface = namedtuple('NetworkInterface', ['iface', 'mac', 'type'])

          def get_mac(iface):
          addresses = netifaces.ifaddresses(iface)
          return addresses[netifaces.AF_LINK][0].get("addr")

          def get_type(iface):
          """Just return TP for testing"""
          return "TP"

          def find_network_interfaces():
          for iface in netifaces.interfaces():
          if FILTER_REGEX.search(iface):
          continue
          yield NetworkInterface(iface, get_mac(iface), get_type(iface))

          if __name__ == '__main__':
          for nwi in find_network_interfaces():
          print(nwi.iface)
          print(nwi.mac)
          print(nwi.type)





          share|improve this answer











          $endgroup$









          • 1




            $begingroup$
            Since you saved the compiled regexes to a variable, you could do FILTER_REGEX.search(iface).
            $endgroup$
            – Graipher
            Jan 21 at 18:58














          5












          5








          5





          $begingroup$



          • Start writing in python3.x ;)



            End of Life for python2.x will happen pretty soon 1




          • One regex to rule them all



            Instead of looping over a the list to create a regex,



            you could use the | char which will work as an or so it can handle multiple outputs



            REGEX_FILTER = re.conmpile('lo|wlp2s0')




          • If you only need the parameters, a simple namedtuple will suffice



            You could create a namedtuple that will get rid of the empty looking class




          • IMHO setting the variables outside of the init is bad style



            I would get the different variables needed before, and only then create the NetworkInterface object.




          Note I will not review getting the interface type, since I am nowhere near a linux atm



          Code



          from collections import namedtuple
          import re

          import netifaces

          FILTER_REGEX = re.compile(r'lo|wlp2s0')
          NetworkInterface = namedtuple('NetworkInterface', ['iface', 'mac', 'type'])

          def get_mac(iface):
          addresses = netifaces.ifaddresses(iface)
          return addresses[netifaces.AF_LINK][0].get("addr")

          def get_type(iface):
          """Just return TP for testing"""
          return "TP"

          def find_network_interfaces():
          for iface in netifaces.interfaces():
          if FILTER_REGEX.search(iface):
          continue
          yield NetworkInterface(iface, get_mac(iface), get_type(iface))

          if __name__ == '__main__':
          for nwi in find_network_interfaces():
          print(nwi.iface)
          print(nwi.mac)
          print(nwi.type)





          share|improve this answer











          $endgroup$





          • Start writing in python3.x ;)



            End of Life for python2.x will happen pretty soon 1




          • One regex to rule them all



            Instead of looping over a the list to create a regex,



            you could use the | char which will work as an or so it can handle multiple outputs



            REGEX_FILTER = re.conmpile('lo|wlp2s0')




          • If you only need the parameters, a simple namedtuple will suffice



            You could create a namedtuple that will get rid of the empty looking class




          • IMHO setting the variables outside of the init is bad style



            I would get the different variables needed before, and only then create the NetworkInterface object.




          Note I will not review getting the interface type, since I am nowhere near a linux atm



          Code



          from collections import namedtuple
          import re

          import netifaces

          FILTER_REGEX = re.compile(r'lo|wlp2s0')
          NetworkInterface = namedtuple('NetworkInterface', ['iface', 'mac', 'type'])

          def get_mac(iface):
          addresses = netifaces.ifaddresses(iface)
          return addresses[netifaces.AF_LINK][0].get("addr")

          def get_type(iface):
          """Just return TP for testing"""
          return "TP"

          def find_network_interfaces():
          for iface in netifaces.interfaces():
          if FILTER_REGEX.search(iface):
          continue
          yield NetworkInterface(iface, get_mac(iface), get_type(iface))

          if __name__ == '__main__':
          for nwi in find_network_interfaces():
          print(nwi.iface)
          print(nwi.mac)
          print(nwi.type)






          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Jan 21 at 20:25

























          answered Jan 21 at 16:20









          LudisposedLudisposed

          8,43722164




          8,43722164








          • 1




            $begingroup$
            Since you saved the compiled regexes to a variable, you could do FILTER_REGEX.search(iface).
            $endgroup$
            – Graipher
            Jan 21 at 18:58














          • 1




            $begingroup$
            Since you saved the compiled regexes to a variable, you could do FILTER_REGEX.search(iface).
            $endgroup$
            – Graipher
            Jan 21 at 18:58








          1




          1




          $begingroup$
          Since you saved the compiled regexes to a variable, you could do FILTER_REGEX.search(iface).
          $endgroup$
          – Graipher
          Jan 21 at 18:58




          $begingroup$
          Since you saved the compiled regexes to a variable, you could do FILTER_REGEX.search(iface).
          $endgroup$
          – Graipher
          Jan 21 at 18:58


















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Code Review Stack Exchange!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          Use MathJax to format equations. MathJax reference.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f211915%2flooping-through-multiple-regex-efficiently%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          Can a sorcerer learn a 5th-level spell early by creating spell slots using the Font of Magic feature?

          Does disintegrating a polymorphed enemy still kill it after the 2018 errata?

          A Topological Invariant for $pi_3(U(n))$