Crash Course In Python 3
Python is a popular general-purpose programming language. For a while now, I wanted to pick up the language, however learning for the sake of learning is hard for me, until it was required of me to do my work. I spent a week learning python in order to do some embedded development work. I made myself a cheat sheet for future refresher/reference.
Setup:
- Anaconda
- Python 3.6
- PyCharm IDE
Python Basics
import math import random import json # single line comment ''' multi line comment ''' def python_variable(): # call the name of the current function print(python_variable.__name__) int_variable = 1 float_variable = 2.345 string_variable = "Hello there young one" # single line def and initialization a, b, c = 1, 4.33, "Hi There" # variables can be feed by deleting them del a # variables can be redefined into different types a = 0x2 a = "HI" # complex number a = 3.14j some_string = "Another test string" some_string_a = string_variable[0] # A some_string_b = some_string[2:5] # Character from 2 to 5 index def python_arrays(): print(python_arrays.__name__) # CLASS: List can store mix types some_list = ["Hi my name is", "Masum", "age", 23, "height", 172.2, "CM"] print(type(some_list), "\n Print the whole list: ", some_list, "\n Or just a element of the the list", some_list[1]) # Generate list some_list = [x for x in range(0, 100, 5)] # same as some_list_2 = [] for x in range(0, 100, 5): some_list_2.append(x) def python_tuples(): print(python_tuples.__name__) # Similar to list but size cannot extend tuple_list = (123, "2345fg", 234.44) def python_dictionaries(): print(python_dictionaries.__name__) # Python dictionary is is similar to a hash table dict_key_pair = {0} dict_key_pair["Key_1"] = "002223444" dict_key_pair["Key_2"] = 8.334 # Or it can be defined like this some_dict = {"Name": "Masum", "Age": 23.2, "Height CM": 172.2} def data_conversion(): print(data_conversion.__name__) ''' Convert to Int ''' float_variable_conv = 23.5 int_variable_conv = int(float_variable_conv) # 23 gets saved ''' Convert to Float''' some_int_a = 44 float_string_conv = float(some_int_a) ''' Convert to Complex Number ''' list_a = [234, 55.3] complex_number = complex(33, 21) def python_operators(): add_op = 3 + 4 sub_op = 4 - 2 multi_op = 4 * 5 div_op = 67 / 5 mod_op = 10 % 3 exponent_op = 3**3 # 3^3 = 27 floor_div = 9//2 # 9 // 2 = 4 # Equal == # Not Equal != # More Than > # Less Than < # More Than Equal to >= # Less Than Equal to <= ''' Bitwise Operator ''' # Bitwise AND: & # Bitwise OR: | # Bitwise XOR: ^ # Bitwise invert: ~ # Bitwise shift right: >> # Bitwise shit left: << ''' Logical Operator ''' # Logical AND: AND, and # Logical OR: OR, or # Logical NOT: NOT, not ''' Python Membership Operators''' # E.g var_x in var_y evaluates to True if var_x value is a member of var_y # E.g var_x not in var_y evaluates to True if var_x value is not a member of var_y def python_if_statement(): print(python_if_statement.__name__) var_y = 5 var_x = [1, 4, 55, 6] if var_x[0] == 1: print("First index is: ", var_x[0]) if var_y in var_x: print("Contains ", var_y) elif var_x[0] == 1: print("First index is: ", var_x[0]) else: print("Nope") def python_switch_statement(): print(python_switch_statement.__name__) def python_loops(): print(python_loops.__name__) some_list = [x for x in range(5, 25, 5)] some_dict = {"Key_1": 10, "Key_2": 12.5} # for loop example print("Simple for loop using range") for x in range(10): print(x) print("Simple loop using range with step size") for x in range(5, 20, 2): print(x) print("Loops list using an iterator") for x in some_list: print(x) print("Loops Dictionary ") for key, value in some_dict.items(): print("Key: ", key) print("Values ", value) print("While Loop") while x < 10: x += 1 print(x) def python_number(): some_list = [x for x in range(-22, 10, 4)] ''' Maths Functions ''' absolute_value = abs(some_list[0]) print(absolute_value) # prints 22 float_abs = math.fabs(-22.33) print(float_abs) # 22.33 smallest_int = math.ceil(66.78) print(smallest_int) # prints 66 # exponential expo_value = math.exp(2) # e^2 print(expo_value) # log(x) base 2 # log10(x) base 10 # max(var1, var2, ...) returns largest # min(var1, var2, ...) returns smallet # modf this is pretty cool modf_var = math.modf(10.4) print(modf_var) # returns a tuple (0.40000000000000036, 10.0) round_number = round(23.4444433324, 3) print(round_number) print(math.sqrt(144)) def python_random_number(): random_number_from_a_list = random.choice([x for x in range(10, 100, 2)]) print("Random Number From A List", random_number_from_a_list) random_number_from_range = random.randrange(0, 20, 3) print("Random Number From A Range: ", random_number_from_range) print("Random Float From 0 to 1 ", random.random()) print("Random Seed ", random.seed()) shuffle_list = [x for x in range(0, 10, 1)] random.shuffle(shuffle_list) print("Shuffle List: ", shuffle_list) def python_io(): str_name = input("Enter your name ") user_age = int(input("Enter Age")) print(str_name, user_age) some_dict = {"Name": str_name, "Age": user_age} print(some_dict) file = open('test_file_a.json', 'w') file_string = json.dumps(some_dict, indent=4) file.write(file_string) with open('test_file_b.json', 'w') as file_obj: json.dump(some_dict, file_obj, indent=4)
Python OOP
# Subclass / Parent Class / Base Class class Employee: num_of_emps = 0 raise_amount = 1.04 # raise 4 % per year # Default Ctor def __init__(self, first_name, last_name, salary): self.first_name = first_name self.last_name = last_name self.salary = salary self.email = first_name + '.' + last_name + '@gmail.com' Employee.num_of_emps += 1 # Default Dtor def __del__(self): print("Object Deleted") # Example Instance Method / Function def get_full_name(self): return '{} {}'.format(self.first_name, self.last_name) # Example of Instance Method / Function def apply_raise(self): self.salary = int(self.salary * Employee.raise_amount) # Example of Class Method / Function - similar to C++ static functions @classmethod def set_raise_amt(cls, amount): cls.raise_amount = amount # Python Ctor overloaded using @classmethod, the return statement calls the class ctor # Since cls is the class it is the same as calling Employee() @classmethod def ctor_from_string(cls, cls_str): first_name, last_name, salary = cls_str.split('-') return cls(first_name, last_name, salary) # Python static functions do not use / alter class attribute however the functionality is # loosely related to the class @staticmethod def is_workday(day): if day.weekday() == 5 or day.weekday == 6: # Monday = 0 ... Sunday = 6 return False return True # Class/ Child Class / Super Class class Developer(Employee): raise_amount = 1.05 # 5% per year def __init__(self, first_name, last_name, salary, lang): super(Developer, self).__init__(first_name, last_name, salary) self.prog_lang = lang def learn_new_lang(self, new_lang): self.prog_lang.append(new_lang) @classmethod def get_raise_amount(cls): return cls.raise_amount new_dev_a = Developer("Alex", "Smith", 35000, "Javascript") print(new_dev_a.prog_lang) print(new_dev_a.salary
Python kwargs, args
# min_value(33,44,3,2,66,75,2,-77,0.43) # will return -77 def min_value(*args): result = args[0] for item in args: if item < result: result = item return result # Accepts dictionary like input and returns a dictionary def some_kwarg_func(**kwargs): print(kwargs) return kwargs
Sandbox – Matplotlib, PySerial, Thread, JSON, IO
main.py
import serial_logger import time import sys is_running = True def main(): global is_running serial_logger.com_port = input("Enter the RTD board com port e.g COM11 ") serial_logger.start_rtd_thread() while is_running: input_str = input(" Enter STOP to Stop Logging ") if input_str != "STOP": time.sleep(1) else: is_running = False serial_logger.is_logging = False serial_logger.join_rtd_thread() sys.exit() # Press the green button in the gutter to run the script. if __name__ == '__main__': main()
serial_logger.py
import serial import threading import json import csv is_logging = True com_port = "" def read_rtd_serial(): global is_logging # Connect to correct com port - currently hard coded rtd_serial_in = serial.Serial(com_port, 921600, timeout=0.5) rtd_serial_in.flushInput() # CSV File Header field_name = ["ADC ChA1", "ADC ChA2", "ADC ChA3", "ADC ChA4", "ADC ChA5", "ADC ChA6", "ADC ChA7", "ADC ChA8", "ADC ChB1", "ADC ChB2", "ADC ChB3", "ADC ChB4", "ADC ChB5", "ADC ChB6", "ADC ChB7", "ADC ChB8", "ADC ChC1", "ADC ChC2", "ADC ChC3", "ADC ChC4", "ADC ChC5", "ADC ChC6", "ADC ChC7", "ADC ChC8", "UI Logger Period", "UI Logger Enabled", "UI Test ID", "UI Mock Chip ID", "UI Test Run Time", "UI CChiller Power", "UI CPump Power", "UI Fluidic Temperature", "UI Chiller Auto Mode", "UI Heater One", "UI Heater Two", "UI Heater Three", "UI Heater Four" ] # Creates a new file is file does not already exist, then adds the correct header. f = open("rtd_logger.csv", "w", newline='', encoding="utf-8") tmp = csv.DictWriter(f, fieldnames=field_name) tmp.writeheader() f.close() # Logging Thread : saves board settings and RTD count in a CSV file while is_logging: serial_byte = rtd_serial_in.readline() json_string = serial_byte.decode("utf-8") if json_string != '': # print("Running") no_newline = json_string.rstrip('\n') log_string = no_newline.replace("}{", ", ") compose_dict = json.loads(log_string) with open("rtd_logger.csv", "a", newline='') as f: data_log = csv.DictWriter(f, fieldnames=field_name) data_log.writerow(compose_dict) # print(compose_dict) # when leaving the thread close serial connection rtd_serial_in.close() serial_rtd = threading.Thread(target=read_rtd_serial) # function to start the RTD thread def start_rtd_thread(): global serial_rtd serial_rtd.start() def join_rtd_thread(): serial_rtd.join()
sandbox_matlibplot.py
from matplotlib import animation import matplotlib.pyplot as plt from stm32_serial import adc_dictionary import threading import collections counter = 0 cy_data = collections.deque([[0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0]]) cx_data = collections.deque([[0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0]]) fig, ax = plt.subplots() ax.set_xlim(0, 200) #plt.show() def adc_animate(): i = 0 global counter plt.cla() for key, value in adc_dictionary.items(): cx_data[i].append(int(counter)) cy_data[i].append(int(value)) ax.plot(cx_data[i], cy_data[i], label=key) counter += 1 if counter > 1000: cx_data[i].pop(0) cy_data[i].pop(0) i += 1 plt.draw() plt.pause(0.001) def plot_init(): plt.ion() plt.show() ax.legend() def start_plot_thread(): plot_init() plot_animate = threading.Thread(target=adc_animate) plot_animate.start() #ani = animation.FuncAnimation(fig, adc_animate, frames=10, interval=100) ''' for _ in range(10): for key, value in adc_dictionary.items(): plt.plot(counter, int(value), label=key) counter += 1 plt.show() '''