# AppJar number pad and keyboard

I am currently working on a python program with appJar. This program is made for Raspberry, as I wanted to create a program that is portable. I wanted to insert a virtual keyboard into it, by using buttons, and I currently succeeded by building one. This because it is much more useful for a little touch-screen. Here is the code of the full program:

import csv
import RPi.GPIO as GPIO
import time
from appJar import gui
#all the names of the buttons are in italian
l=[]
class misure: #class where I manage all the measures and the functions of the entries
global l
def nome_file(self):
nome_file=app.getEntry("e1") +'.csv'
return nome_file
def verticale(self):
verticale=float(app.getEntry("e2"))
return verticale
def prof_tot(self):
prof_tot=float(app.getEntry("e3"))
return prof_tot
def dist_riv(self):
mis=float(app.getEntry("e2"))
return mis
def dist_fond(self):
dist_fond=float(app.getEntry("e4"))
return dist_fond
def cambia_mis(self):
app.clearEntry("e2")
app.clearEntry("e3")
app.clearEntry("e4")
app.clearLabel("e5")
app.showButton("Inizia misura")
app.setFocus("e2")
def cambia_prof(self):
prof=float(app.getEntry("e4"))
v=app.getLabel("e5")
l.append(prof)
l.append(v)
print(l)
app.clearEntry("e4")
app.showButton("Inizia misura")
def cambia_staz(self):
app.clearEntry("e1")
app.clearEntry("e2")
app.clearEntry("e3")
app.clearEntry("e4")
app.clearLabel("e5")
app.showButton("Inizia misura")
app.setFocus("e1")
def mulinello(self):
mulinello=app.getOptionBox("Mulinello")
return mulinello
def tempo_mis(self):
tempo_mis=app.getOptionBox("Secondi misurazione")
return float(tempo_mis)

class calcoli: #here are all of the calculation to transform rotation of an hydrometer reel to speed
def velocita(self,mulinello,giri):
v=0
giri_1s=0
if giri=='':
v=''
return v
giri=float(giri)
giri_1s=giri/30
if giri_1s==0:
v=0
return v
if mulinello=='125':
if giri_1s<1.98:
v=(1.93+(31.17*giri_1s))/100
return v
elif giri_1s<10.27:
v=(0.19+(32.05*giri_1s))/100
return v
else:
v=(-14.09+(33,44*giri_1s))/100
return v
elif mulinello=='80':
if giri_1s<1:
v=(2.8+(31.34*giri_1s))/100
return v
else:
v=(0.82+(33.32*giri_1s))/100
return v
elif mulinello=='50':
if giri_1s<1.74:
v=(1.23+(24.73*giri_1s))/100
return v
else:
v=(-0.42+(25.68*giri_1s))/100
return v
elif mulinello=='30':
if giri_1s<1.16:
v=(1.90+(10.57*giri_1s))/100
return v
else:
v=(2.26+(10.26*giri_1s))/100
return v
def conta_giri(self,temp_mis):
"""print(temp_mis)
giri=input('Inserire numero di giri') # use this if from computer so you don't have to use raspberry function
t_fine = time.time()+temp_mis
print(t_fine)
return giri"""
GPIO.setmode(GPIO.BOARD) #input from raspberry of the rotations
GPIO.setup(32,GPIO.IN)

#set up a counter
giri = 0

#set up a variable for reed activation
reed_state = 0
print("Misurazione in corso...")
t_fine = time.time()+temp_mis
#while loop until t_fine
while time.time()<t_fine:
#check if reed newly activated(the hydrometric reel works like an on and off circuit)
if GPIO.input(32) == 1 and reed_state == 0:
#turn on LED. Set reed_state to 1. Add to counter .
reed_state = 1
giri = giri + 1
#pause to debounce
time.sleep(.01)
#check if reed released
if GPIO.input(32) == 0 and reed_state == 1:
# set reed_state to 0
reed_state = 0

#now that loop has finished, print the final count
return giri
def funz(self): #function to start the measure of speed
c=calcoli()
m=misure()
v=c.velocita(m.mulinello(),c.conta_giri(m.temp_mis()))
v=round(v,4)
l=[m.dist_fond(),v]
app.setLabel("e5",v)
app.hideButton("Inizia misura")
file1=''
def inserisci_mis(self): #insert measure into csv file
global file1,mis_0,l
m=misure()
myFile = open(m.nome_file(),'a')
with myFile:
writer = csv.writer(myFile,lineterminator='\n')
if file1!=m.nome_file():
primaLinea = ["Distanza dalla verticale", "Distanza dalla riva", "Profondità"]+["Dist dal Fondo","Velocità"]*5
writer.writerow(primaLinea)
file1=m.nome_file()
mis_0=float(m.dist_riv())
prof=float(app.getEntry("e4"))
v=app.getLabel("e5")
l.append(prof)
l.append(v)
writer.writerow([m.verticale(),(m.verticale()-mis_0),m.prof_tot()]+l)
l=[]
app=gui() #appJar gui
app.setTitle("Water app")
app.setFont(size=12, family="Calibri")

