Where do I put end_editing() in Pythonista? - pythonista

I’m making a little pricing tool in Pythonista. Here’s what I wrote.
# starts actions with go button
def getPrices(mtmPriceUser):
viewSelector = mtmPriceUser.superview
userInput = viewSelector['textview1'].text
userInput = float(userInput)
textLabel1 = v['label1']
discNamesList, discOutcomesdict = creatDiscList(standardDisc, userInput)
# create string of discounts and prices
priceString = createString(discNamesList,discOutcomesDict)
textLabel1.text = priceString
textLabel1.end_editing()
v = ui.load_view()
v.present('sheet')
I get the following error
Traceback (most recent call last):
File "/private/var/mobile/Containers/Shared/AppGroup/7C463C71-C565-47D8-A1D8-C2D588A974C1/Pythonista3/Documents/Pricing App/UI_Attempt.py", line 79, in getPrices
textLabel1.end_editing()
AttributeError: '_ui.Label' object has no attribute 'end_editing'
Where do I use the end editing method? If I can’t, how else can I get the keyboard to go away after I push the button?

You seem to be calling end_editing() on a label, which does not have this method.
You need to call the method on the TextField or TextView object that was used for data entry.
In your case, this seems to be viewSelector['textview1'] which might be worth storing in a variable for simplicity, like you do with the label.
For example:
text_entry = viewSelector['textview1']
userInput = text_entry.text
# Your other code
text_entry.end_editing()

Related

how to read a multiline element from PySimpleGUI

My program stub looks like this:
import PySimpleGUI as sg
layout = [[sg.Text("Geheime Nachricht eintippen:")],
[sg.Multiline(size=(70,4),key="GEHEIM")],
[sg.Spin([i for i in range(1,26)], initial_value=12, key="SS"), sg.Text("Schlüssel zwischen 1 und 25 wählen")],
[sg.Radio("Codieren:", "RADIO1", key="XX" ,default=True),
sg.Radio("Decodieren:","RADIO1", key="YY")],
[sg.Text("ERGEBNIS:")],
[sg.Multiline(size=(70,4),key="AUSGABE")],
[sg.Button("Weiter"), sg.Button("Ende")]]
window = sg.Window("Geheimcode", layout)
while True: # Ereignisschleife
event, values = window.Read()
geheimertext = values("GEHEIM")
print(values("GEHEIM"))
schluessel = int(values["SS"])
print ("Schlüssel = ", schluessel)
if values["XX"] == True:
codedecode = "C"
print("wir codieren:",codedecode)
else:
codedecode = "D"
print("wir decodieren:",codedecode)
if event is None or event == "Ende":
break
window.Close()
The program-line geheimertext = values("GEHEIM") gives this error:
TypeError: 'dict' object is not callable
I quess that the multiline generates a dictonary in the dictionary values?
so my simple newbie-question is how to read the multiline of a gui made with pysimpleGUI
ok, one possible solution is to iterate over the elements of the multiline:
geheimertext=""
for zeichen in values["GEHEIM"]:
geheimertext = geheimertext +zeichen
print(geheimertext)
Is there a better solution? Please teach a newbie
print(values["GEHEIM"])
values is a dict, and not a callable, so you cannot use () brackets (callables are functions or objects that have a function property). You can access to values through [] brackets. values["GEHEIM"].

How to use the __post_init__ method in Dataclasses in Python

