how to save user input string in init() - python-3.x

I don't understand how to save the input string and then for in init() to later use it in another function
Class Person:
def __init__ (self):
....
def cCount (self):
num_A = self.count('A')
return num_A
import sys
def main():
inX = input('sequence?')
while inX
myY = Person(inX)
myCnumber = myY.cCount()
print (" {0}".format(myCnumber))
...
I want the output to be the count the number of As in the user input string

You can rearrange your code a little bit like this to achieve what you want:
class Person:
def __init__ (self, sequence):
self.sequence = sequence
def cCount (self):
return self.sequence.count('A')
import sys
def main():
inX = input('sequence?')
while inX:
myY = Person(inX)
myCnumber = myY.cCount()
print (" {0}".format(myCnumber))
inX = input('sequence?')
main()
Result
sequence?ABCDEF
1
sequence?XAAAEWF
3
sequence?
Changes made
Class was replaced with class - lowercase
Init definition added with sequence parameter
Inside init added self.sequence and initialized it
In def cCount, changed to self.sequence.count('A') and returned it
Indented def main's body
Added colon after inX
added inX = input.. at the bottom of while so that while can continue until you just hit Enter

Related

Duplicate a string in Tkinter when redirecting output to a text field

I redirect all my output to the program text field in Tkinter and I wanted to add a date and time to the message:
class StdRedirector(object):
def __init__(self, text_field):
self.text_field = text_field
def write(self, string):
msg_time = datetime.now().strftime('%m-%d %H:%M:%S')
self.text_field.configure(state='normal')
self.text_field.insert('end', f'{msg_time} >> {string}')
self.text_field.see('end')
self.text_field.configure(state='disabled')
class App:
def __init__(self):
self.builder = pygubu.Builder()
self.__init_ui()
self.__init_callbacks()
self.mainwindow.mainloop()
def __init_ui(self):
self.builder.add_from_file(path.join(base_dir, 'assets', 'app.ui'))
self.mainwindow = self.builder.get_object('mainwindow')
self.output_text_field = self.builder.get_object('output_text_field')
sys.stdout = StdRedirector(self.output_text_field)
sys.stderr = StdRedirector(self.output_text_field)
def __init_callbacks(self):
callbacks = {
'update_balance_function': self.__update_balance
}
self.builder.connect_callbacks(callbacks)
def __update_balance(self):
print(True)
But the date line I added is duplicated:
As I understand it, the line is separated by the line separator \n and each substring is sent separately, including line break. Can I fix it somehow?
You can simply check whether the string argument in write() contains any meaningful content, e.g. using ìf string.strip():
class StdRedirector(object):
def __init__(self, text_field):
self.text_field = text_field
def write(self, string):
self.text_field.configure(state='normal')
if string.strip(): # add date before message
msg_time = datetime.now().strftime('%m-%d %H:%M:%S')
self.text_field.insert('end', f'{msg_time} >> {string}')
else: # simply insert string
self.text_field.insert('end', string)
self.text_field.see('end')
self.text_field.configure(state='disabled')

Getting "NameError: name 'self' is not defined" while executing the following program

class inputoutstring(object):
def __init__(self):
self.s = ""
class getstring(self):
self.s = input("Enter the string for printing")
class printstring(self):
print(self.s.upper())
str_obj = inputoutstring()
str_obj.getstring()
str_obj.printstring()
You are defining class instead of function, replace the second, third and last "class" by "def" and indent the code. I think you will be set !
Like the following code:
class inputoutstring(object):
def __init__(self):
self.s = ""
def getstring(self):
self.s = input("Enter the string for printing")
def printstring(self):
print(self.s.upper())
str_obj = inputoutstring()
str_obj.getstring()
str_obj.printstring()
The class class getstring(self): cant be invoked like str_obj.getstring() because it refers to a function call.I think you misplaced the functions with class.
You only need to define the getstring() printstring() as functions and include them in the scope of inputoutstring class such as below:
class inputoutstring(object):
def __init__(self):
self.s = ""
def getstring(self):
self.s = input("Enter the string for printing: ")
def printstring(self):
print(self.s.upper())
str_obj = inputoutstring()
str_obj.getstring()
str_obj.printstring()
output:
Enter the string for printing hello
HELLO
Hope this helps!

Can we skip explicit object creation in Python