app.setEntryDefault("e1", "Nome stazione")
app.setEntryDefault("e2", "Verticale n°")
app.setEntryDefault("e3", "Profondità totale")
app.setEntryDefault("e4", "Distanza dal fondo")

app.setLabelFont(size=13,weight="bold")
app.setEntryWidths(["e1","e2","e3","e4"], 20)
app.setEntryRelief("e1", "raised")
app.setEntryRelief("e2", "raised")
app.setEntryRelief("e3", "raised")
app.setEntryRelief("e4", "raised")

app.go()


Function recalled when you press the letters and numbers buttons:

def press(Button): #function to write into entries with buttons of the program
if Button=="A":
entry=''
focus=app.getFocus()
entry=app.getEntry(focus)
entry=entry+"A"
app.setEntry(focus,entry)
elif Button=="B":
focus=app.getFocus()
entry=app.getEntry(focus)
entry=entry+"B"
app.setEntry(focus,entry)
elif Button=="C":
focus=app.getFocus()
entry=app.getEntry(focus)
entry=entry+"C"
app.setEntry(focus,entry)
elif Button=="D":
focus=app.getFocus()
entry=app.getEntry(focus)
entry=entry+"D"
app.setEntry(focus,entry)
elif Button=="E":
focus=app.getFocus()
entry=app.getEntry(focus)
entry=entry+"E"
app.setEntry(focus,entry)
elif Button=="F":
focus=app.getFocus()
entry=app.getEntry(focus)
entry=entry+"F"
app.setEntry(focus,entry)
elif Button=="G":
focus=app.getFocus()
entry=app.getEntry(focus)
entry=entry+"G"
app.setEntry(focus,entry)
elif Button=="H":
focus=app.getFocus()
entry=app.getEntry(focus)
entry=entry+"H"
app.setEntry(focus,entry)
elif Button=="I":
focus=app.getFocus()
entry=app.getEntry(focus)
entry=entry+"I"
app.setEntry(focus,entry)
elif Button=="L":
focus=app.getFocus()
entry=app.getEntry(focus)
entry=entry+"L"
app.setEntry(focus,entry)
elif Button=="M":
focus=app.getFocus()
entry=app.getEntry(focus)
entry=entry+"M"
app.setEntry(focus,entry)
elif Button=="N":
focus=app.getFocus()
entry=app.getEntry(focus)
entry=entry+"N"
app.setEntry(focus,entry)
elif Button=="O":
focus=app.getFocus()
entry=app.getEntry(focus)
entry=entry+"O"
app.setEntry(focus,entry)
elif Button=="P":
focus=app.getFocus()
entry=app.getEntry(focus)
entry=entry+"P"
app.setEntry(focus,entry)
elif Button=="Q":
focus=app.getFocus()
entry=app.getEntry(focus)
entry=entry+"Q"
app.setEntry(focus,entry)
elif Button=="R":
focus=app.getFocus()
entry=app.getEntry(focus)
entry=entry+"R"
app.setEntry(focus,entry)
elif Button=="S":
focus=app.getFocus()
entry=app.getEntry(focus)
entry=entry+"S"
app.setEntry(focus,entry)
elif Button=="T":
focus=app.getFocus()
entry=app.getEntry(focus)
entry=entry+"T"
app.setEntry(focus,entry)
elif Button=="U":
focus=app.getFocus()
entry=app.getEntry(focus)
entry=entry+"U"
app.setEntry(focus,entry)
elif Button=="V":
focus=app.getFocus()
entry=app.getEntry(focus)
entry=entry+"V"
app.setEntry(focus,entry)
elif Button=="Z":
focus=app.getFocus()
entry=app.getEntry(focus)
entry=entry+"Z"
app.setEntry(focus,entry)
elif Button=="0":
focus=app.getFocus()
entry=app.getEntry(focus)
entry=entry+"0"
app.setEntry(focus,entry)
elif Button=="1":
focus=app.getFocus()
entry=app.getEntry(focus)
entry=entry+"1"
app.setEntry(focus,entry)
elif Button=="2":
focus=app.getFocus()
entry=app.getEntry(focus)
entry=entry+"2"
app.setEntry(focus,entry)
elif Button=="3":
focus=app.getFocus()
entry=app.getEntry(focus)
entry=entry+"3"
app.setEntry(focus,entry)
elif Button=="4":
focus=app.getFocus()
entry=app.getEntry(focus)
entry=entry+"4"
app.setEntry(focus,entry)
elif Button=="5":
focus=app.getFocus()
entry=app.getEntry(focus)
entry=entry+"5"
app.setEntry(focus,entry)
elif Button=="6":
focus=app.getFocus()
entry=app.getEntry(focus)
entry=entry+"6"
app.setEntry(focus,entry)
elif Button=="7":
focus=app.getFocus()
entry=app.getEntry(focus)
entry=entry+"7"
app.setEntry(focus,entry)
elif Button=="8":
focus=app.getFocus()
entry=app.getEntry(focus)
entry=entry+"8"
app.setEntry(focus,entry)
elif Button=="9":
focus=app.getFocus()
entry=app.getEntry(focus)
entry=entry+"9"
app.setEntry(focus,entry)
elif Button==".":
focus=app.getFocus()
entry=app.getEntry(focus)
entry=entry+"."
app.setEntry(focus,entry)


