Problem with writing to file second time, Python3 - python

I have created a phonebook with tkinker using Python 3.6
When I add persons to phonebook it save it to a file.
When I load the program again it loads the file as it should.
If I add 2 person at first run, all works fine.
Second run, I add one person and it adds an empty line at index 1 and adds the person below as it should.
Third run, I add one person, it adds a new line at index 1 and a person last in the list.
Now I get 2 empty lines.
I can't figure out why it creates an empty space at index 1 . It should not do it.
Here is the code, comments are in Swedish so sorry about it.
How I write to the file is in function lägg_till()
It will auto create kontakter.txt when you run it first time.
"Lägg till" means add in Sweden and "Avsluta" is quit the program.
from tkinter import *
import os.path
root = Tk()
root.geometry("640x640+200+100")
root.title("Telefon listan")
def avsluta():
quit()
def spara():
#Spara kontakter till fil.
name = entry_1.get()
mobil = entry_2.get()
if name == "" or mobil == "" :
pass
else:
with open("kontakter.txt","w") as file:
file.write("\n".join(kontakter.get(0,END)))
def ta_bort():
# Ta bort kontakter,genom att välja index av element och sparar värdet i variabel index.
index = kontakter.curselection()
print(index)
kontakter.delete(index)
def lägg_till():
# Ta inmatade värden från name,mobil och spara i kontakter.
# Använder .get() för att hämta
name = entry_1.get()
mobil = entry_2.get().replace(" ", "") # Använder replace för att rensa whitespace
# Varning när alla värden inte är ifyllda
if name == "" or mobil == "" :
label_error.config(text="Alla fälten är inte ifyllda")
else:
# trycka in dessa i kontakter med .insert() END för slutet av listan, dvs index "kan vara 0,1,2,3"
#Rensar error fältet innan man lägger till kontakten
label_error.config(text="")
kontakter.insert(END,name + " - " + mobil)
# Rensa fältet efter lägg till
entry_1.delete(0,END)
entry_2.delete(0,END)
kontakt = kontakter.get(0,END)
with open("kontakter.txt","w") as file:
file.write("\n".join(kontakt))
def uppdatera():
# Hämta det markerade data
index = kontakter.curselection()
name = entry_1.get()
mobil = entry_2.get()
# Varning när alla värden inte är ifyllda
if name == "" or mobil == "" :
label_error.config(text="Alla fälten är inte ifyllda")
else:
# trycka in dessa i kontakter med .insert() END för slutet av listan, dvs index "kan vara 0,1,2,3"
#Rensar error fältet innan man lägger till kontakten
label_error.config(text="")
# Raderar det ifyllda data
kontakter.delete(index)
#Skriver nytt
kontakter.insert(index,name + "-" + mobil)
entry_1.delete(0,END)
entry_2.delete(0,END)
# Skapar frame
#Namn
fram_1 = Frame(root)
fram_1.pack()
#Mobil
fram_2 = Frame(root)
fram_2.pack()
#Knappar
fram_3 = Frame(root)
fram_3.pack()
# Listbox
fram_4 = Frame(root)
fram_4.pack()
#Skapar label
#Namn
label_1 = Label(fram_1,text="Name:")
label_1.grid(row=0, column=0)
#Mobil
label_2 = Label(fram_2,text="Mobil:")
label_2.grid(row=1,column=0)
# Skapar entry
#namn
entry_1 = Entry(fram_1)
entry_1.grid(row=0,column=1)
#Mobil
entry_2 = Entry(fram_2)
entry_2.grid(row=1,column=2,)
# Kolla om filen finns, annars skapa den, behöver importera os.path
if not os.path.exists("kontakter.txt"):
open('kontakter.txt', 'w').close()
else:
pass
# Läsa från fil
data = []
with open("kontakter.txt" ,"r") as fil:
for line in fil:
data += [line]
# Listbox
kontakter = Listbox(fram_4,height=8,width=40,bg="pink")
kontakter.grid(row=0,column=0)
# Lägger till kontakter , första värdet är index följt av värde,
kontakter.insert(END,)
#Läsa in från fil
for i in range(len(data)):
kontakter.insert(i+0 , data[i])
# Error
label_error = Label(root,text="",fg="red")
label_error.pack()
# Knappar
# knapp Lägg till
button_1 = Button(fram_3,text="Lägg till",command=lägg_till)
button_1.grid(row=0,column=0)
# knapp edit
button_2 = Button(fram_3,text="Uppdatera",command=uppdatera)
button_2.grid(row=0,column=1)
# Knapp delete
button_3 = Button(fram_3,text="Radera",command=ta_bort)
button_3.grid(row=0,column=2)
# Knapp avsluta
button_4 = Button(fram_3,text="Avsluta",command=avsluta)
button_4.grid(row=0,column=3)
button_5 = Button(fram_3,text="Spara",command=spara)
button_5.grid(row=0,column=4)
root.attributes("-topmost", True)
root.mainloop()

