Differences
This shows you the differences between two versions of the page.
Both sides previous revision Previous revision | |||
knowledge_base:programming:python:python3 [2024/12/26 23:12] – removed - external edit (Unknown date) 127.0.0.1 | knowledge_base:programming:python:python3 [2024/12/26 23:12] (current) – ↷ Page moved from knowledge_base:programming:python3 to knowledge_base:programming:python:python3 George Wayne | ||
---|---|---|---|
Line 1: | Line 1: | ||
+ | ====== Python Programming ====== | ||
+ | |||
+ | ===== Python Virtual Environments ===== | ||
+ | |||
+ | ==== Create virtual environment inside the project folder ==== | ||
+ | |||
+ | < | ||
+ | python -m venv .venv | ||
+ | </ | ||
+ | |||
+ | ==== Activate It ==== | ||
+ | |||
+ | < | ||
+ | .\.venv\Scripts\activate | ||
+ | </ | ||
+ | |||
+ | ==== Install Packages ==== | ||
+ | |||
+ | < | ||
+ | pip install < | ||
+ | </ | ||
+ | |||
+ | ==== Create Requirements.txt ==== | ||
+ | |||
+ | < | ||
+ | pip freeze > requirements.txt | ||
+ | </ | ||
+ | |||
+ | ==== Install Packages All at Once ==== | ||
+ | |||
+ | < | ||
+ | pip install -r requirements.txt | ||
+ | </ | ||
+ | |||
+ | ==== Deactivate ==== | ||
+ | |||
+ | < | ||
+ | deactivate | ||
+ | </ | ||
+ | |||
+ | |||
+ | |||
+ | ===== Distribute Standalone EXE using Pyinstaller ===== | ||
+ | |||
+ | **Note: It is highly recommended to download the Python program from python.org directly. Python installed from Microsoft Store may have issues (speaking from my personal experience when wxPython was used)** | ||
+ | - Install pyinstaller package '' | ||
+ | - Execute '' | ||
+ | |||
+ | ===== Regular Expression ===== | ||
+ | |||
+ | https:// | ||
+ | |||
+ | ===== Threading ===== | ||
+ | |||
+ | https:// | ||
+ | |||
+ | ===== Pandas Dataframe Multiindexing ===== | ||
+ | |||
+ | https:// | ||
+ | |||
+ | ===== My NTAG, I2C, Wifi, Subprocess, Timeout, Argparsing Example ===== | ||
+ | **tested on Raspbian Jessie** | ||
+ | < | ||
+ | # | ||
+ | import smbus | ||
+ | import math | ||
+ | import re | ||
+ | import subprocess | ||
+ | import shlex | ||
+ | import os | ||
+ | import time | ||
+ | import signal | ||
+ | import functools | ||
+ | import argparse | ||
+ | |||
+ | # common i2c functions are: | ||
+ | # read_byte(addr) | ||
+ | # write_byte(addr, | ||
+ | # read_byte_data(addr, | ||
+ | # write_byte_data(addr, | ||
+ | # read_word_data(addr, | ||
+ | # write_word_data(addr, | ||
+ | # read_i2c_block_data(addr, | ||
+ | # write_i2c_block_data(addr, | ||
+ | |||
+ | class TimedOut(Exception): | ||
+ | pass | ||
+ | |||
+ | def call_with_timeout(timeout, | ||
+ | """ | ||
+ | f returns, raise TimedOut. The exception is raised asynchronously, | ||
+ | so data structures being updated by f may be in an inconsistent state. | ||
+ | """ | ||
+ | def handler(signum, | ||
+ | raise TimedOut(" | ||
+ | |||
+ | old = signal.signal(signal.SIGALRM, | ||
+ | try: | ||
+ | signal.alarm(timeout) | ||
+ | try: | ||
+ | return f(*args, **kwargs) | ||
+ | finally: | ||
+ | signal.alarm(0) | ||
+ | finally: | ||
+ | signal.signal(signal.SIGALRM, | ||
+ | |||
+ | def with_timeout(timeout): | ||
+ | """ | ||
+ | number of seconds. | ||
+ | """ | ||
+ | def decorator(f): | ||
+ | @functools.wraps(f) | ||
+ | def wrapped(*args, | ||
+ | return call_with_timeout(timeout, | ||
+ | return wrapped | ||
+ | return decorator | ||
+ | |||
+ | # def run_program(rcmd): | ||
+ | # Runs a program, and it's parameters (e.g. rcmd = 'ls -lh / | ||
+ | # Returns output if sucessful, or None and logs error if not. | ||
+ | @with_timeout(50) | ||
+ | def run_program(rcmd, | ||
+ | cmd = shlex.split(rcmd) | ||
+ | try: | ||
+ | proc = subprocess.Popen(cmd, | ||
+ | if (wpacli): | ||
+ | for line in iter(proc.stdout.readline, | ||
+ | line = line.decode(' | ||
+ | if (re.search(r' | ||
+ | print(line, | ||
+ | scanned = re.search(r" | ||
+ | if (scanned): print(' | ||
+ | elif (re.search(r' | ||
+ | print(line, | ||
+ | break | ||
+ | elif (re.search(r' | ||
+ | print(line, | ||
+ | # break # not connected but could be another ssid to try | ||
+ | elif (re.search(r' | ||
+ | re.search(r' | ||
+ | re.search(r' | ||
+ | elif (re.search(r'< | ||
+ | resp = proc.communicate(input=b' | ||
+ | else: | ||
+ | resp = proc.communicate() | ||
+ | except TimedOut: | ||
+ | print(' | ||
+ | proc.terminate() | ||
+ | resp = proc.communicate() | ||
+ | finally: | ||
+ | return resp | ||
+ | |||
+ | # Function to put credentials to / | ||
+ | # Returns True if updated or added, False if nothing to do | ||
+ | def addwpa(ssid, | ||
+ | if (not ssid or not psk): return | ||
+ | try: | ||
+ | f = open('/ | ||
+ | wpafile = f.read() | ||
+ | pattern = r' | ||
+ | # | ||
+ | network = re.search(pattern, | ||
+ | if (network): # update exiting network | ||
+ | oldpsk = network.group(2) | ||
+ | if (psk != oldpsk): # only do work if needed | ||
+ | substr = r' | ||
+ | newfile = re.subn(pattern, | ||
+ | f = open('/ | ||
+ | f.write(newfile[0]) | ||
+ | f.close() | ||
+ | print(' | ||
+ | return True | ||
+ | else: | ||
+ | print(' | ||
+ | return False | ||
+ | else: # add new network | ||
+ | newnet = ' | ||
+ | f = open('/ | ||
+ | f.write(newnet) | ||
+ | f.close() | ||
+ | print(' | ||
+ | return True | ||
+ | except (OSError, IOError) as err: | ||
+ | print(err) | ||
+ | |||
+ | def read_ntag(): | ||
+ | bus = smbus.SMBus(1) | ||
+ | addr = 0x55 | ||
+ | block1 = bus.read_i2c_block_data(addr, | ||
+ | try: | ||
+ | if (block1[1] == 0xFF and block[2] != 0xD1): | ||
+ | raise ValueError(' | ||
+ | if (block1[2] != 0xD1): raise ValueError(' | ||
+ | if (block1[5] != 0x54): raise ValueError(' | ||
+ | recordlen = block1[4] | ||
+ | payload = block1[9: | ||
+ | i = 0x2 | ||
+ | while i <= 0x2 + math.floor((recordlen-9)/ | ||
+ | block = bus.read_i2c_block_data(addr, | ||
+ | payload = payload + block | ||
+ | i = i+1 | ||
+ | # | ||
+ | del payload[recordlen-2: | ||
+ | if (payload[recordlen-3] != 0xFE): | ||
+ | raise ValueError(' | ||
+ | del payload[recordlen-3: | ||
+ | payload = '' | ||
+ | value = re.findall(r' | ||
+ | if (len(value)< | ||
+ | return value[0][1], | ||
+ | except ValueError as err: | ||
+ | print(err) | ||
+ | finally: | ||
+ | bus.close() | ||
+ | |||
+ | |||
+ | |||
+ | # main function | ||
+ | def main(): | ||
+ | parser = argparse.ArgumentParser() | ||
+ | parser.add_argument(' | ||
+ | args = parser.parse_args() | ||
+ | |||
+ | username, password = read_ntag() | ||
+ | if (args.force or addwpa(username, | ||
+ | # re-start wpa_supplicant | ||
+ | print(' | ||
+ | if (not os.path.isfile('/ | ||
+ | print(' | ||
+ | resp = run_program(' | ||
+ | for x in list(map(lambda x: x.decode(' | ||
+ | # | ||
+ | else: | ||
+ | print(' | ||
+ | resp = run_program(' | ||
+ | for x in list(map(lambda x: x.decode(' | ||
+ | time.sleep(3) | ||
+ | print(' | ||
+ | resp = run_program(' | ||
+ | for x in list(map(lambda x: x.decode(' | ||
+ | resp = run_program(' | ||
+ | for x in list(map(lambda x: x.decode(' | ||
+ | resp = run_program(' | ||
+ | for x in list(map(lambda x: x.decode(' | ||
+ | print(' | ||
+ | time.sleep(10) | ||
+ | ipaddr = subprocess.check_output([' | ||
+ | print(' | ||
+ | else: print(' | ||
+ | print(' | ||
+ | |||
+ | if __name__ == ' | ||
+ | main() | ||
+ | </ | ||
+ | |||
+ | ===== Subprocess and Wifi ===== | ||
+ | |||
+ | < | ||
+ | # | ||
+ | # -*- coding: utf-8 -*- | ||
+ | # [email protected] / @glennzw | ||
+ | # Handle wireless networking from Python | ||
+ | # The name (evil.py) is a play on ' | ||
+ | from subprocess import Popen, call, PIPE | ||
+ | import errno | ||
+ | from types import * | ||
+ | import logging | ||
+ | import sys | ||
+ | import logging | ||
+ | import time | ||
+ | import argparse | ||
+ | import re | ||
+ | import shlex | ||
+ | |||
+ | SUPPLICANT_LOG_FILE = " | ||
+ | |||
+ | """ | ||
+ | This bit of code allows you to control wireless networking | ||
+ | via Python. I chose to encapsualte wpa_supplicant because | ||
+ | it has the most consistent output with greatest functionality. | ||
+ | |||
+ | Currently supports OPEN, WPA[2], and WEP. | ||
+ | |||
+ | #e.g: | ||
+ | |||
+ | >>> | ||
+ | >>> | ||
+ | >>> | ||
+ | >>> | ||
+ | >>> | ||
+ | True | ||
+ | >>> | ||
+ | >>> | ||
+ | True | ||
+ | |||
+ | """ | ||
+ | |||
+ | logging.basicConfig(level=logging.DEBUG, | ||
+ | format=' | ||
+ | datefmt=' | ||
+ | filename=' | ||
+ | filemode=' | ||
+ | |||
+ | |||
+ | def run_program(rcmd): | ||
+ | """ | ||
+ | Runs a program, and it's paramters (e.g. rcmd=" | ||
+ | Returns output if successful, or None and logs error if not. | ||
+ | """ | ||
+ | |||
+ | cmd = shlex.split(rcmd) | ||
+ | executable = cmd[0] | ||
+ | executable_options=cmd[1: | ||
+ | |||
+ | try: | ||
+ | proc = Popen(([executable] + executable_options), | ||
+ | response = proc.communicate() | ||
+ | response_stdout, | ||
+ | except OSError, e: | ||
+ | if e.errno == errno.ENOENT: | ||
+ | logging.debug( " | ||
+ | else: | ||
+ | logging.error( "O/S error occured when trying to run ' | ||
+ | except ValueError, e: | ||
+ | logging.debug( "Value error occured. Check your parameters." | ||
+ | else: | ||
+ | if proc.wait() != 0: | ||
+ | logging.debug( " | ||
+ | return response | ||
+ | else: | ||
+ | logging.debug( " | ||
+ | return response_stdout | ||
+ | |||
+ | |||
+ | def start_wpa(_iface): | ||
+ | """ | ||
+ | Terminates any running wpa_supplicant process, and then starts a new one. | ||
+ | """ | ||
+ | run_program(" | ||
+ | time.sleep(1) | ||
+ | run_program(" | ||
+ | |||
+ | def get_wnics(): | ||
+ | """ | ||
+ | Kludgey way to get wireless NICs, not sure if cross platform. | ||
+ | """ | ||
+ | r = run_program(" | ||
+ | ifaces=[] | ||
+ | for line in r.split(" | ||
+ | if " | ||
+ | ifaces.append( line.split()[0] ) | ||
+ | return ifaces | ||
+ | |||
+ | |||
+ | |||
+ | def get_networks(iface, | ||
+ | """ | ||
+ | Grab a list of wireless networks within range, and return a list of dicts describing them. | ||
+ | """ | ||
+ | while retry > 0: | ||
+ | if " | ||
+ | networks=[] | ||
+ | r = run_program(" | ||
+ | if " | ||
+ | for line in r.split(" | ||
+ | b, fr, s, f = line.split()[: | ||
+ | ss = " " | ||
+ | networks.append( {" | ||
+ | return networks | ||
+ | retry-=1 | ||
+ | logging.debug(" | ||
+ | time.sleep(0.5) | ||
+ | logging.error(" | ||
+ | |||
+ | |||
+ | def _disconnect_all(_iface): | ||
+ | """ | ||
+ | Disconnect all wireless networks. | ||
+ | """ | ||
+ | lines = run_program(" | ||
+ | if lines: | ||
+ | for line in lines[1: | ||
+ | run_program(" | ||
+ | |||
+ | |||
+ | def connect_to_network(_iface, | ||
+ | """ | ||
+ | Associate to a wireless network. Support _type options: | ||
+ | *WPA[2], WEP, OPEN | ||
+ | """ | ||
+ | _disconnect_all(_iface) | ||
+ | time.sleep(1) | ||
+ | if run_program(" | ||
+ | if run_program(' | ||
+ | if _type == " | ||
+ | run_program(" | ||
+ | run_program(" | ||
+ | elif _type == " | ||
+ | run_program(' | ||
+ | elif _type == " | ||
+ | run_program(" | ||
+ | else: | ||
+ | logging.error(" | ||
+ | | ||
+ | run_program(" | ||
+ | | ||
+ | def is_associated(_iface): | ||
+ | """ | ||
+ | Check if we're associated to a network. | ||
+ | """ | ||
+ | if " | ||
+ | return True | ||
+ | return False | ||
+ | |||
+ | def has_ip(_iface): | ||
+ | """ | ||
+ | Check if we have an IP address assigned | ||
+ | """ | ||
+ | status = run_program(" | ||
+ | r = re.search(" | ||
+ | if r: | ||
+ | return r.group(1) | ||
+ | return False | ||
+ | |||
+ | def do_dhcp(_iface): | ||
+ | """ | ||
+ | Request a DHCP lease. | ||
+ | """ | ||
+ | run_program(" | ||
+ | |||
+ | |||
+ | def main(): | ||
+ | print "[--- EViL. Python wireless network manager. ---]" | ||
+ | print " | ||
+ | parser = argparse.ArgumentParser() | ||
+ | parser.add_argument(" | ||
+ | parser.add_argument(" | ||
+ | parser.add_argument(" | ||
+ | parser.add_argument(" | ||
+ | parser.add_argument(" | ||
+ | parser.add_argument(" | ||
+ | parser.add_argument(" | ||
+ | args = parser.parse_args() | ||
+ | |||
+ | if len(sys.argv) < 2: | ||
+ | print "[!] No options supplied. Try --help." | ||
+ | sys.exit(-1) | ||
+ | |||
+ | if args.nics: | ||
+ | nics = get_wnics() | ||
+ | if nics: | ||
+ | print "[+] Available NICs:" | ||
+ | for nic in get_wnics(): | ||
+ | print nic | ||
+ | else: | ||
+ | print "[W] No wireless interfaces found :-(" | ||
+ | elif args.list: | ||
+ | if not args.iface: | ||
+ | print "[!] Please specify interface. Use --help for help." | ||
+ | sys.exit(-1) | ||
+ | else: | ||
+ | if args.iface not in get_wnics(): | ||
+ | print "[E] Bad interface! - ' | ||
+ | sys.exit(-1) | ||
+ | print "[+] Searching for available networks..." | ||
+ | start_wpa(args.iface) | ||
+ | networks = get_networks(args.iface) | ||
+ | if networks: | ||
+ | networks = sorted(networks, | ||
+ | print "[+] Networks in range:" | ||
+ | for network in networks: | ||
+ | print " SSID: | ||
+ | print " Sig: | ||
+ | print " BSSID: | ||
+ | print " Flags: | ||
+ | print " Freq: | ||
+ | else: | ||
+ | print "[W] No wireless networks detected :-(" | ||
+ | elif args.connect: | ||
+ | if not args.iface or not args.ssid or not args.type or (args.type != " | ||
+ | print "[E] Missing options for --connect. Check --help for assistance." | ||
+ | sys.exit(-1) | ||
+ | else: | ||
+ | sys.stdout.write( "[+] Associating to ' | ||
+ | sys.stdout.flush() | ||
+ | if args.iface not in get_wnics(): | ||
+ | print "[E] No such wireless interface! - ' | ||
+ | sys.exit(-1) | ||
+ | start_wpa(args.iface) | ||
+ | connect_to_network(args.iface, | ||
+ | while not is_associated(args.iface): | ||
+ | time.sleep(1) | ||
+ | print " | ||
+ | sys.stdout.write(" | ||
+ | sys.stdout.flush() | ||
+ | do_dhcp(args.iface) | ||
+ | while not has_ip(args.iface): | ||
+ | time.sleep(1) | ||
+ | print " | ||
+ | print "[+] Associated and got lease. Hoorah." | ||
+ | |||
+ | if __name__ == " | ||
+ | main() | ||
+ | </ | ||
+ | |||
+ | ===== Resources ===== | ||
+ | |||
+ | ==== Plotly & Dash ==== | ||
+ | |||
+ | - https:// | ||
+ | - https:// | ||
+ | - https:// | ||
+ | - https:// | ||
+ | - https:// | ||
+ | - https:// | ||
+ | |||
+ | |||