6
\$\begingroup\$

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()
asked Feb 10, 2017 at 4:37
\$\endgroup\$
2
  • \$\begingroup\$ Generally you don't put a capital letter for a function name so I would probably modify def Test(self): to def test(self): \$\endgroup\$ Commented Dec 16, 2017 at 15:15
  • \$\begingroup\$ Some python 'standards': space after #, funcion or variable name: function_name, class name: ClassName. You can search for more. \$\endgroup\$ Commented Nov 13, 2019 at 19:51

1 Answer 1

4
\$\begingroup\$

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):

answered Nov 13, 2019 at 20:53
\$\endgroup\$
3
  • \$\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\$ Commented 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\$ Commented 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\$ Commented Nov 14, 2019 at 10:15

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.