Inside lägg_till() when you open the file use ab instead of w:
with open("kontakter.txt","ab") as file:
file.write("\n".join(kontakt))

By adding .strip() , I made workaround, but I think problem is still there.
# Läsa från fil
data = []
with open("kontakter.txt" ,"r") as fil:
for line in fil.readlines():
data += [line.strip()] #.strip() fix the problem
fil.close()

The problem in your program is kontakt = kontakter.get(0,END), which returns your data as follows :
('1 - 1\n', '2 - 2', '3 - 3')
Note that the third entry (3 - 3) is made after the GUI was closed once. By joining together with '\n'.join(), you get an additional space character:
'1 - 1\n\n2 - 2\n3 - 3\n'
I don't know the exact reason why this only happens if you close the program once.
You can avoid this conflict by using 'a' instead of 'w', which simply appends the string in the text file.
with open("kontakter.txt","a") as file:
file.write(name + " - " + mobil + '\n')

Related

How to transform an affirmative sentence into a general question using Python Udapi?

I would like to trasnform some pretty simple affirmative sentences into general questions (the language of choise is Spanish). Consider the following example:
Esto es muy difícil. -> Es esto muy difícil?
So I just need to shift the position of subject and predicate (wherever they are).
Normally it can be done with the shift_before_node() method:
pron_node, aux_node = tree.descendants[0], tree.descendants[1]
aux_node.shift_before_node(pron_node)
However, if I want to automate the process (because subject and predicate will not always be in the same position) I need to create a cycle (See The Problem paragraph below) for each node of a tree, where it checks that if node's part of speech (upos) is a PRON or PROPN, and it is followed (not necessarily directly) by a node which is a VERB or AUX, it needs to shift the second node before the first one (like in the example above). But, I dont know how to implement it into cycle. Any suggestions?
Here is my code so far (done in Google Colab). I apologize for excluding some of the console text, otherwise it would be too lengthy:
Request to UDPipe server
import requests
response = requests.get("http://lindat.mff.cuni.cz/services/udpipe/api/models")
info = response.json()
info
for key, data in info["models"].items():
if "spanish" in key:
print(key, data)
params = {"tokenizer": "", "tagger": "", "parser": "", "model": "spanish-gsd-ud-2.6-200830"}
text = "Esto es muy difícil."
params["data"] = text
response = requests.get("http://lindat.mff.cuni.cz/services/udpipe/api/process", params)
json_response = response.json()
parse = json_response["result"]
print(parse)
Output #1 (print (parse)):
# generator = UDPipe 2, https://lindat.mff.cuni.cz/services/udpipe
# udpipe_model = spanish-gsd-ud-2.6-200830
# udpipe_model_licence = CC BY-NC-SA
# newdoc
# newpar
# sent_id = 1
# text = Esto es muy difícil.
1 Esto este PRON _ Number=Sing|PronType=Dem 4 nsubj _ _
2 es ser AUX _ Mood=Ind|Number=Sing|Person=3|Tense=Pres|VerbForm=Fin 4 cop _ _
3 muy mucho ADV _ _ 4 advmod _ _
4 difícil difícil ADJ _ Number=Sing 0 root _ SpaceAfter=No
5 . . PUNCT _ _ 4 punct _ SpaceAfter=No
Udapi Installation:
!pip install --upgrade git+https://github.com/udapi/udapi-python.git
import os
os.environ['PATH'] += ":" + os.path.join(os.environ['HOME'], ".local/bin")
from udapi.block.read.conllu import Conllu
from udapi.core.document import Document
from udapi.block.write.textmodetrees import TextModeTrees
from io import StringIO
Building a tree:
In my understanding a tree is a variable of a built in Udapi class, which is a structured version of a parse variable, and which contains all the information about each word of a sentence - its order (ord), given form (form), initial form (lemma), part of speech (upos) and so on:
tree = Conllu(filehandle=StringIO(parse)).read_tree()
writer = TextModeTrees(attributes="ord,form,lemma,upos,feats,deprel", layout="align")
writer.process_tree(tree)
Output #2 (writer.process_tree(tree)):
# sent_id = 1
# text = Esto es muy difícil.
─┮
│ ╭─╼ 1 Esto este PRON Number=Sing|PronType=Dem nsubj
│ ┢─╼ 2 es ser AUX Mood=Ind|Number=Sing|Person=3|Tense=Pres|VerbForm=Fin cop
│ ┢─╼ 3 muy mucho ADV _ advmod
╰─┾ 4 difícil difícil ADJ Number=Sing root
╰─╼ 5 . . PUNCT _ punct
It is also possible to print out all the dependents for each node of a given tree. As already correctly noted in the comments, tree.descendants consists of a list of nodes:
for node in tree.descendants:
print(f"{node.ord}:{node.form}")
left_children = node.children(preceding_only=True)
if len(left_children) > 0:
print("Left dependents:", end=" ")
for child in left_children:
print(f"{child.ord}:{child.form}", end=" ")
print("")
right_children = node.children(following_only=True)
if len(right_children) > 0:
print("Right dependents:", end=" ")
for child in right_children:
print(f"{child.ord}:{child.form}", end=" ")
print("")
Output #3:
1:Esto
2:es
3:muy
4:difícil
Left dependents: 1:Esto 2:es 3:muy
Right dependents: 5:.
5:.
The problem (beginning of a cycle):
for node in tree.descendants:
if node.upos == "VERB" or node.upos == "AUX":
UPDATE 1
So, I`ve come to the first somewhat complete version of a needed cycle and now it looks like this:
for i, curr_node in enumerate(nodes[1:], 1):
prev_node = nodes[i-1]
if (prev_node.upos == "PRON" or prev_node.upos == "PROPN") and (curr_node.upos == "VERB" or curr_node.upos == "AUX"):
curr_node.shift_before_node(prev_node)
But now I get this error:
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-11-a967bbd730fe> in <module>()
9
10
---> 11 for i, curr_node in enumerate(nodes[1:], 1):
12 prev_node = nodes[i-1]
13 if (prev_node.upos == "PRON" or prev_node.upos == "PROPN") and (curr_node.upos == "VERB" or curr_node.upos == "AUX"):
NameError: name 'nodes' is not defined
UPDATE 2
I tried defining nodes like that:
nodes = tree.descendants
And now my cycle compiles at least, but it still didn't do anything with the structure of a given sentence:
nodes = tree.descendants
for i, curr_node in enumerate(nodes[1:], 1):
prev_node = nodes[i-1]
if (prev_node.upos == "PRON" or prev_node.upos == "PROPN") and (curr_node.upos == "VERB" or curr_node.upos == "AUX"):
curr_node.shift_before_node(prev_node)
Checking the tree:
tree = Conllu(filehandle=StringIO(parse)).read_tree()
writer = TextModeTrees(attributes="ord,form,lemma,upos,feats,deprel", layout="align")
writer.process_tree(tree)
# sent_id = 1
# text = Esto es muy difícil.
─┮
│ ╭─╼ 1 Esto este PRON Number=Sing|PronType=Dem nsubj
│ ┢─╼ 2 es ser AUX Mood=Ind|Number=Sing|Person=3|Tense=Pres|VerbForm=Fin cop
│ ┢─╼ 3 muy mucho ADV _ advmod
╰─┾ 4 difícil difícil ADJ Number=Sing root
╰─╼ 5 . . PUNCT _
Nothing changed.
UPDATE 3
I've also tried to check if the cycle swaps subject and predicate back again (2nd time), making the sentence look like the original one, but I guess it's not the case, becuase even if I comment the break part, flag has increased by 1 only:
nodes = tree.descendants
flag = 1
for i, curr_node in enumerate(nodes[1:], 1):
prev_node = nodes[i-1]
if ((prev_node.upos == "PRON") or (prev_node.upos == "PROPN")) and ((curr_node.upos == "VERB") or (curr_node.upos == "AUX")):
curr_node.shift_before_node(prev_node)
flag = flag + 1
# if flag == 2:
# break
print(flag)
Output
2
HOWEVER, it means, that the condition if ((prev_node.upos == "PRON") or (prev_node.upos == "PROPN")) and ((curr_node.upos == "VERB") or (curr_node.upos == "AUX")) was satisified.
Suppose there is one sentence per line in affirm.txt with affirmative Spanish sentences such as "Esto es muy difícil." or "Tus padres compraron esa casa de la que me hablaste.".
As an alternative to using the UDPipe web service, we can parse the sentences locally (I slightly prefer the es_ancora model over es_gsd):
import udapi
doc = udapi.Document('affirm.txt')
udapi.create_block('udpipe.Base', model_alias='es_ancora').apply_on_document(doc)
To make repeated experiments faster, we can now store the parsed trees to a CoNLL-U file using doc.store_conllu('affirm.conllu') and later load it using doc = udapi.Document('affirm.conllu').
To draw the trees we can use the doc.draw() method (or even tree.draw()), which is a syntactic sugar that uses TextModeTrees() behind the scenes. So to compare the sentences before and after changing the word order, we can use:
print("Original word order:")
doc.draw() # or doc.draw(attributes="ord,form,lemma,deprel,feats,misc")
for tree in doc.trees:
process_tree(tree)
print("Question-like word order:")
doc.draw()
Now comes the main work - to implement the process_tree() subroutine. Note that
We need to change the word order of the main clause only (e.g "Tus padres compraron esa casa."), not any dependent clauses (e.g. "de la que me hablaste".) So we don't want to iterate over all nodes (tree.descendants), we just need to find the main predicate (usually a verb) and its subject.
The subject does not need to be only PRON and PROPN, it can be NOUN or maybe just ADJ if the governing noun is omitted. So it is safer to just ask for deprel=nsubj (handling csubj is beyond the scope of this question).
I don't speak Spanish, but I think the rule is not as simple as moving the verb before the subject (or moving the subject after the verb). At least, we need to distinguish transitive verbs (with objects) and copula constructions. Of course, even the solution below is not perfect. It is rather an example how to use Udapi.
We should handle the nasty details like capitalization and spacing.
def process_tree(tree):
# Find the main predicate and its subject
main_predicate = tree.children[0]
nsubj = next((n for n in main_predicate.children if n.udeprel == 'nsubj'), None)
if not nsubj:
return
# Move the subject
# - after the auxiliary copula verb if present
# - or after the last object if present
# - or after the main predicate (verb)
cop = next((n for n in main_predicate.children if n.udeprel == 'cop'), None)
if cop:
nsubj.shift_after_subtree(cop)
else:
objects = [n for n in main_predicate.children if n.udeprel in ('obj', 'iobj')]
if objects:
nsubj.shift_after_subtree(objects[-1])
else:
nsubj.shift_after_node(verb)
# Fix the capitalization
nsubj_start = nsubj.descendants(add_self=True)[0]
if nsubj_start.lemma[0].islower() and nsubj_start.form[0].isupper():
nsubj_start.form = nsubj_start.form.lower()
tree.descendants[0].form = tree.descendants[0].form.capitalize()
# Add a question mark (instead of fullstop)
dots = [n for n in main_predicate.children if n.form == '.']
if not dots:
dots = [main_predicate.create_child(upos="PUNCT", deprel="punct")]
dots[-1].form = '?'
# Fix spacing
dots[-1].prev_node.misc["SpaceAfter"] = "No"
nsubj_start.prev_node.misc["SpaceAfter"] = ""
# Recompute the string representation of the sentence
tree.text = tree.compute_text()
The solution above uses Udapi as a library. An alternative would be to move the main code into a Udapi block called e.g. MakeQuestions:
from udapi.core.block import Block
class MakeQuestions(Block):
def process_tree(self, tree):
# the rest is same as in the solution above
If we store this block in the current directory in file makequestions.py, we can call it from the command line in many ways:
# parse the affirmative sentences
cat affirm.txt | udapy -s \
read.Sentences \
udpipe.Base model_alias=es_ancora \
> affirm.conllu
# visualize the output with TextModeTrees (-T)
cat affirm.conllu | udapy -T .MakeQuestions | less -R
# store the output in CoNLL-U
udapy -s .MakeQuestions < affirm.conllu > questions.conllu
# show just the plain-text sentences
udapy write.Sentences < questions.conllu > questions.txt
# visualize the differences in HTML
udapy -H \
read.Conllu files=affirm.conllu zone=affirm \
read.Conllu files=questions.conllu zone=questions \
util.MarkDiff gold_zone=affirm attributes=form ignore_parent=1 \
> differences.html

Python - Append input to .txt but deletes prior data

I´m trying to append input to a .txt and succeed to do so, however the data previously present in my .txt file gets overwritten by the data inputted. I wish for the data to stay with the input added.
Heres my code so far:
def tilføjMedlem():
while True:
tilføjFornavn = input("Skriv fornavn på det medlem du ønsker at tilføje: (Tast q for at afslutte)")
if tilføjFornavn == 'q':
break
else:
tilføjEfternavn= input("Efternavn:")
tilføjJollypoints= input("Jollypoints:")
tilføjInstagram = input("Instagram:")
tilføjMedlemSiden = input('Medlem siden:')
with open('fans.txt', 'a') as text_file:
text_file.write(tilføjFornavn+" "+tilføjEfternavn+" "+tilføjJollypoints+" "+tilføjInstagram+" "+tilføjMedlemSiden)
tilføjMedlem()
You need to fix the indentation of the with open() function.
Your code is re-assigning the values to variables you have declared. It will call write to file function only once with the last values entered in the variables after user had entered q to quit.
def tilføjMedlem():
while True:
tilføjFornavn = input("Skriv fornavn på det medlem du ønsker at tilføje: (Tast q for at afslutte)")
if tilføjFornavn == 'q':
break
else:
tilføjEfternavn= input("Efternavn:")
tilføjJollypoints= input("Jollypoints:")
tilføjInstagram = input("Instagram:")
tilføjMedlemSiden = input('Medlem siden:')
with open('fans.txt', 'a') as text_file:
text_file.write(tilføjFornavn+" "+tilføjEfternavn+" "+tilføjJollypoints+" "+tilføjInstagram+" "+tilføjMedlemSiden)
tilføjMedlem()
The code work
Actually, the code append the text correctly to the .txt file. But it overwrite the previous input you may enter in the while loop.
If the input getter behave like intended, then there is no issues with your code. It get the 4 last inputs you enter, then append them in the file without overwriting it:
however the data previously present in my .txt file gets overwritten by the data inputted
This is false. Your code works.
Here is what I executed:
def tilføjMedlem():
while True:
tilføjFornavn = input("Skriv fornavn på det medlem du ønsker at tilføje: (Tast q for at afslutte)")
if tilføjFornavn == 'q':
break
else:
tilføjEfternavn= input("Efternavn:")
tilføjJollypoints= input("Jollypoints:")
tilføjInstagram = input("Instagram:")
tilføjMedlemSiden = input('Medlem siden:')
with open('fans.txt', 'a') as text_file:
text_file.write(tilføjFornavn+" "+tilføjEfternavn+" "+tilføjJollypoints+" "+tilføjInstagram+" "+tilføjMedlemSiden)
tilføjMedlem()
Original file:
This is the original data
Script execution:
Skriv fornavn på det medlem du ønsker at tilføje: (Tast q for at afslutte)
>>>? n
Efternavn:
>>>? First input
Jollypoints:
>>>? second input
Instagram:
>>>? third input
Medlem siden:
>>>? and this is the last one.
Skriv fornavn på det medlem du ønsker at tilføje: (Tast q for at afslutte)
>>>? q
Final file:
This is the original data
q First input second input third input and
this is the last one.
If the intended behavior is that EVERY inputs append to the file, you have to change the indent of the with block:
def tilføjMedlem():
while True:
tilføjFornavn = input("Skriv fornavn på det medlem du ønsker at tilføje: (Tast q for at afslutte)")
if tilføjFornavn == 'q':
break
else:
tilføjEfternavn= input("Efternavn:")
tilføjJollypoints= input("Jollypoints:")
tilføjInstagram = input("Instagram:")
tilføjMedlemSiden = input('Medlem siden:')
with open('fans.txt', 'a') as text_file:
text_file.write(tilføjFornavn+" "+tilføjEfternavn+" "+tilføjJollypoints+" "+tilføjInstagram+" "+tilføjMedlemSiden)
tilføjMedlem()

Cant get my functions (Munt2 and Munt1) to subtract my global variable (aantal_munten)

I have a problem with my code (trying to make the NIM game with a Tkinter GUI). Anyhow i cant get my functions (Munt1, Munt2) to subtract to my global (aantal_munten). And i dont know how to fix it. Can someone point me in the right direction? Also the TKinter gui is still a bit new for me so if you have any tips or tricks for me they are well appreciated!
import tkinter
import random
def toonStartscherm():
keuzescherm.pack_forget()
spelerscherm.pack_forget()
startscherm.pack()
def toonKeuzescherm():
keuzescherm.pack()
startscherm.pack_forget()
spelerscherm.pack_forget()
def spelOptie1():
keuzescherm.pack_forget()
startscherm.pack_forget()
spelerscherm.pack()
def randomSpeler():
beginnende_speler = random.choice(['1', '2'])
speler = beginnende_speler
if speler == '1':
speler = '2'
else:
speler = '1'
return str(speler)
def Munt1():
eenMunt = 1
aantal_munten -= eenMunt
def Munt2():
tweeMunt = 2
aantal_munten -= tweeMunt
nim_spel = tkinter.Tk()
global aantal_munten
aantal_munten = 7
startscherm = tkinter.Frame(master=nim_spel)
startscherm.pack()
start_welkom = tkinter.Label(startscherm, text= 'Welkom bij het NIM spel! \nHieronder volgende de spelregels.')
start_welkom.pack()
start_uitleg = tkinter.Label(startscherm, text= 'Het spel NIM start met 7 munten, elke speler mag één of twee munten pakken. \n De speler die de laatste munt pakt verliest!')
start_uitleg.pack() # zet uitleg automatisch in venster
doorgaan_knop = tkinter.Button(startscherm, text = 'Ik snap de regels!', fg = 'green', command = toonKeuzescherm) # maakt knop en laat stoppen
doorgaan_knop.pack(side = 'bottom')
keuzescherm = tkinter.Frame(master=nim_spel)
keuzescherm.pack()
keuze_opties = tkinter.Label(keuzescherm, text='Het NIM spel kan op twee manieren gespeeld worden. \n Optie 1: Tegen elkaar \n Optie 2: Tegen de computer')
keuze_opties.pack() # zet opties automatisch in venster
keuze_vraag = tkinter.Label(keuzescherm, text='Voor welke optie kies je?')
keuze_vraag.pack()
optie_1 = tkinter.Button(keuzescherm, text = 'Optie 1', fg = 'green', command = spelOptie1) # maakt knop en laat stoppen
optie_1.pack(side = 'left')
optie_2 = tkinter.Button(keuzescherm, text = 'Optie 2', fg = 'red', command = keuzescherm.quit) # maakt knop en laat stoppen
optie_2.pack(side = 'right')
spelerscherm = tkinter.Frame(master=nim_spel)
spelerscherm.pack()
beurt_speler = tkinter.Label(spelerscherm, text='Speler ' + (randomSpeler()) + ' is aan de beurt!')
beurt_speler.pack()
munten_over = tkinter.Label(spelerscherm, text='Er zijn nog ' + (str(aantal_munten)) + ' aantal munten over, hoeveel pak je er?')
munten_over.pack()
pak_1_munt = tkinter.Button(spelerscherm, text = '1 munt', fg = 'blue', command = Munt1)
pak_1_munt.pack(side = 'left')
pak_2_munt = tkinter.Button(spelerscherm, text = '2 munten', fg = 'blue', command = Munt2)
pak_2_munt.pack(side = 'right')
toonStartscherm()
nim_spel.mainloop()
def Munt1():
global aantal_munten
eenMunt = 1
aantal_munten -= eenMunt
def Munt2():
global aantal_munten
tweeMunt = 2
aantal_munten -= tweeMunt
I just added the global aantal_munten line and checked it, and it's working perfectly now.

Printing the results of a function into a tkinter message box?

I've been coding for years and I have always been able to find an answer on google, until now. I cannot manage to make this work in any way.
Before this I have several lists of different countries, and a dozen or so functions that just print stuff for the user, it is not relevant here.
I use tkinter to create an input box where a user can type a country (input gets assigned to typedCountry). I then search for the country in each and every list in the mainProgram() function, and every time I find a list that matches I return another function. Everything works marvelously as it should, except I want mainProgram() to return the information to a tkinter GUI box and not the terminal. I've been fighting with it for hours and I cannot find a way to make it work, I am willing to take any advice, even changing the code significantly or using something other than tkinter would work just fine.
def mainProgram():
typedCountry = e.get()
Country = typedCountry.lower()
print 'Your country is: ' + typedCountry + '\n'
if Country in bannedCountries:
banned(typedCountry)
if Country in cpBannedCountries:
cpBanned(typedCountry)
if Country in skrillBannedCountries:
skrillBanned(typedCountry)
if Country in bacsCountries:
Bacs(typedCountry)
if Country in sepaCountries:
sepa(typedCountry)
if Country in eftCountries:
eft(typedCountry)
if Country in ltdCountries:
ltd(typedCountry)
if Country in marketsCountries:
markets(typedCountry)
master = Tk()
e = Entry(master)
e.pack()
e.focus_set()
var = mainProgram()
def textBox():
root = Tk()
label = Message(root, textvariable=var)
label.pack()
root.mainloop()
b = Button(master, text = "Search", command = mainProgram)
b.pack()
mainloop()
And here is the main code if you want it (if you want to run this in your end for example):
from tkinter import *
import tkMessageBox
bannedCountries = ['afghanistan','american samoa','belarus','brazil','burundi',
'central african republic','congo','cook islands','cote d\'ivoire',
'crimea','cuba','guam','iran','japan','liberia','libya','myanmar',
'new zealand','north korea','northern mariana islands','puerto rico',
'russia','singapore','somalia','south korea','sudan','syria','tokelau',
'turkey','ukraine','united states','vanuatu','virgin islands',
'western sahara','zimbabwe']
cpBannedCountries = ['belarus','bosnia and herzegovina','burundi','cote d\'ivoire',
'cuba','iran','iraq','kosovo','lebanon','liberia','macedonia','montenegro','myanmar',
'nigeria','north korea','saint helena','somalia','sudan']
skrillBannedCountries = ['angola','barbados','benin','burkina faso','cape verde',
'comoros','djibouti','faroe islands','gambia','greenland','grenada','guyana','laos',
'liechtenstein','macao','martinique','mongolia','namibia','niger','palau','samoa',
'suriname','tajikistan','togo','trinidad and tobago','turkmenistan']
bacsCountries = ["united kingdom"]
eftCountries = ['australia']
sepaCountries = ['austria','belgium','bulgaria','cyprus','czech republic','check',
'denmark','estonia','finland','france','germany','greece','hungary','iceland',
'ireland','italy','latvia','liechtenstein','lithuania','luxembourg','malta',
'martinique','mayotte','monaco','netherlands','norway','poland','portugal',
'romania','slovakia','slovenia','spain','sweden','switzerland','united kingdom']
ltdCountries = ['austria','belgium','bulgaria','croatia','cyprus','czech republic',
'denmark','estonia','finland','france','germany','greece','hungary','ireland',
'italy','latvia','lithuania','luxembourg','malta','netherlands','poland','portugal',
'romania','slovakia','slovenia','spain','united kingdom']
marketsCountries = ['albania','algeria','andorra','angola','anguilla','armenia',
'aruba','bahamas','bangladesh','barbados','belize','benin','bermuda','bhutan',
'bonaire','bosnia','herzegovina','bosnia and herzegovina','botswana','brunei',
'burkina faso','burma','cambodia','cameroon','cape verde','cayman islands',
'chad','comoros','djibouti','equatorial guinea','eritrea','ethiopia','falkland islands (malvinas)',
'faroe islands','gabon','gambia','ghana','greenland','grenada','guinea','guinea-bissau',
'guyana','haiti','iceland','india','jamaica','jordan','kazakhstan','kenya',
'kiribati','kosovo','kyrgyzstan','laos','lesotho','liechtenstein','macao',
'macedonia','madagascar','malawi','malaysia','maldives','mali','marshall islands',
'mauritania','mauritius','micronesia','mongolia','morocco','mozambique','namibia',
'nauru','nepal','niger','nigeria','norway','pakistan','palau','papua new guinea',
'philippines','rwanda','saint helena','saint kitts and nevis','saint lucia','saint vincent and the grenadines',
'samoa','sao tome and principe','senegal','serbia','seychelles','sierra leone',
'solomon islands','sri lanka','suriname','swaziland','tajikistan','tanzania','togo',
'tonga','trinidad and tobago','tunisia','turkmenistan','turks and caicos islands','tuvalu',
'uganda','uzbekistan','yemen','zambia']
def banned(x):
if 'kingdom' not in x:
return 'Clients from %s are not able to open an account with FXCM' % x
else:
return
def cpBanned(x):
return "FXCM does not accept cards issued in %s" % x
def skrillBanned(x):
return "Clients from %s cannot use Skrill" % x
def Bacs(x):
return """Clients from %s can use BACS if their bank account is located in
%s and both their bank account and their FXCM account is in GBP""" % (x, x)
def sepa(x):
return """Clients from %s can use SEPA if their bank account is located either in
%s or in another European country, and both their bank account and their FXCM account is in EUR""" % (x, x)
def eft(x):
return """Clients from %s can use EFT if their bank account is located in
%s, and both their bank account and their FXCM account is in AUD""" % (x, x)
print "Clients from %s must open with FXCM AU" % x
def ltd(x):
return "Clients from %s must open with FXCM LTD" % x
def markets(x):
return "Clients from %s must open with FXCM Markets" % x
def mainProgram():
typedCountry = e.get() # This is the text you may want to use later
Country = typedCountry.lower()
print 'Your country is: ' + typedCountry + '\n'
if Country in bannedCountries:
banned(typedCountry)
if Country in cpBannedCountries:
cpBanned(typedCountry)
if Country in skrillBannedCountries:
skrillBanned(typedCountry)
if Country in bacsCountries:
Bacs(typedCountry)
if Country in sepaCountries:
sepa(typedCountry)
if Country in eftCountries:
eft(typedCountry)
if Country in ltdCountries:
ltd(typedCountry)
if Country in marketsCountries:
markets(typedCountry)
master = Tk()
e = Entry(master)
e.pack()
e.focus_set()
var = mainProgram()
def textBox():
root = Tk()
label = Message(root, textvariable=var)
label.pack()
root.mainloop()
b = Button(master, text = "Search", command = mainProgram)
b.pack()
mainloop()
Just replace for example:
return "FXCM does not accept cards issued in %s" % x
with:
Label(master, text="FXCM does not accept cards issued in %s" % x).pack()
in each of your functions.
Or better add:
lbl = Label(master)
lbl.pack()
under your e lines and then replace the returns with:
lbl['text'] = x
You don't call the textBox function. For this to work, if I understand the problem correctly, the called function has to update the text box label. Also, you don't send the lower() county to the function. A shortened version of your code
import sys
if sys.version_info[0] < 3:
import Tkinter as tk ## Python 2.x
else:
import tkinter as tk ## Python 3.x
ltdCountries = ['austria','belgium','bulgaria','croatia','cyprus','czech republic']
sepaCountries = ['austria','belgium','bulgaria','cyprus','czech republic','check']
marketsCountries = ['albania','algeria','andorra','angola','anguilla']
def ltd(country):
var.set(var.get() +" *** ltd " + country)
def sepa(country):
var.set(var.get() +" *** sepa " + country)
def markets(country):
var.set(var.get() +" *** markets " + country)
def mainProgram():
typedCountry = e.get()
print('Your country is: ' + typedCountry + '\n')
country_lower=typedCountry.lower()
for country_list, country_function in ((ltdCountries, ltd),
(sepaCountries, sepa),
(marketsCountries, markets)):
if country_lower in country_list:
country_function(country_lower)
master = tk.Tk()
e = tk.Entry(master)
e.pack()
e.focus_set()
var=tk.StringVar()
var.set("")
tk.Label(master, textvariable=var, bg="lightyellow",
width=25).pack()
b = tk.Button(master, text = "Search", command = mainProgram)
b.pack()
tk.Button(master, text="Quit", bg="orange",
command=master.quit).pack()
master.mainloop()
# First create a text box
txt = scrolledtext.ScrolledText(root)
# this line is for deleting it's content
txt.delete(1.0, END)
# this other line is for inserting text in it
txt.insert(1.0, 'Some Text')

Close TopLevel window after command

I'm doing a simple compressor in Python for a school assignment, my problem here is that when you enter the name of the file, a little window has to appear with a button that will execute the tar command, I want that window to close after it does the command but I dont know why, here's my code
def crea_arxiu():
global aux
if v.get() is 1 or v.get() is 2 or v.get() is 3 or v.get() is 4:
f = open('fitxers.txt','w')
for i in range(llista2.size()):
f.write(llista2.get(i)+'\n')
f.close()
print 'Arxius a comprimir:',llista2.size()
obre_finestra()
if aux is 1:
print 'AUX IS TRUE'
subprocess.call(['rm','fitxers.txt'])
else:
print 'Escolleix una opcio'
#Aquest mètode crea i mostra la pantalla per guardar el nom
#i i la finestra amb la comanda que executara
def obre_finestra():
global aux
ruta_text = StringVar()
finestra2=Toplevel(finestra)
finestra2.minsize(0,0)
finestra2.title('Comanda a executar:')
ruta = Label(finestra2, width=60, relief=SUNKEN, textvariable=ruta_text)
ruta.pack(side=LEFT)
boto = Button(finestra2, text = 'Executar', command = lambda: executar_commanda(nom_arxiu, tipus_comp))
boto.pack(side = RIGHT)
nom_arxiu = tkFileDialog.asksaveasfilename(title='Guardar com')
if v.get() is 1:
tipus_comp = 'cf'
nom_arxiu = nom_arxiu+'.tar'
elif v.get() is 2:
tipus_comp = 'czf'
nom_arxiu = nom_arxiu+'.tgz'
elif v.get() is 3:
tipus_comp = 'cjf'
nom_arxiu = nom_arxiu+'.tbz'
elif v.get() is 4:
tipus_comp = 'cJf'
nom_arxiu = nom_arxiu+'.txz'
ruta_text.set('tar '+tipus_comp+' '+nom_arxiu+' '+'fitxers de la llista')
if aux is 1:
finestra2.destroy()
def executar_commanda(nom,tipus_comp):
global aux
aux = 1
subprocess.call(['tar',tipus_comp,nom,'-T','fitxers.txt'])
The order of the functions is: crea_arxiu -> obre_finestra (summons the asksaveasfilename and the little window) , and when i press 'Execute' does executar_commanda and then i want the window to be killed
Before entering the name of the file:
http://imgur.com/KOgxIe3
After the name is given:
http://imgur.com/zDB5Bbs
So at the end I just want the path window to be closed after it does de 'Executar' button, so much thank you guys and sry for my english not being so good ^^'

Categories