This is my program. I modified appJar.py into the appJar directory module to not have the focus on the buttons (lines 488-489-490 are all commented):

#self.topLevel.bind('<Button-1>', lambda e: _setFocus(e))
#self.topLevel.bind('<Button-2>', lambda e: _setFocus(e))
#self.topLevel.bind('<Button-3>', lambda e: _setFocus(e))


I wanted to ask if there is a more efficient way to do a keyboard and numeric pad, because I think that there is a better way to do it. Or even something that I could change in my program to be more efficient.

Python has an official style guide, PEP8. It won't hurt getting familiar with it, since it helps keeping your code readable, consistent and ready for others to mess with.

Combining Italian and English gets confusing fast. It's also unhelpful for those of us that don't read Italian. There's also a distinct lack of whitespace between blocks of code and one-letter variable names are not helpful.

Your class uses a global l where l=[]. I don't like globals, especially in a class. Consider the following:

class misure:
def __init__(self):
self.l = []
def nome_file(self):

my_misure = misure()
print(my_misure.l)


And all of a sudden you can have 20 instances of misure because they all have their own list. A class should hold it's own data as much as possible.

The following can be improved a lot:

def press(Button): #function to write into entries with buttons of the program
if Button=="A":
entry=''
focus=app.getFocus()
entry=app.getEntry(focus)
entry=entry+"A"
app.setEntry(focus,entry)
elif Button=="B":
focus=app.getFocus()
entry=app.getEntry(focus)
entry=entry+"B"
app.setEntry(focus,entry)
elif Button=="C":
focus=app.getFocus()
entry=app.getEntry(focus)
entry=entry+"C"
app.setEntry(focus,entry)


If that entry should do what you want it to do, create it before the first if. But since you overwrite it anyway, why not toss it? Which leaves the following:

    focus=app.getFocus()
entry=app.getEntry(focus)
entry=entry+"character"
app.setEntry(focus,entry)


That's what all those blocks look like, right? So why not put it in a function?

def we_put_it_in_a_function(character):
focus=app.getFocus()
entry=app.getEntry(focus)
entry=entry+"character"
app.setEntry(focus,entry)


All of a sudden, your massive if block looks like this:

def press(Button): #function to write into entries with buttons of the program
if Button=="A":
we_put_it_in_a_function("A"):
elif Button=="B":
we_put_it_in_a_function("B"):
elif Button=="C":
we_put_it_in_a_function("C"):
elif Button=="D":
we_put_it_in_a_function("D"):
elif Button=="E":
we_put_it_in_a_function("E"):
elif Button=="F":
we_put_it_in_a_function("F"):


And here comes the real kicker, it can be done even shorter:

def press(Button): #function to write into entries with buttons of the program
we_put_it_in_a_function(Button):

• we_put_it_in_a_function needs to validate that the value of Button is allowed. Put all the allowed values of Button in a set and check that it exists in the set before doing stuff with it. – Simon Forsberg Apr 8 '18 at 11:14
• @SimonForsberg Definitely. But the current code didn't appear to do any of that either although I wasn't sure, with half of it in Italian. Perhaps the app already handles invalid input. Validation could be a whole review by itself. – Mast Apr 8 '18 at 12:14
• I need to revise my python knolwedge XD. Could you explain me in simple words what self means? Cause I looked up in various part of the internet an I couldn't understand. Anyway I will upload the code all in english, so that you can understand. – Lorenz Bonat Apr 8 '18 at 12:17
• @Mast The problem of having the list as into the _init_ is that every time I call that class it removes the values that are into it. What I need is a list where I append different values from different funcrions, so I think that is better to use global – Lorenz Bonat Apr 8 '18 at 12:35
• @LorenzBonat If you decide to upload new (translated) code, do so in a new question (linking back to this one). I think your problems with init are due to how you're calling your code, but I can't be certain without seeing how you do it. Don't create a new class on every action. If that's what you're doing, you might need to restructure a couple of things. Honestly a good explanation of what your code does (and more importantly, why) would go a long way in helping you clear things up. – Mast Apr 8 '18 at 12:48