When I do not crate object for CP class, the operations are not captured. I am referring to the code below, Can somebody help me understand why we need obj creation in this case
from abc import ABC, abstractmethod
class P(ABC):
def __init__(self):
super().__init__()
self._pre_map = {}
self._pre_order = []
def set_pre(self, tag_value):
index = len(self._pre_map)
print(index)
self._pre_map[index] = tag_value
self._pre_order.append(index)
def execute(self):
pass
class CP(P):
def __init__(self):
super().__init__()
def execute(self):
self.prnt()
def prnt(self):
print (self._pre_map)
print (self._pre_order)
#Working
print("\n++++++++ working")
obj = CP()
obj.set_pre("test string added")
obj.execute()
#Not Working
print("\n+++++++ not working")
CP().set_pre("test string added")
CP().execute()
It produces,
++++++++working
0
{0: 'test string added'}
[0]
+++++++not working
0
{}
[]
When you call the class the second time with CP.execute(), you have created a completely new instance of the CP class. It is not going to have the text string you specified.
If you actually wanted it to print the values like the working one you can make the functions return self after each call in the P class. If you did that you could do something like this.
from abc import ABC, abstractmethod
class P(ABC):
def __init__(self):
super().__init__()
self._pre_map = {}
self._pre_order = []
def set_pre(self, tag_value):
index = len(self._pre_map)
print(index)
self._pre_map[index] = tag_value
self._pre_order.append(index)
##need to return self here
return self
def execute(self):
pass
class CP(P):
def __init__(self):
super().__init__()
def execute(self):
self.prnt()
def prnt(self):
print (self._pre_map)
print (self._pre_order)
#Working
print("\n++++++++ working")
obj = CP()
obj.set_pre("test string added")
obj.execute()
#Not Working
print("\n+++++++ not working: but now working after returning self in the P class")
CP().set_pre("test string added").execute()
++++++++ working
0
{0: 'test string added'}
[0]
+++++++ not working: but now working after returning self in the P class
0
{0: 'test string added'}
[0]
This would print the result you want.
The reason for the difference is the fact that in the first one, you are creating an instance, and using that instance the whole way through, whereas in the second one, you are using two different instances of your class.
The two different instances cannot share their attributes, so you are unable to recall what happened. If you really don't want to use a dedicated variable, change your P class to look like this:
class P(ABC):
...
def set_pre(self, tag_value):
index = len(self._pre_map)
print(index)
self._pre_map[index] = tag_value
self._pre_order.append(index)
return self
...
And use CP().set_pre("test string added").execute()

Python Multithreading Producer Consumer Pattern

I'm still learning how to code and these are my first attempts at multithreading.
I've read a bunch of multithreading articles. I thought these were very helpful:
Processing single file from multiple processes
Python module of the week: multiprocessing
Producer-consumer problem in Python
Multiprocessing
There's quite a lot to think about. Especially for a beginner.
Unfortunately, when I try to put this information into practice my code isn't quite working.
The idea behind this code is to read simplified.txt which contains lines of comma delimited numbers. Eg: 0.275,0.28,0.275,0.275,36078.
The producer thread reads each line and strips the newline character from the end of the line. Then each number in the line is split and assigned a variable.
Variable1 is then placed into the queue.
The consumer thread will pick up items in the queue, square it, then add an entry into the log file.
The code I am using comes from this template. This is the code I have so far:
import threading
import queue
import time
import logging
import random
import sys
read_file = 'C:/temp/temp1/simplified.txt'
log1 = open('C:/temp/temp1/simplified_log1.txt', "a+")
logging.basicConfig(level=logging.DEBUG, format='(%(threadName)-9s) %(message)s',)
BUF_SIZE = 10
q = queue.Queue(BUF_SIZE)
class ProducerThread(threading.Thread):
def __init__(self, name, read_file):
super(ProducerThread,self).__init__()
self.name = name
self.read_file = read_file
def run(self, read_file):
while True:
if not q.full():
with open(read_file, 'r') as f:
for line in f:
stripped = line.strip('\n\r')
value1,value2,value3,value4,value5,value6,value7 = stripped.split(',')
q.put(value1)
logging.debug('Putting ' + str(value1) + ' : ' + str(q.qsize()) + ' items in queue')
time.sleep(random.random())
return
class ConsumerThread(threading.Thread):
def __init__(self, name, value1, log1):
super(ConsumerThread,self).__init__()
self.name = name
self.value1 = value1
self.log1 = log1
return
def run(self):
while True:
if not q.empty():
value1 = q.get()
sqr_value1 = value1 * value1
log1.write("The square of " + str(value1) + " is " + str(sqr_value1))
logging.debug('Getting ' + str(value1) + ' : ' + str(q.qsize()) + ' items in queue')
time.sleep(random.random())
return
if __name__ == '__main__':
p = ProducerThread(name='producer')
c = ConsumerThread(name='consumer')
p.start()
time.sleep(2)
c.start()
time.sleep(2)
When I run the code, I get this error:
Traceback (most recent call last):
File "c:/Scripta/A_Simplified_Producer_Consumer_Queue_v0.1.py", line 60, in <module>
p = ProducerThread(name='producer')
TypeError: __init__() missing 1 required positional argument: 'read_file'
I don't know where else I need to add read_file.
Any help would be greatly appreciated. Thanks in advance.
Your ProducerThread class requires 2 parameters (name and read_file) as arguments to its constructor as defined in its __init__ method, where you only provide the first such argument when you create an instance in your main block. You have the same problem with your second class.
You should either provide the read_file to the constructors when creating instances or just remove it from the constructor signature since you don't appear to use it anyways (you use the read_file passed into run function, but I don't think that is correct). Seems like you're attempting to override that method from the Thread superclass and I doubt that takes such a parameter.
Thank you userSeventeen for setting me on the right path.
I thought that in order to use outside variables I needed to place them in the init method, then again into the run method. You've clarified that I only needed to use the variables in the run methods.
This is the working code. I had to remove the while true: statement as I did not want the code to run forever.
import threading
import queue
import time
import logging
import random
import sys
import os
read_file = 'C:/temp/temp1/simplified.txt'
log1 = open('C:/temp/temp1/simplified_log1.txt', "a+")
logging.basicConfig(level=logging.DEBUG, format='(%(threadName)-9s) %(message)s',)
BUF_SIZE = 10
q = queue.Queue(BUF_SIZE)
class ProducerThread(threading.Thread):
def __init__(self, name):
super(ProducerThread,self).__init__()
self.name = name
def run(self):
with open(read_file, 'r') as f:
for line in f:
stripped = line.strip('\n\r')
value1,value2,value3,value4,value5 = stripped.split(',')
float_value1 = float(value1)
if not q.full():
q.put(float_value1)
logging.debug('Putting ' + str(float_value1) + ' : ' + str(q.qsize()) + ' items in queue')
time.sleep(random.random())
return
class ConsumerThread(threading.Thread):
def __init__(self, name):
super(ConsumerThread,self).__init__()
self.name = name
return
def run(self):
while not q.empty():
float_value1 = q.get()
sqr_value1 = float_value1 * float_value1
log1.write("The square of " + str(float_value1) + " is " + str(sqr_value1))
logging.debug('Getting ' + str(float_value1) + ' : ' + str(q.qsize()) + ' items in queue')
time.sleep(random.random())
return
if __name__ == '__main__':
p = ProducerThread(name='producer')
c = ConsumerThread(name='consumer')
p.start()
time.sleep(2)
c.start()
time.sleep(2)

