So I made a little game that prints everything to the console which consists of some functions, a couple of lists and two extra text files with stats. The standalone game works fine, however, when I stick all the functions in a class and then call the class (so it works with the layout I made using Kivy), the error "name "getValue" is not defined" comes up.
I am confused because putting the functions into a class were the only change I have made. What did I miss?
I know that this would be very vague and unclear without the full code so here it is:
original working file
import time
import random
import os
import operator
import tkinter
import sys
homeIp = "1.1.1.1"
ipNum = homeIp
workingDir = "home/"
found = []
ports = {"ssh":[True,22],"sql":[True,1433],"http":[True,80],"ftp":[True,21]}
admin = True
def load(text,delay):
print(text, end="")
for x in range(0,delay-1):
time.sleep(0.5)
print(".", end="")
print(".")
def createIpList():
global found
for x in range(0,random.randint(1,3)):
found.append(str(random.randint(0,255))+"."+str(random.randint(0,255))+"."+str(random.randint(0,255))+"."+str(random.randint(0,255)))
def connect(ip):
global ipNum
load("trying to connect",8)
if ip in found:
print("connected to "+ip)
ipNum = ip
setPorts()
createIpList()
admin = False
else:
print("ip not found")
def scan():
load("scanning for devices",6)
for x in found:
print(x)
def setPorts():
ports["ssh"][0] = [random.choice([True,False])]
ports["sql"][0] = [random.choice([True,False])]
ports["http"][0] = [random.choice([True,False])]
ports["ftp"][0] = [random.choice([True,False])]
def probe():
print("SSH\t"+str(ports["ssh"][1])+"\t"+str(ports["ssh"][0]).strip("[").strip("]")+"\n"+
"SQL\t"+str(ports["sql"][1])+"\t"+str(ports["sql"][0]).strip("[").strip("]")+"\n"+
"HTTP\t"+str(ports["http"][1])+"\t"+str(ports["http"][0]).strip("[").strip("]")+"\n"+
"FTP\t"+str(ports["ftp"][1])+"\t"+str(ports["ftp"][0]).strip("[").strip("]")+"\n"+
"ALL PORTS MUST BE FALSE TO PORTHACK")
def shutDown():
load("Shutting down ",4)
quit()
def clearScreen():
os.system('cls')
def giveHelp():
print("COMMANDS :")
for key in commands0:
print(key)
for key in commands1:
print(key+" [ ]")
def openPort(portName,portNum):
if portNum == ports[portName][1]:
load("opening port "+str(portNum),10)
ports[portName][0] = False
print("port "+str(portNum)+" opened")
else:
print("Wrong port number")
def portHack():
shut = False
for port in ports:
if str(ports[port][0])== "[True]":
shut = True
if shut == True:
print("Can not operate port hack - all ports must be open")
else:
admin = True
print("You are now system admin")
def inbox():
file = open("emails.txt","r")
for line in file:
if line.strip()=="###EMAIL"+str(int(getValue("email")))+"###":
ended = False
for line in file:
if line.strip()=="###EMAIL"+str(int(getValue("email"))+1)+"###":
ended = True
if ended == False:
print(line)
file.close()
def editValue(var,val):
originalLines = []
file = open("saveData.txt","r")
for line in file:
if len(line)>1:
originalLines.append(line)
file.close()
for x in range(0,len(originalLines)):
if originalLines[x].split("=")[0].strip()==var:
newVal = (float(originalLines[x].split("=")[1].strip())+val)
originalLines[x] = var+"="+str(newVal)
file = open("saveData.txt","w")
for item in originalLines:
file.write(item+"\n")
file.close
def reply():
load("SENDING",3)
def getValue(var):
file = open("saveData.txt","r")
for line in file:
if line.split("=")[0].strip() == var:
return float(line.split("=")[1].strip())
file.close()
def sysSpecs():
print("CPU\t\t"+str(getValue("cpu"))+"GHz\n"+
"RAM\t\t"+str(getValue("ram"))+"GB\n"+
"PSU\t\t"+str(getValue("psu"))+"W\n"+
"STORAGE\t\t"+str(getValue("storage"))+"GB")
if getValue("gpu") == 0:
print("GPU\t\tNONE")
else:
print("GPU\t\t"+str(getValue("gpu"))+"GHz")
def market():
category = input("WELCOME TO AMAZING\n\nCategories\n->CPU\n->RAM\n->storage\n->PSU\n->GPU\n\n[Press ENTER to leave]\n")
measurement={"CPU":"GHz","RAM":"GB","storage":"GB","PSU":"W","GPU":"GHz"}
sortedParts = (sorted(parts[category].items(), key=operator.itemgetter(1)))
print("ITEM\t\t\t|"+measurement[category]+"\t|PRICE\n==================================")
for item in sortedParts:
if len(item[0])>=8:
print(item[0]+"\t\t|"+str(item[1][0])+"\t|"+str(item[1][1]))
else:
print(item[0]+"\t\t\t|"+str(item[1][0])+"\t|"+str(item[1][1]))
def buy(item):
exist = False
itemCat = ""
for category in parts:
for part in parts[category]:
if part == item:
exist = True
itemCat = category
if exist == False:
print("ITEM NOT IN STOCK")
else:
if parts[itemCat][item][1] <= getValue("money"):
print("PURCHASED")
editValue(itemCat.lower(),float(parts[itemCat][item][0])-getValue(itemCat.lower()))
else:
print("INSUFFICIENT BALANCE")
def balance():
print(getValue("money"))
def eventCheck(command):
if int(getValue("email")) == 0:
inbox()
editValue("email",1)
inbox()
if command[0] == "reply":
if int(getValue("email")) == 1:
editValue("email",1)
inbox()
print("$100 recieved")
editValue("money",100)
elif int(getValue("email")) == 3:
if ipNum != homeIp:
if admin == True:
print("CONGRATS")
if int(getValue("email")) == 2:
if getValue("cpu")>=1.5:
editValue("email",1)
def main():
command = input(ipNum+":"+workingDir+">").split(' ')
try:
if len(command) == 1:
commands0[command[0]]()
elif len(command) == 2:
if command[0] == "sshCrack":
commands1[command[0]]("ssh",int(command[1]))
elif command[0] == "sqlInjection":
commands1[command[0]]("sql",int(command[1]))
elif command[0] == "webServerWorm":
commands1[command[0]]("http",int(command[1]))
elif command[0] == "ftpSpoof":
commands1[command[0]]("ftp",int(command[1]))
else:
commands1[command[0]](command[1])
except:
print("",end="")
eventCheck(command)
parts = {"CPU":{"LEG_1":[1.5,100],"LEG_2":[2,200],"AMP_Mk3":[2.5,300],"Inzel_Pontium":[3,500],"Inzel_Eye7":[3.5,700],"AMP_String_Cutter":[4,999]},
"RAM":{"InsaneX_2":[2,40],"Revenger_4":[4,60],"InsaneX_8":[8,100],"Korsair_16":[16,160],"Z.SKILL_FORK":[32,400]},
"storage":{"Sumsing_10":[10,20],"Queenston_50":[50,50],"EastDigital_100":[100,75],"SinDisk_250":[250,120],"CrazyX_500":[500,200],"Sumsing_TB":[1000,499]},
"PSU":{"Korsair_Feather":[200,50],"Korsair_Beefy":[500,130],"Korsair_Ultra":[800,200]},
"GPU":{"ZTX_1050":[2,100],"ZTX_1060":[4,200],"ZTX_1070":[8,400],"ZTX_1080":[16,800]}}
commands0 = {"scan":scan,"probe":probe,"shutdown":shutDown,"cls":clearScreen,"help":giveHelp,"portHack":portHack,"inbox":inbox,
"reply":reply,"market":market,"sysSpecs":sysSpecs,"balance":balance}
commands1 = {"connect":connect,"sshCrack":openPort,"sqlInjection":openPort,"webServerWorm":openPort,"ftpSpoof":openPort,"buy":buy}
setPorts()
createIpList()
eventCheck([""])
while True:
main()
file where the only change is that all functions are put into a class which is then called:
from kivy.app import App
from kivy.clock import Clock
from kivy.core.text import LabelBase
from kivy.core.window import Window
from kivy.uix.gridlayout import GridLayout
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.boxlayout import BoxLayout
from kivy.graphics import Color, Ellipse, Rectangle
from kivy.uix.widget import Widget
import time
import random
import os
import operator
import sys
homeIp = "1.1.1.1"
ipNum = homeIp
workingDir = "home/"
found = []
ports = {"ssh":[True,22],"sql":[True,1433],"http":[True,80],"ftp":[True,21]}
admin = True
class MainWindow(BoxLayout):
def load(text,delay):
print(text, end="")
for x in range(0,delay-1):
time.sleep(0.5)
print(".", end="")
print(".")
def createIpList():
global found
for x in range(0,random.randint(1,3)):
found.append(str(random.randint(0,255))+"."+str(random.randint(0,255))+"."+str(random.randint(0,255))+"."+str(random.randint(0,255)))
def connect(ip):
global ipNum
load("trying to connect",8)
if ip in found:
print("connected to "+ip)
ipNum = ip
setPorts()
createIpList()
admin = False
else:
print("ip not found")
def scan():
load("scanning for devices",6)
for x in found:
print(x)
def setPorts():
ports["ssh"][0] = [random.choice([True,False])]
ports["sql"][0] = [random.choice([True,False])]
ports["http"][0] = [random.choice([True,False])]
ports["ftp"][0] = [random.choice([True,False])]
def probe():
print("SSH\t"+str(ports["ssh"][1])+"\t"+str(ports["ssh"][0]).strip("[").strip("]")+"\n"+
"SQL\t"+str(ports["sql"][1])+"\t"+str(ports["sql"][0]).strip("[").strip("]")+"\n"+
"HTTP\t"+str(ports["http"][1])+"\t"+str(ports["http"][0]).strip("[").strip("]")+"\n"+
"FTP\t"+str(ports["ftp"][1])+"\t"+str(ports["ftp"][0]).strip("[").strip("]")+"\n"+
"ALL PORTS MUST BE FALSE TO PORTHACK")
def shutDown():
load("Shutting down ",4)
quit()
def clearScreen():
os.system('cls')
def giveHelp():
print("COMMANDS :")
for key in commands0:
print(key)
for key in commands1:
print(key+" [ ]")
def openPort(portName,portNum):
if portNum == ports[portName][1]:
load("opening port "+str(portNum),10)
ports[portName][0] = False
print("port "+str(portNum)+" opened")
else:
print("Wrong port number")
def portHack():
shut = False
for port in ports:
if str(ports[port][0])== "[True]":
shut = True
if shut == True:
print("Can not operate port hack - all ports must be open")
else:
admin = True
print("You are now system admin")
def inbox():
file = open("emails.txt","r")
for line in file:
if line.strip()=="###EMAIL"+str(int(getValue("email")))+"###":
ended = False
for line in file:
if line.strip()=="###EMAIL"+str(int(getValue("email"))+1)+"###":
ended = True
if ended == False:
print(line)
file.close()
def editValue(var,val):
originalLines = []
file = open("saveData.txt","r")
for line in file:
if len(line)>1:
originalLines.append(line)
file.close()
for x in range(0,len(originalLines)):
if originalLines[x].split("=")[0].strip()==var:
newVal = (float(originalLines[x].split("=")[1].strip())+val)
originalLines[x] = var+"="+str(newVal)
file = open("saveData.txt","w")
for item in originalLines:
file.write(item+"\n")
file.close
def reply():
load("SENDING",3)
def getValue(var):
file = open("saveData.txt","r")
for line in file:
if line.split("=")[0].strip() == var:
return float(line.split("=")[1].strip())
file.close()
def sysSpecs():
print("CPU\t\t"+str(getValue("cpu"))+"GHz\n"+
"RAM\t\t"+str(getValue("ram"))+"GB\n"+
"PSU\t\t"+str(getValue("psu"))+"W\n"+
"STORAGE\t\t"+str(getValue("storage"))+"GB")
if getValue("gpu") == 0:
print("GPU\t\tNONE")
else:
print("GPU\t\t"+str(getValue("gpu"))+"GHz")
def market():
category = input("WELCOME TO AMAZING\n\nCategories\n->CPU\n->RAM\n->storage\n->PSU\n->GPU\n\n[Press ENTER to leave]\n")
measurement={"CPU":"GHz","RAM":"GB","storage":"GB","PSU":"W","GPU":"GHz"}
sortedParts = (sorted(parts[category].items(), key=operator.itemgetter(1)))
print("ITEM\t\t\t|"+measurement[category]+"\t|PRICE\n==================================")
for item in sortedParts:
if len(item[0])>=8:
print(item[0]+"\t\t|"+str(item[1][0])+"\t|"+str(item[1][1]))
else:
print(item[0]+"\t\t\t|"+str(item[1][0])+"\t|"+str(item[1][1]))
def buy(item):
exist = False
itemCat = ""
for category in parts:
for part in parts[category]:
if part == item:
exist = True
itemCat = category
if exist == False:
print("ITEM NOT IN STOCK")
else:
if parts[itemCat][item][1] <= getValue("money"):
print("PURCHASED")
editValue(itemCat.lower(),float(parts[itemCat][item][0])-getValue(itemCat.lower()))
else:
print("INSUFFICIENT BALANCE")
def balance():
print(getValue("money"))
def getValue(var):
file = open("saveData.txt","r")
for line in file:
if line.split("=")[0].strip() == var:
return float(line.split("=")[1].strip())
file.close()
def eventCheck(command):
if int(getValue("email")) == 0:
inbox()
editValue("email",1)
inbox()
if command[0] == "reply":
if int(getValue("email")) == 1:
editValue("email",1)
inbox()
print("$100 recieved")
editValue("money",100)
elif int(getValue("email")) == 3:
if ipNum != homeIp:
if admin == True:
print("CONGRATS")
if int(getValue("email")) == 2:
if getValue("cpu")>=1.5:
editValue("email",1)
def main():
command = input(ipNum+":"+workingDir+">").split(' ')
try:
if len(command) == 1:
commands0[command[0]]()
elif len(command) == 2:
if command[0] == "sshCrack":
commands1[command[0]]("ssh",int(command[1]))
elif command[0] == "sqlInjection":
commands1[command[0]]("sql",int(command[1]))
elif command[0] == "webServerWorm":
commands1[command[0]]("http",int(command[1]))
elif command[0] == "ftpSpoof":
commands1[command[0]]("ftp",int(command[1]))
else:
commands1[command[0]](command[1])
except:
print("",end="")
eventCheck(command)
parts = {"CPU":{"LEG_1":[1.5,100],"LEG_2":[2,200],"AMP_Mk3":[2.5,300],"Inzel_Pontium":[3,500],"Inzel_Eye7":[3.5,700],"AMP_String_Cutter":[4,999]},
"RAM":{"InsaneX_2":[2,40],"Revenger_4":[4,60],"InsaneX_8":[8,100],"Korsair_16":[16,160],"Z.SKILL_FORK":[32,400]},
"storage":{"Sumsing_10":[10,20],"Queenston_50":[50,50],"EastDigital_100":[100,75],"SinDisk_250":[250,120],"CrazyX_500":[500,200],"Sumsing_TB":[1000,499]},
"PSU":{"Korsair_Feather":[200,50],"Korsair_Beefy":[500,130],"Korsair_Ultra":[800,200]},
"GPU":{"ZTX_1050":[2,100],"ZTX_1060":[4,200],"ZTX_1070":[8,400],"ZTX_1080":[16,800]}}
commands0 = {"scan":scan,"probe":probe,"shutdown":shutDown,"cls":clearScreen,"help":giveHelp,"portHack":portHack,"inbox":inbox,
"reply":reply,"market":market,"sysSpecs":sysSpecs,"balance":balance}
commands1 = {"connect":connect,"sshCrack":openPort,"sqlInjection":openPort,"webServerWorm":openPort,"ftpSpoof":openPort,"buy":buy}
setPorts()
createIpList()
eventCheck([""])
class MainApp(App):
def build(self):
Window.clearcolor = (1,1,1,1)
return MainWindow()
if __name__ == '__main__':
MainApp().run()
Just so you know, the whole point of putting it in a class is so I can use the layout I created using the kv design language in a different piece of code. If it is necessary, I can post my .kv file that is opened by the program.
My attempt is as below, it captures well when i'm typing, but sucks if multiple key pressed. It only capture the first pressed key.
I removed all unrelated to keylogging.
import win32console
import win32gui
import pythoncom, pyHook
import threading
import pickle
class keylogger(object):
def init(self, ifPrintDetail = False):
self.keylog_enable = False
self.ifPrintDetail = ifPrintDetail
self.log = ''
def KeyEvent(self, event):
if self.keylog_enable:
self.log += event.Key
if self.ifPrintDetail:
print ('MessageName:',event.MessageName )
print ('Message:',event.Message)
print ('Time:',event.Time)
print ('Window:',event.Window)
print ('WindowName:',event.WindowName)
print ('Ascii:', event.Ascii, chr(event.Ascii) )
print ('Key:', event.Key)
print ('KeyID:', event.KeyID)
print ('ScanCode:', event.ScanCode)
print ('Extended:', event.Extended)
print ('Injected:', event.Injected)
print ('Alt', event.Alt)
print ('Transition', event.Transition)
print ('---')
elif event.MessageName == 'key down':
print(event.Key, end='')
def threadkeylog(self):
win = win32console.GetConsoleWindow()
win32gui.ShowWindow(win, 0)
# create a hook manager object for both key up and down
self.hm=pyHook.HookManager()
#i want both up and down key event
self.hm.KeyDown = self.KeyEvent
self.hm.KeyUp = self.KeyEvent
# set the hook
self.hm.HookKeyboard()
#start sending messages, this seems not to stop except WM_QUIT
pythoncom.PumpMessages()
def go(self):
#build and start a thread
self.keylog_enable = True
self.threadkl = threading.Thread(target = self.threadkeylog)
self.threadkl.start()
def pause(self):
self.keylog_enable = False
def save(self):
pickle.dump(self.log, open('keylog.txt', 'wb'))
You may use it with
kl = keylogger()
kl.init()
kl.go()#build and run a thread
kl.pause()#"pause" the thread
kl.save()#will save what you have typed to a file in working directory
print(pickle.load(open('keylog.txt', "rb")))#take a look at it
I do this to collect key log of myself playing car racing game, for training data of my machine learning project. So, say, if I control my racing car with simple "WASD" buttons, I would probably hold "W" and "A" to turn left and accelerate. So, I would like to have both of them captured at the same time, but those keys conflicts, and it capture only one character.
Using ctypes alone you can make quite an effective keylogger.
ctypes allows you to check if a key is currently pressed, or toggled.
If you set up a dictionary where all the keys are virtual keycodes and all of the values are the keycode's respective string character then you can iterate through the dictionary, and check if the key is pressed.
Having another dictionary called TrackedKeys which is empty, you can just set TrackedKeys[key] = The bool returned by the ctypes function which sees if a key is pressed when you are ticking in your "main loop" (A while true in the main python file).
then when you update the value of trackedkeys before doing so you can see if the value in trackedkey is different from the value returned by ctypes checking if a key is pressed, and if it is then call a function and pass either "key up" or "key down" to that function.
import threading, time
from ctypes import *
class Thread():
def __init__(self, addressOf, args):
self.terminate = False
self.Instance = threading.Thread(target=addressOf, args=args)
self.Instance.daemon = True
self.Instance.start()
VKStr = {}
VKStr[0x01] = "LEFT_MOUSEE"
VKStr[0x02] = "RIGHT_MOUSE"
VKStr[0x03] = "MIDDLE_MOUSE"
VKStr[0x08] = "BACKSPACE"
VKStr[0x09] = "TAB"
VKStr[0x0D] = "ENTER"
VKStr[0x10] = "SHIFT"
VKStr[0x11] = "CTRL"
VKStr[0x12] = "ALT"
VKStr[0x14] = "CAPSLOCK"
VKStr[0x18] = "ESCAPE"
VKStr[0x20] = " "
VKStr[0x25] = "LEFT_ARROW"
VKStr[0x26] = "UP_ARROW"
VKStr[0x27] = "RIGHT_ARROW"
VKStr[0x28] = "DOWN_ARROW"
VKStr[0x2C] = "PRINT_SCREEN"
VKStr[0x30] = "0"
VKStr[0x31] = "1"
VKStr[0x32] = "2"
VKStr[0x33] = "3"
VKStr[0x34] = "4"
VKStr[0x35] = "5"
VKStr[0x36] = "6"
VKStr[0x37] = "7"
VKStr[0x38] = "8"
VKStr[0x39] = "9"
VKStr[0x41] = "a"
VKStr[0x42] = "b"
VKStr[0x43] = "c"
VKStr[0x44] = "d"
VKStr[0x45] = "e"
VKStr[0x46] = "f"
VKStr[0x47] = "g"
VKStr[0x48] = "h"
VKStr[0x49] = "i"
VKStr[0x4A] = "j"
VKStr[0x4B] = "k"
VKStr[0x4C] = "l"
VKStr[0x4D] = "m"
VKStr[0x4E] = "n"
VKStr[0x4F] = "o"
VKStr[0x50] = "p"
VKStr[0x51] = "q"
VKStr[0x52] = "r"
VKStr[0x53] = "s"
VKStr[0x54] = "t"
VKStr[0x55] = "u"
VKStr[0x56] = "v"
VKStr[0x57] = "w"
VKStr[0x58] = "x"
VKStr[0x59] = "y"
VKStr[0x5A] = "z"
ShiftEquivs={}
ShiftEquivs[0x30] = ")"
ShiftEquivs[0x31] = "!"
ShiftEquivs[0x32] = "\""
ShiftEquivs[0x33] = "£"
ShiftEquivs[0x34] = "$"
ShiftEquivs[0x35] = "%"
ShiftEquivs[0x36] = "^"
ShiftEquivs[0x37] = "&"
ShiftEquivs[0x38] = "*"
ShiftEquivs[0x39] = "("
ActiveKeys = {}
def StringToVK(string):
for key, value in VKStr.items():
if value == string:
return key
def VKToString(VK):
return VKStr[VK]
def IsKeyPressed(VK_KEYCODE):
if type(VK_KEYCODE) == str:
try:
VK_KEYCODE = StringToVK(VK_KEYCODE)
except:
raise Exception("Exception caught in sub: 'IsKeyPressed' arg VK_KEYCODE is invalid")
return
return windll.user32.GetKeyState(c_int(VK_KEYCODE)) & 0x8000 != 0
def IsKeyToggled(VK_KEYCODE):
return windll.user32.GetKeyState(c_int(VK_KEYCODE)) & 0x0001 != 0
class KeyTracker:
def __init__(self):
self.tracking = False
self.tracked_string_concat = ""
self.file_open = False
def StartTracking(self):
self.tracking = True
def StopTracking(self):
self.tracking = False
self.CompileData()
def KeyDown(self, key):
if self.tracking and VKToString(key) != "SHIFT":
if IsKeyToggled(StringToVK("CAPSLOCK")):
self.tracked_string_concat = self.tracked_string_concat + VKToString(key).upper()
elif IsKeyPressed(StringToVK("SHIFT")):
shiftEquiv = False
try:
ShiftEquivs[key]
shiftEquiv = True
except:
pass
if shiftEquiv:
self.tracked_string_concat = self.tracked_string_concat + ShiftEquivs[key]
else:
self.tracked_string_concat = self.tracked_string_concat + VKToString(key).upper()
else:
self.tracked_string_concat = self.tracked_string_concat + VKToString(key)
def KeyUp(self, key):
if self.tracking and VKToString(key) == "SHIFT":
#self.tracked_string_concat = self.tracked_string_concat + VKToString(key)
pass
def UpdateKeyState(self, key, state):
def SetKeyState(key, state):
ActiveKeys[key] = state
if state == True:
self.KeyDown(key)
elif state == False:
self.KeyUp(key)
keyExists = False
try:
ActiveKeys[key]
keyExists = True
except:
pass
if keyExists:
if ActiveKeys[key] != state:
SetKeyState(key, state)
else:
SetKeyState(key, state)
def CompileData(self):
try:
file = open("logger_data.txt", "a")
file.write("\n")
file.write("-"*15)
file.write("\n")
file.write(self.tracked_string_concat)
file.close()
except:
pass
def TrackData(self, time_length): #timeLength in seconds
KeyTracker.StartTracking()
time.sleep(time_length)
KeyTracker.StopTracking()
KeyTracker = KeyTracker()
t = Thread(KeyTracker.TrackData, [5])
while True:
for key, key_name in VKStr.items():
KeyTracker.UpdateKeyState(key, IsKeyPressed(key))
change the argument passed to the thread stored in the variable t to change how long your keylogger records data for, 5 is just a short testing value.
Alright so what I am trying to do is to get objects to save in list form when a user creates a NoteSet. It appends the objects to the list db properly when I input NoteSet('ex','example',True). I made a function called makeNewNoteSet() and it seems to be working correctly but it doesnt append to the db list. I can not figure out why.
import sys
import datetime
import pickle
notesets = []
db = []
def save():
global db
filename = "notesets.dat"
file = open(filename, "wb")
if file == None:
print("There was an error creating your file")
return
pickle.dump(db, file)
file.close()
print("Saved words to ",filename)
def load():
global db
filename = "notesets.dat"
file = open(filename, "rb")
db = pickle.load(file)
print("There are ",len(db)," Note Sets")
file.close()
class NoteSet:
nextseqNum = len(db)+2
def __init__(self,name,description,hidden):
global db
self.seqNum = NoteSet.nextseqNum
self.name = name
self.description = description
self.dateCreated = datetime.date.today()
self.hidden = hidden
self.notes = list()
NoteSet.nextseqNum += 1
print(self)
notesets.append(self)
notelist = [self.seqNum,self.name,self.description,self.dateCreated,self.hidden,self.notes]
print(notelist)
db.append(notelist)
NoteSet.nextseqNum += 1
def __str__(self):
printstr = str(self.seqNum),self.name,self.description,str(self.dateCreated)
printstr = str(printstr)
return printstr
class Note:
nextseqNum = 0
def __init__(self,text,dateCreated,description,category,priority,hidden):
self.text = text
self.dateCreated = str
self.dateRead = str
self.description = str
self.category = str
self.priority = int
self.hidden = bool
self.seqNum = Note.nextseqNum
Note.nextseqNum += 1
def main():
while True:
load()
printMainMenu()
selection = int(input("? "))
if selection == 1:
listNoteSets()
elif selection == 2:
listAllNoteSets()
elif selection == 3:
makeNewNoteSet()
elif selection == 4:
selectNoteSet() # this makes the working note set
elif selection == 5:
deleteNoteSet()
elif selection == 6:
sys.exit()
else:
print("Invalid choice")
def printMainMenu():
print("1. List note sets")
print("2. List all note sets (including hidden sets)")
print("3. Make a new note set")
print("4. Select a working note set")
print("5. Delete a note set")
print("6. Quit")
def listNoteSets():
num = 0
for row in db:
if db[num][4] == False:
print('#',db[num][0],' ',db[num][1],'----',db[num][2])
num += 1
input("[Press return to see main menu]")
main()
def listAllNoteSets():
num = 0
for row in db:
print('#',db[num][0],' ',db[num][1],'----',db[num][2])
num += 1
input("[Press return to see main menu]")
main()
def makeNewNoteSet():
num = 0
name = input("What would you like to name your note set? --- ")
for row in db:
if name == db[num][1]:
print("That note set has already been created")
makeNewNoteSet()
description = input("Describe your note set briefly --- ")
hidden = input("Would you like this note set to be hidden? --- ")
if hidden == 'y' or 'yes':
hidden = True
else:
hidden = False
NoteSet(name, description, hidden)
print("noteset created you can now access it through the menu")
input("[Press enter to return to menu]")
main()
def selectNoteSet():
num = 0
for row in db:
print('#',db[num][0],' ',db[num][1],'----',db[num][2])
num += 1
response = input("Enter the number assosciated with the noteset you would like to access")
print("Note set #",response," was selected")
main()
After you add a new note in makeNewNoteSet(), you call main() which calls load() which overwrites the in-memory copy of the database you just changed. You probably want to call save() somewhere in there.
I have written the code below to handle and collect perfomance counters (including the test lines (at the end of the code)).
However, when I call the function getAndReset(), it seems to reset the values to Zero before outputting the current value of lendingStats dictionary. This is despite the fact that within the function getAndReset() , the lendingStats value is updated first then stored in a variable theStats.
#!/usr/bin/python
import threading
import time, datetime,pytz
startTime = datetime.datetime.now(pytz.timezone('Africa/Nairobi')).strftime('%Y-%m-%d %H:%M:%S%z')
lendingStats = {'ussdRequests':{'getSubInfo':None,'loanRequests':None},'time':{'startTime':startTime,'currentTime':startTime,'last-reset-time:':startTime}}
lendingStatsNow = {'ussdRequests':{'getSubInfo':None,'loanRequests':None},'time':{'startTime':startTime,'currentTime':startTime,'last-reset-time:':startTime}}
subInfoCounter = dict()
loanRequestCounter = dict()
currentTime = startTime
lastResetTime = startTime
def synchronized(func):
func.__lock__ = threading.RLock()
def synced_func(*args, **kws):
with func.__lock__:
return func(*args, **kws)
return synced_func
#synchronized
def lastResetTimeFunc(action):
global lendingStats,subInfoCounter,loanRequestCounter,currentTime,lastResetTime
if action == "Get":
return lastResetTime
elif action == "Update":
lastResetTime = datetime.datetime.now(pytz.timezone('Africa/Nairobi')).strftime('%Y-%m-%d %H:%M:%S%z')
##synchronized
def getAndReset():
global lendingStats,subInfoCounter,loanRequestCounter,currentTime,lastResetTime
# Get the values to return
theStats = dict()
theStats = getLendingStats()
resetStats()
return theStats
#synchronized
def resetStats():
global lendingStats,subInfoCounter,loanRequestCounter,currentTime,lastResetTime
ussdSubInfoStatsFunc(action="Reset")
ussdLoanReqStatsFunc(action="Reset")
lastResetTimeFunc("Update")
#synchronized
def getLendingStats():
global lendingStats,subInfoCounter,loanRequestCounter,currentTime,lastResetTime
# Get the values
# lendingStats['ussdRequests']['getSubInfo'] = ussdSubInfoStatsFunc(action="Get")
# lendingStats['ussdRequests']['loanRequests'] = ussdLoanReqStatsFunc(action="Get")
# lendingStats['time']['last-reset-time'] = lastResetTimeFunc("Get")
# lendingStats['time']['currentTime'] = getCurrentTimeFunc()
returnValue = dict()
for KeyName in lendingStats.iterkeys():
returnValue[KeyName] = dict()
returnValue['ussdRequests']['getSubInfo'] = ussdSubInfoStatsFunc(action="Get")
returnValue['ussdRequests']['loanRequests'] = ussdLoanReqStatsFunc(action="Get")
returnValue['time']['last-reset-time'] = lastResetTimeFunc("Get")
returnValue['time']['currentTime'] = getCurrentTimeFunc()
returnValue['time']['startTime'] = lendingStats['time']['startTime']
lendingStats = returnValue
# Return the Values
return returnValue
#synchronized
def getCurrentTimeFunc():
global lendingStats,subInfoCounter,loanRequestCounter,currentTime,lastResetTime
currentTime = datetime.datetime.now(pytz.timezone('Africa/Nairobi')).strftime('%Y-%m-%d %H:%M:%S%z')
theTime = currentTime
return theTime
#synchronized
def ussdLoanReqStatsFunc(**kwargs):
global lendingStats,subInfoCounter,loanRequestCounter,currentTime,lastResetTime
if kwargs['action'] == "Add":
if loanRequestCounter.has_key(kwargs['respcode']):
if loanRequestCounter[kwargs['respcode']].has_key(kwargs['denom']):
currentcount = loanRequestCounter[kwargs['respcode']][kwargs['denom']]
loanRequestCounter[kwargs['respcode']][kwargs['denom']] = currentcount + 1
else:
loanRequestCounter[kwargs['respcode']][kwargs['denom']] = 1
else:
loanRequestCounter[kwargs['respcode']] = dict()
loanRequestCounter[kwargs['respcode']][kwargs['denom']] = 1
elif kwargs['action'] == "Reset":
for respCodeKeyName in loanRequestCounter.iterkeys():
for denomKeyName in loanRequestCounter[respCodeKeyName].iterkeys():
loanRequestCounter[respCodeKeyName][denomKeyName] = 0
elif kwargs['action'] == "Get":
theDict = loanRequestCounter
return theDict
#synchronized
def ussdSubInfoStatsFunc(**kwargs):
global lendingStats,subInfoCounter,loanRequestCounter,currentTime,lastResetTime
if kwargs['action'] == "Add":
if subInfoCounter.has_key(kwargs['respcode']):
currentcount = subInfoCounter[kwargs['respcode']]
subInfoCounter[kwargs['respcode']] = currentcount + 1
else:
subInfoCounter[kwargs['respcode']] = 1
elif kwargs['action'] == "Reset":
for keyname in subInfoCounter.iterkeys():
subInfoCounter[keyname] = 0
elif kwargs['action'] == "Get":
theDict = subInfoCounter
return theDict
def testSubInfoCounter(KeyName,numOfEvents):
i = 0
while i < numOfEvents:
ussdSubInfoStatsFunc(action="Add",respcode=KeyName)
i +=1
print ussdSubInfoStatsFunc(action="Get")
def testLoanReqCounter(respCodeT,theDenom,numOfEvents):
i = 0
while i < numOfEvents:
ussdLoanReqStatsFunc(action="Add",respcode=respCodeT,denom=theDenom)
i +=1
print ussdLoanReqStatsFunc(action="Get")
thread1 = threading.Thread(target = testLoanReqCounter("0","200",7767))
thread2 = threading.Thread(target = testLoanReqCounter("1","1000",55))
thread1.start()
thread2.start()
thread1.join()
thread2.join()
print "At the beginning:"
print getLendingStats()
print getAndReset()
testSubInfoCounter("9",7)
testSubInfoCounter("0",7000)
testLoanReqCounter("0","200",7767)
testLoanReqCounter("1","200",33)
testLoanReqCounter("0","1000",3928)
testLoanReqCounter("1","1000",55)
testLoanReqCounter("0","5000",492)
testSubInfoCounter("1",3000)
testSubInfoCounter("3",1000)
testSubInfoCounter("0",7000)
print "Cumulatively:"
print getAndReset()
# print getLendingStats()
# resetStats()
time.sleep(3)
print "After the Reset"
# print getLendingStats()
# resetStats()
print getAndReset()
testLoanReqCounter("0","200",7767)
testLoanReqCounter("1","200",33)
testLoanReqCounter("0","1000",3928)
testLoanReqCounter("1","1000",55)
testLoanReqCounter("0","5000",492)
print getLendingStats()
resetStats()
testSubInfoCounter("1",3230)
testSubInfoCounter("3",1901)
testSubInfoCounter("0",76887)
print getAndReset()
time.sleep(4)
print getAndReset()
# print getLendingStats()
# resetStats()
The problem here is that I needed to use a deepcopy as opposed to a simple assignment (which uses a simple copy).
Therefore the code that I needed to change was:
import copy
#synchronized
def getAndReset():
global lendingStats,subInfoCounter,loanRequestCounter,currentTime,lastResetTime
# Get the values to return
theStats = copy.deepcopy(getLendingStats())
resetStats()
return theStats