This is my finished perceptron written in python. Is there anything that I can improve/suggestions? I'm a beginner with python so anything would be helpful!
import random
class Train:
def __init__(self):
self.train = [[10,5,3,False],[3,2,16,True],[4,15,11,False]]
#Initialize training set
self.fired = False #activate when over thresh
self.threshold = 1.0
self.x1 = 1 #weights
self.x2 = -1
self.x3 = 0.5
self.learningRate = 0.1 #not used
#true if fired state == answers in training set
self.correct = [False,False,False]
self.desire ='' #input value
def trainIt(self):
#while one or more of the answers are wrong
while self.correct[1] == False or self.correct[0] == False or self.correct[2] == False:
for i in range(3):
#Perceptron formula
if self.train[i][0]*self.x1+self.train[i][1]*self.x2+self.train[i][2]*self.x3 < self.threshold:
#under thresh, dont fire
self.fired = False
else:
#fire perceptron
self.fired = True
if self.fired == self.train[i][3]:
#if fired state is correct, log it
self.correct[i] = True
else:
#my subsitution for the learning rate
self.x1 += random.randrange(-1,2)
self.x2 += random.randrange(-1,2)
self.x3 += random.randrange(-1,2)
#prints weights
print("W1: "+str(self.x1))
print("W2: "+str(self.x2))
print("W3: "+str(self.x3))
self.Test()
def Test(self):
#random point to test perceptron!
self.test = [3,20,8]
#reset some values
self.fired = False
self.correct = [False,False,False]
#fire if over threshold
if self.test[0]*self.x1+self.test[1]*self.x2 < self.threshold:
self.fired = False
else:
self.fired = True
print("Test Result: "+str(self.fired))
self.desire = input("Was this your desired result? ")
#print the test result and ask the user if the perceptron was right. This would be useful in filtering spam
if self.desire == 'N':
#if it was not right, continue training
print("Okay! Training...")
self.trainIt()
#initialize object and call methods
ptron = Train()
ptron.trainIt()
ptron.Test()
1 Answer 1
Here's your code slightly changed. Please check python conventions, PEP8, etc. Also, learn how to name variables, functions, and classes. Furthermore, learn how to comment. Usually, you comment on the class and the method, the code inside them should be clear enough, you don't need to pollute with comments if you have good variable descriptions, for example.
If you need to comment inside methods, try to comment blocks of code and not almost every line with useless comments (obvious ones) like "set var to True".
One tip I can do to you is to look at opensource codes and check the code style. You will see they differ a little, and some even ignore Python conventions. Anyway, stick to the ones that try to follow PEP8.
Code with general comments
import random
# space after comments
# comment in the same line? double space # comment
# CONSTANT = 1
# variable_name = function_name: Function and variable names should be lowercase,
# with words separated by underscores as necessary to improve readability
# ClassName
# method_name.py
# 'if var == True:' >>> more pythonic is simply:
# 'if var:' or 'if not var:' for False condition
# comment me
class Train:
def __init__(self):
self.train = [[10,5,3,False],[3,2,16,True],[4,15,11,False]]
# Initialize training set
self.fired = False # activate when over thresh (threshold: don't be lazy :-) )
self.threshold = 1.0
self.x1 = 1 # weights
self.x2 = -1
self.x3 = 0.5
self.learningRate = 0.1 # not used
# true if fired state == answers in training set
self.correct = [False,False,False]
self.desire = '' # input value
# comment me
def train_it(self):
'''
You can comment
like this
too
'''
# while one or more of the answers are wrong
# while self.correct[1] == False or self.correct[0] == False or self.correct[2] == False:
# use parenthesis to divide the logic, is easier to read and to understand
while (not self.correct[1]) or (not self.correct[0]) or (not self.correct[2]):
for i in range(3):
# Perceptron formula
# fire perceptron
# You don't need the else in this case. However, leave it if it's more clear to you
self.fired = True
if (self.train[i][0]*self.x1+self.train[i][1]*self.x2+self.train[i][2]*self.x3 < self.threshold):
# under threshold, dont fire
self.fired = False
if self.fired == self.train[i][3]:
# if fired state is correct, log it
self.correct[i] = True
else:
# my subsitution for the learning rate
self.x1 += random.randrange(-1,2)
self.x2 += random.randrange(-1,2)
self.x3 += random.randrange(-1,2)
# prints weights
# using fstrings
# prints should be in another method, learn about callback functions
print(f"W1: {self.x1}")
print(f"W2: {self.x2}")
print(f"W3: {self.x3}")
self.test()
# what does this method do?
def test(self):
# random point to test perceptron!
self.test_lst = [3,20,8]
# reset some values - useless comment!?
self.fired = False
self.correct = [False,False,False]
# fire if over threshold
self.fired = True
if self.test_lst[0]*self.x1+self.test_lst[1]*self.x2 < self.threshold:
self.fired = False
print(f"Test Result: {self.fired}")
self.desire = input("Was this your desired result? 'N' for NO. Anything else for YES: ")
# print the test result and ask the user if the perceptron was right.
# This would be useful in filtering spam
# You need to check if the input is 'N' or 'Y'
if self.desire.lower() == 'n':
#if it was not right, continue training
print("Okay! Training...")
self.train_it()
# main function called when module executed directly
# ex. python3 this_module.py
def main():
# initialize object and call methods - this type of comment is useless in my opinion.
ptron = Train()
ptron.train_it()
ptron.test()
# If you execute this_module.py, main() will be called
# If you import this_module, you need to initialize the object Train()
# in the module that is calling this one:
# import this_module or from this_module import Train
# then just use Train: ptron = Train() etc.
if __name__ == '__main__':
main()
Code without general comments
import random
# Comment me
class Train:
def __init__(self):
self.train = [[10, 5, 3, False],
[3, 2, 16, True],
[4, 15, 11, False]]
# Initialize training set
self.fired = False
self.threshold = 1.0
self.weight = 1
self.x2 = -1
self.x3 = 0.5
self.correct = [False, False, False]
self.input_val = ''
# Comment me
def train_it(self):
# while one or more of the answers are wrong
while not all(self.correct):
# Perceptron formula
for i in range(3):
self.fired = True # fire perceptron
# under threshold, dont fire
if ((self.train[i][0] * self.weight)
+ (self.train[i][1] * self.x2)
+ (self.train[i][2] * self.x3) < self.threshold):
self.fired = False
# if fired state is correct, log it
if self.fired == self.train[i][3]:
self.correct[i] = True
else:
# my subsitution for the learning rate
self.weight += random.randrange(-1,2)
self.x2 += random.randrange(-1,2)
self.x3 += random.randrange(-1,2)
print(f"W1: {self.weight}")
print(f"W2: {self.x2}")
print(f"W3: {self.x3}")
self.test()
# Comment me
def test(self):
self.test_lst = [3, 20, 8] # random point to test perceptron!
self.fired = False
self.correct = [False, False, False]
self.fired = True
# under threshold, dont fire
if ((self.test_lst[0]*self.weight)
+ (self.test_lst[1]*self.x2) < self.threshold):
self.fired = False
print(f"Test Result: {self.fired}")
input_str = "Was this your desired result? "
input_str += "'N' for NO. Anything else for YES: "
self.input_val = input(input_str)
# print the test result and ask the user if the perceptron was right.
# this would be useful in filtering spam
if self.input_val.lower() == 'n':
print("Okay! Training...") # if it was not right, continue training
self.train_it()
# main function called when module executed directly
# ex. python3 this_module.py
def main():
ptron = Train()
ptron.train_it()
ptron.test()
if __name__ == '__main__':
main()
PS: while self.correct[1] == False or self.correct[0] == False or self.correct[2] == False:
was replaced to while not all(self.correct):
-
\$\begingroup\$ Hello Raphael, this is a pretty good first answer, good job! If I might add, I think it'd be easier to see what improvements you propose if they weren't embedded as comments inside the code. You're free to follow this tip or not, either way I think you did great. \$\endgroup\$IEatBagels– IEatBagels2019年11月13日 21:03:33 +00:00Commented Nov 13, 2019 at 21:03
-
\$\begingroup\$ Thanks for all the activity! In the past two years I have learned about torch and tensorflow, which make this stuff a lot easier, but it is awesome to see a perceptron built from scratch, the right way. I appreciate your answer a lot. \$\endgroup\$iamPres– iamPres2019年11月14日 00:05:02 +00:00Commented Nov 14, 2019 at 0:05
-
1\$\begingroup\$ @IEatBagels Thanks, I will follow your tip and post the clean code this evening. iamPres You're welcome. I'm a python beginner too, so these kinds of questions are great for me as they serve as exercises. \$\endgroup\$Raphael– Raphael2019年11月14日 10:15:12 +00:00Commented Nov 14, 2019 at 10:15
Explore related questions
See similar questions with these tags.
def Test(self):
todef test(self):
\$\endgroup\$