Can't understand why function doesn't work - python

I'm new to Python3 and coding. I'am get stuck with a simple function.
import datetime
date = str(datetime.date.today())
mail = ""
text = (f"""
some text {mail}
some text {date}
some text
""")
print(text)
def get_deadline_date():
mail = "a#a.com"
print(text)
And I have
some text
some text 2019-03-21
some text
some text
some text 2019-03-21
some text
I can't change the text variable.
It should print:
some text a#a.com
some text 2019-03-21
some text
As I understand, I made a simple mistake, but I can't figure it out.
I tried,
import datetime
date = str(datetime.date.today())
mail = ""
text = (f"""
some text {mail}
some text {date}
some text
""")
print(text)
def get_deadline_date():
global mail
mail = "a#a.com"
get_deadlin
It gave the same output.

Your function is defined but not executed. And, if it was executed, it would not change the value of mail because it has it's own namespace of variables, so it could access mail but not set it. What you are doing there is declaring a new variable, also called mail in that function. On top of that, your text is already set and will not update when you chnge the value of mail. I suggest this solution:
text = "some text {mail}\n" \
"some text {date}\n" \
"some text"
def make_text(text, date):
mail = "a#a.com"
return text.format(mail=mail, date=date)
text = make_text(text=text, date=date.today())
You may also want to make separate functions for setting mail and making the text, but remember to return the new mail you make to the outer scope.

Mistake 1: You are not calling the function
Mistake 2: mail is local variable (to function)
Mistake 3: String is already evaluated/initialised
Bad, but your solution should be
import datetime
date = str(datetime.date.today())
mail = ""
text = """
some text {0}
some text {1}
some text
""".format
print(text(mail, date))
def get_deadline_date():
global mail
mail = "a#a.com"
get_deadline_date()
print(text(mail, date))
Avoid global variable
Dedesign your code to avoid global variable, use function parameters and return values instead.

Related

Tkinter: How to print text into a Label?

I have something like an e-mail storage and I want that the saved information printed out in my Label, but I want that the information stacked among each other.
This is my code, but when I enter another e-mail and password, the current Label text is replaced.
How can I fix that?
def print_data(mail,passwort):
label_list["text"] = str(mail)+" | "+str(passwort)
def save_info():
mail = entry_mail.get()
passwort = entry_passwort.get()
entry_mail.delete(0, tk.END)
entry_passwort.delete(0, tk.END)
print_data(mail,passwort)
you have to store the previous information in a variable. Then
use:
label.configure(text= "previous label" + "new text")

How to get readable unicode string from single bibtex entry field in python script

Suppose you have a .bib file containing bibtex-formatted entries. I want to extract the "title" field from an entry, and then format it to a readable unicode string.
For example, if the entry was:
#article{mypaper,
author = {myself},
title = {A very nice {title} with annoying {symbols} like {\^{a}}}
}
what I want to extract is the string:
A very nice title with annoying symbols like รข
I am currently trying to use the pybtex package, but I cannot figure out how to do it. The command-line utility pybtex-format does a good job in converting full .bib files, but I need to do this inside a script and for single title entries.
Figured it out:
def load_bib(filename):
from pybtex.database.input.bibtex import Parser
parser = Parser()
DB = parser.parse_file(filename)
return DB
def get_title(entry):
from pybtex.plugin import find_plugin
style = find_plugin('pybtex.style.formatting', 'plain')()
backend = find_plugin('pybtex.backends', 'plaintext')()
sentence = style.format_title(entry, 'title')
data = {'entry': entry,
'style': style,
'bib_data': None}
T = sentence.f(sentence.children, data)
title = T.render(backend)
return title
DB = load_bib("bibliography.bib")
print ( get_title(DB.entries["entry_label"]) )
where entry_label must match the label you use in latex to cite the bibliography entry.
Building upon the answer by Daniele, I wrote this function that lets one render fields without having to use a file.
from io import StringIO
from pybtex.database.input.bibtex import Parser
from pybtex.plugin import find_plugin
def render_fields(author="", title=""):
"""The arguments are in bibtex format. For example, they may contain
things like \'{i}. The output is a dictionary with these fields
rendered in plain text.
If you run tests by defining a string in Python, use r'''string''' to
avoid issues with escape characters.
"""
parser = Parser()
istr = r'''
#article{foo,
Author = {''' + author + r'''},
Title = {''' + title + '''},
}
'''
bib_data = parser.parse_stream(StringIO(istr))
style = find_plugin('pybtex.style.formatting', 'plain')()
backend = find_plugin('pybtex.backends', 'plaintext')()
entry = bib_data.entries["foo"]
data = {'entry': entry, 'style': style, 'bib_data': None}
sentence = style.format_author_or_editor(entry)
T = sentence.f(sentence.children, data)
rendered_author = T.render(backend)[0:-1] # exclude period
sentence = style.format_title(entry, 'title')
T = sentence.f(sentence.children, data)
rendered_title = T.render(backend)[0:-1] # exclude period
return {'title': rendered_title, 'author': rendered_author}