integrate tkinter whit Sqlite3

I'm looking for a suggestion: I have a Module called main.py where I write all GUI code.In order to avoid repeating all the sqlite queries, I have written all those queries un other Module called admin.py.
So there is this code in main.py:
B = tk.Entry()
B1= B.get()
In admin.py, I have the method validate.That is supposed take the B variable to make the query.Something like:
//Here the function will query the db to see if the value in B1.get() exist//
class myclass()
def validate(a):
....SELECT FROM table WHERE col_val = (a)
And here is the trouble: I don't know how to pass the value of B1 to the validate method. Could be something like this:
s= myclass()
s.validate(B1)
maybe?
I've done but i think could be better.Here is the way i did. Sorry for question i wasn't in the computer.
There is the module main.py
import tkinter as tk
import ingreso
from tkinter import messagebox
from ingreso import myclass
import sqlite3
def __init__(self):
tk.Tk.__init__(self)
frame = tk.Frame(self,width=380, height=420, bg="white", colormap="new")
self.fi = tk.Entry(frame)
self.fi.pack()
self.dni = tk.Entry(frame)
self.dni.pack()
frame.pack()
self.hi = tk.Button(self,text="guardar", command= self.validate)
self.hi.pack()
def validate(self):
messagebox.showwarning(title="validador",message="Se procedera a validar los campos")
fi= self.fi.get() #That is that i pass as class argument
dni= self.dni.get()
if len(fi)== 0 or len(dni)==0:
tk.messagebox.showwarning(message="campos requeridos")
else:
query = myclass(fi, dni) #Create the objet at instance of class
val = query.validar() #Determine if the object exist or not
There is the module ingreso.py:
class myclass():
def __init__(self, a= " ", b= " "): #There is the attributes of the class
self.db = db
self.a = a
self.b = b
def validar(self): # here i determine if the objet exist or not
fi = self.a
dni = self.b
conn = sqlite3.connect('ecina.db')
c = conn.cursor()
c.execute('''SELECT COUNT(*) FROM admision WHERE fi = (?) AND dni =(?)''', (fi, dni))
r = c.fetchone()
number_of_rows=r[0]
return number_of_rows
It's works but any suggestion or correction will be very appreciate.Thanks Alot.

Resources