I am trying to get my hands dirty with dataclasses in Python and what i want to do is have a computed field inside my class and also add the sort_index field to the call but would also want to make it frozen so that i cannot modify any attributes of this class after definition. Below is my code:
from dataclasses import dataclass, field
def _get_year_of_birth(age: int, current_year: int=2019):
return current_year - age
#dataclass(order=True, frozen=True)
class Person():
sort_index: int = field(init=False, repr=False)
name: str
lastname: str
age: int
birthyear: int = field(init=False)
def __post_init__(self):
self.sort_index = self.age
self.birthyear = _get_year_of_birth(self.age)
if __name__ == "__main__":
persons = [
Person(name="Jack", lastname="Ryan", age=35),
Person(name="Jason", lastname="Bourne", age=45),
Person(name="James", lastname="Bond", age=60)
]
sorted_persons = sorted(persons)
for person in sorted_persons:
print(f"{person.name} and {person.age} and year of birth is : {person.birthyear}")
It seems that i cannot set a custom sort field inside my class and also cannot create any attribute which is computed from other attributes since i am using frozen . When i run the above i get the below error:
Traceback (most recent call last):
File "dataclasses_2.py", line 30, in <module>
Person(name="Jack", lastname="Ryan", age=35),
File "<string>", line 5, in __init__
File "dataclasses_2.py", line 23, in __post_init__
self.sort_index = self.age
File "<string>", line 3, in __setattr__
dataclasses.FrozenInstanceError: cannot assign to field 'sort_index'
Is there a better way of doing this ? Please help
The problem is you are trying to set a field of a frozen object.
There are two options here. First option would be to remove frozen=True from the dataclass specification. Secondly, if you still want to freeze Person instances, then you should initialize fields with method __setattr__. Therefore, your post_init method will become:
def __post_init__(self):
object.__setattr__(self, 'sort_index', self.age)
object.__setattr__(self, 'birthyear', _get_year_of_birth(self.age)

Why does mongodb motor not resolve the data correctly?

I have a huge tornado app that was written in a blocking manner. I'm trying to convert my db calls to run async. I'm having lots of issues.
I keep the mongo calls in a top level folder called lib and in the app folder I keep all my views.
The error i'm getting
Traceback (most recent call last):
File "/Users/marcsantiago/staging_env/lib/python2.7/site-packages/tornado/web.py", line 1445, in _execute
result = yield result
File "/Users/marcsantiago/staging_env/lib/python2.7/site-packages/tornado/gen.py", line 1008, in run
value = future.result()
File "/Users/marcsantiago/staging_env/lib/python2.7/site-packages/tornado/concurrent.py", line 232, in result
raise_exc_info(self._exc_info)
File "/Users/marcsantiago/staging_env/lib/python2.7/site-packages/tornado/gen.py", line 1017, in run
yielded = self.gen.send(value)
File "/Users/marcsantiago/pubgears/app/admin.py", line 179, in get
notes, start_date, stats, last_updated = self.db_data()
File "/Users/marcsantiago/pubgears/app/admin.py", line 76, in db_data
while (yield chain_slugs_updated.fetch_next):
AttributeError: 'NoneType' object has no attribute 'fetch_next'
So inside the lib folder I have this method.
def get_chains_updated(date):
slugs = []
# Chain class can't do aggregate could create a class instance if i want
cursor = db.chain.aggregate([
{'$match':{'last_update':{'$gt':date}}},
{'$group':{'_id':{'site':'$site'}, 'total':{'$sum':'$count'}}}
])
while (yield cursor.fetch_next):
res = yield cursor.next_object()
slugs.append(res['_id']['site'])
yield slugs
Later I call this method one of my views
chain_slugs_updated = yield chaindb.get_chains_updated(yesterday)
slugs = []
#for site in chain_slugs_updated:
while (yield chain_slugs_updated.fetch_next):
site = chain_slugs_updated.next_object()
slugs.append('%s' % (site, site))
notes.append('<strong>%s</strong> chains have been updated in the past 24 hours (%s).' % (chain_slugs_updated.count(), ', '.join(slugs)))
This is what it use to be when I was using pymongo
lib
def get_chains_updated(date):
slugs = []
# Chain class can't do aggregate could create a class instance if i want
results = db.chain.aggregate([
{'$match':{'last_update':{'$gt':date}}},
{'$group':{'_id':{'site':'$site'}, 'total':{'$sum':'$count'}}}
])
for res in results:
slugs.append(res['_id']['site'])
return slugs
view
chain_slugs_updated = chaindb.get_chains_updated(yesterday)
slugs = []
for site in chain_slugs_updated:
slugs.append('%s' % (site, site))
notes.append('<strong>%s</strong> chains have been updated in the past 24 hours (%s).' % (len(chain_slugs_updated), ', '.join(slugs)))
I have tons of code I have to translate to get this async working correctly, I would very much appreciate any help. Thanks.
To return a list of objects from get_chains_updated, you must either return slugs the list (Python 3) or raise gen.Return(slugs) (all Python versions). For more info, see Refactoring Tornado Coroutines.

What am I doing wrong with this Python class? AttributeError: 'NoneType' object has no attribute 'usernames'

Hey there I am trying to make my first class my code is as follows:
class Twitt:
def __init__(self):
self.usernames = []
self.names = []
self.tweet = []
self.imageurl = []
def twitter_lookup(self, coordinents, radius):
twitter = Twitter(auth=auth)
coordinents = coordinents + "," + radius
print coordinents
query = twitter.search.tweets(q="", geocode='33.520661,-86.80249,50mi', rpp=10)
print query
for result in query["statuses"]:
self.usernames.append(result["user"]["screen_name"])
self.names.append(result['user']["name"])
self.tweet.append(h.unescape(result["text"]))
self.imageurl.append(result['user']["profile_image_url_https"])
What I am trying to be able to do is then use my class like so:
test = Twitt()
hello = test.twitter_lookup("38.5815720,-121.4944000","1m")
print hello.usernames
This does not work and I keep getting: "AttributeError: 'NoneType' object has no attribute 'usernames'"
Maybe I just misunderstood the tutorial or am trying to use this wrong. Any help would be appreciated thanks.
I see the error is test.twitter_lookup("38.5815720,-121.4944000","1m") return nothing. If you want the usernames, you need to do
test = Twitt()
test.twitter_lookup("38.5815720,-121.4944000","1m")
test.usernames
Your function twitter_lookup is modifying the Twitt object in-place. You didn't make it return any kind of value, so when you call hello = test.twitter_lookup(), there's no return value to assign to hello, and it ends up as None. Try test.usernames instead.
Alternatively, have the twitter_lookup function put its results in some new object (perhaps a dictionary?) and return it. This is probably the more sensible solution.
Also, the function accepts a coordinents (it's 'coordinates') argument, but then throws it away and uses a hard-coded value instead.

Why do I get mysterious "TypeError: can only update value with String or number"?

This is really bizarre. If I run this code (as a nose test), it prints "-0:34:00.0" and all is well
def test_o1(self):
observer = ephem.Observer()
observer.lon, observer.lat = math.radians(73.9), math.radians(40.7)
observer.horizon = '-0:34'
print observer.horizon
but, if I run this:
def test_o2(self):
location = UserLocation()
location.foo()
where UserLocation is:
# Document is mongoengine.Document
class UserLocation(Document):
[...]
def foo(self):
observer = ephem.Observer()
observer.lon, observer.lat = math.radians(73.9), math.radians(40.7)
observer.horizon = '-0:34'
I get:
Traceback (most recent call last):
File "/home/roy/deploy/current/python/local/lib/python2.7/site-packages/nose/case.py", line 197, in runTest
self.test(*self.arg)
File "/home/roy/deploy/current/code/pyza/models/test_user_location.py", line 82, in test_o2
location.foo()
File "/home/roy/deploy/current/code/pyza/models/user_location.py", line 134, in foo
observer.horizon = '-0:34'
TypeError: can only update value with String or number
Any idea what might be going on?
Arrggghhh. I figured it out. My UserLocation source file starts with:
from future import unicode_literals
apparently, _libastro insists on ascii strings, not unicode.