How to use global variable from one scenario in other. Python, Webdriver, lettuce

I'm using WebDriiver, lettuce and python for testing. In first scenario I verifay, that user can create anaccount. For user name I use an e-mail generaror with timestamp.
the lettuce step is:
Then input text "NEW_EMAIL" to text field with ID "s-txt-email"
the python code is:
#step('input text "([^"]*)" to text field with ID "([^"]*)"')
def input_with_id(step, txt, ID):
global new_email
links = get_driver().find_elements_by_xpath("//input[#id='%s']" % ID)
if links:
links[0].click()
else:
raise ValueError('Link with ID %s not found' % ID)
if not "generated_email" in txt:
timestamp = datetime.now().strftime('%m_%d_%Y.%H_%M')
new_email = "automation.%s#yopmail.com" % timestamp
txts = {"NEW_EMAIL": new_email,
"STANDARD_PSW": "xxxxx",
"NEW_USER": new_email,
}
if txt in txts.keys():
txt = txts[txt]
else:
txt = new_email
links[0].send_keys(str(txt))
In other scenario I'm using the same code for verify that user can loggin.
Lettuce step is:
Then input text "generated_email" to text field with ID "l-txt-email-address"
And python code is the same (see above).
But it's generated new e-mail with new timestamp and user can't loggin. What I'm douing wrong? How I can use global variable from one scenario in other one?

Python dictionary editing entries

def replace_acronym(): # function not yet implemented
#FIND
for abbr, text in acronyms.items():
if abbr == acronym_edit.get():
textadd.insert(0,text)
#DELETE
name = acronym_edit.get().upper()
name.upper()
r =dict(acronyms)
del r[name]
with open('acronym_dict.py','w')as outfile:
outfile.write(str(r))
outfile.close() # uneccessary explicit closure since used with...
message ='{0} {1} {2} \n '.format('Removed', name,'with its text from the database.')
display.insert('0.0',message)
#ADD
abbr_in = acronym_edit.get()
text_in = add_expansion.get()
acronyms[abbr_in] = text_in
# write amended dictionary
with open('acronym_dict.py','w')as outfile:
outfile.write(str(acronyms))
outfile.close()
message ='{0} {1}:{2}{3}\n '.format('Modified entry', abbr_in,text_in, 'added')
display.insert('0.0',message)
I am trying to add the functionality of editing my dictionary entries in my tkinter widget. The dictionary is in the format {ACRONYM: text, ACRONYM2: text2...}
What I thought the function would achieve is to find the entry in the dictionary, delete both the acronym and its associated text and then add whatever the acronym and text have been changed to. What happens is for example if I have an entry TEST: test and I want to modify it to TEXT: abc what is returned by the function is TEXT: testabc - appending the changed text although I have (I thought) overwritten the file.
What am I doing wrong?
That's a pretty messy lookin' function. The acronym replacement itself can be done pretty simple:
acronyms = {'SONAR': 'SOund Navigation And Ranging',
'HTML': 'HyperText Markup Language',
'CSS': 'Cascading Style Sheets',
'TEST': 'test',
'SCUBA': 'Self Contained Underwater Breathing Apparatus',
'RADAR': 'RAdio Detection And Ranging',
}
def replace_acronym(a_dict,check_for,replacement_key,replacement_text):
c = a_dict.get(check_for)
if c is not None:
del a_dict[check_for]
a_dict[replacement_key] = replacement_text
return a_dict
new_acronyms = replace_acronym(acronyms,'TEST','TEXT','abc')
That works perfect for me (in Python 3). You could just call this in another function that writes the new_acronyms dict into the file or do whatever else you want with it 'cause it's no longer tied to just being written to the file.

Python using(parsing) a textbox value as string into a function

url=StringVar()
txt1=Entry(root,textvariable=url)
txt1.pack()
button1 = Button(root, text="Download" ,command=downloadFile)
button1.pack()
root.mainloop()
ok this is my basic GUI... I have a textbox txt1 which i want to use in the function below
def downloadFile():
#print "url is:",url
file_name = url.split('/')[-1]
My aim is to feed in the URL in the textbox and then split the URL in my function downloadfile(), but my url variable becomes PY_VAR0 instead of "www.example.com/file.exe"
and the error message I get is "StringVar instance has no attribute split"
I am doing something very wrong but i don't know where.
Can anyone help please?
StringVar is just a "Value holder for strings variables". To get its content (the string) use:
StringVar.get() # Return value of variable as string.
printing the StringVar directly ("print url") invokes:
StringVar.__str__() # Return the name of the variable in Tcl.
which will return the internal variable name, not its value. in your code use:
file_name = url.get().split('/')[-1]

Categories