[web2py] Re: Multi computed fields
The onsuccess parameter of form.process() seems to cover your problems: from http://web2py.com/books/default/chapter/29/7 onsuccess and onfailure can be functions like lambda form: do_something(form) Il giorno giovedì 17 maggio 2012 10:35:46 UTC+2, Gabriella Canavesi ha scritto: Hi all, I have a simple table with 3 computed fields, the function that set their values is almost the same. However, unfortunately I had to set up three different functions because I didn't find a better approach. The code: db.define_table('cities', Field('name', 'string', requires=IS_TRIM()), Field('full_address', 'string',requires=IS_TRIM()), Field(lat, double, label=T('Latitude')), Field(lgt, double, label=T('Longitude'))) db.cities.full_address.compute = compute_geoCode_place db.cities.lat.compute = compute_geoCode_lat db.cities.lgt.compute = compute_geoCode_lng def compute_geoCode_place(r): g = geocoders.Google() place, (lat, lng) = g.geocode(r.name) return place def compute_geoCode_lat(r): g = geocoders.Google() place, (lat, lng) = g.geocode(r.name) return lat def compute_geoCode_lng(r): g = geocoders.Google() place, (lat, lng) = g.geocode(r.name) return lng What I would like to find is a way to fire the execution of a function when the form is submitted. More or less something like a compute action at table level. Regards, -- Paolo
[web2py] Re: Multi computed fields
To get it down to it down to one function, how about: def compute_geoCode(r, component): g = geocoders.Google() place, (lat, lng) = g.geocode(r.name) return eval(component) db.cities.full_address.compute = lambda r: compute_geoCode(r, 'place') db.cities.lat.compute = lambda r: compute_geoCode(r, 'lat') db.cities.lgt.compute = lambda r: compute_geoCode(r, 'lng') Anthony On Thursday, May 17, 2012 4:35:46 AM UTC-4, Gabriella Canavesi wrote: Hi all, I have a simple table with 3 computed fields, the function that set their values is almost the same. However, unfortunately I had to set up three different functions because I didn't find a better approach. The code: db.define_table('cities', Field('name', 'string', requires=IS_TRIM()), Field('full_address', 'string',requires=IS_TRIM()), Field(lat, double, label=T('Latitude')), Field(lgt, double, label=T('Longitude'))) db.cities.full_address.compute = compute_geoCode_place db.cities.lat.compute = compute_geoCode_lat db.cities.lgt.compute = compute_geoCode_lng def compute_geoCode_place(r): g = geocoders.Google() place, (lat, lng) = g.geocode(r.name) return place def compute_geoCode_lat(r): g = geocoders.Google() place, (lat, lng) = g.geocode(r.name) return lat def compute_geoCode_lng(r): g = geocoders.Google() place, (lat, lng) = g.geocode(r.name) return lng What I would like to find is a way to fire the execution of a function when the form is submitted. More or less something like a compute action at table level. Regards, -- Paolo
Re: [web2py] Re: Multi computed fields
Hi Niphlod, thanks for your answer. Actually, I am looking for something that I can put in my model without touch the code of the forms, e.g., I don't want to change the code of the admin application to solve the problem. Paolo Il 17.05.2012 13:14 Niphlod ha scritto: The onsuccess parameter of form.process() seems to cover your problems: from http://web2py.com/books/default/chapter/29/7 onsuccess and onfailure can be functions like lambda form: do_something(form) Il giorno giovedì 17 maggio 2012 10:35:46 UTC+2, Gabriella Canavesi ha scritto: Hi all, I have a simple table with 3 computed fields, the function that set their values is almost the same. However, unfortunately I had to set up three different functions because I didn't find a better approach. The code: db.define_table('cities', Field('name', 'string', requires=IS_TRIM()), Field('full_address', 'string',requires=IS_TRIM()), Field(lat, double, label=T('Latitude')), Field(lgt, double, label=T('Longitude'))) db.cities.full_address.compute = compute_geoCode_place db.cities.lat.compute = compute_geoCode_lat db.cities.lgt.compute = compute_geoCode_lng def compute_geoCode_place(r): g = geocoders.Google() place, (lat, lng) = g.geocode(r.name [1]) return place def compute_geoCode_lat(r): g = geocoders.Google() place, (lat, lng) = g.geocode(r.name [2]) return lat def compute_geoCode_lng(r): g = geocoders.Google() place, (lat, lng) = g.geocode(r.name [3]) return lng What I would like to find is a way to fire the execution of a function when the form is submitted. More or less something like a compute action at table level. Regards, -- Paolo Links: -- [1] http://r.name [2] http://r.name [3] http://r.name
Re: [web2py] Re: Multi computed fields
Hi Anthony, thanks for the answer, Your solution is pretty nice but I am still calling it 3 times which actually is the main problem since I am asking 'google' 3 times the same stuff. Is it possible to store the answer somewhere (cache?) the first time and then use the cache copy for the latter calls? Regards, Paolo Il 17.05.2012 15:09 Anthony ha scritto: To get it down to it down to one function, how about: def compute_geoCode(r, component): g = geocoders.Google() place, (lat, lng) = g.geocode(r.name [4]) return eval(component) db.cities.full_address.compute = lambda r: compute_geoCode(r, 'place') db.cities.lat.compute = lambda r: compute_geoCode(r, 'lat') db.cities.lgt.compute = lambda r: compute_geoCode(r, 'lng') Anthony On Thursday, May 17, 2012 4:35:46 AM UTC-4, Gabriella Canavesi wrote: Hi all, I have a simple table with 3 computed fields, the function that set their values is almost the same. However, unfortunately I had to set up three different functions because I didn't find a better approach. The code: db.define_table('cities', Field('name', 'string', requires=IS_TRIM()), Field('full_address', 'string',requires=IS_TRIM()), Field(lat, double, label=T('Latitude')), Field(lgt, double, label=T('Longitude'))) db.cities.full_address.compute = compute_geoCode_place db.cities.lat.compute = compute_geoCode_lat db.cities.lgt.compute = compute_geoCode_lng def compute_geoCode_place(r): g = geocoders.Google() place, (lat, lng) = g.geocode(r.name [1]) return place def compute_geoCode_lat(r): g = geocoders.Google() place, (lat, lng) = g.geocode(r.name [2]) return lat def compute_geoCode_lng(r): g = geocoders.Google() place, (lat, lng) = g.geocode(r.name [3]) return lng What I would like to find is a way to fire the execution of a function when the form is submitted. More or less something like a compute action at table level. Regards, -- Paolo Links: -- [1] http://r.name [2] http://r.name [3] http://r.name [4] http://r.name/ -- Paolo
Re: [web2py] Re: Multi computed fields
def compute_geoCode(r, component): g = geocoders.Google() place, (lat, lng) = cache.ram(r.name, lambda: g.geocode(r.name), None) return eval(component) Anthony On Thursday, May 17, 2012 11:44:16 AM UTC-4, Gabriella Canavesi wrote: Hi Anthony, thanks for the answer, Your solution is pretty nice but I am still calling it 3 times which actually is the main problem since I am asking 'google' 3 times the same stuff. Is it possible to store the answer somewhere (cache?) the first time and then use the cache copy for the latter calls? Regards, Paolo Il 17.05.2012 15:09 Anthony ha scritto: To get it down to it down to one function, how about: def compute_geoCode(r, component): g = geocoders.Google() place, (lat, lng) = g.geocode(r.name [4]) return eval(component) db.cities.full_address.compute = lambda r: compute_geoCode(r, 'place') db.cities.lat.compute = lambda r: compute_geoCode(r, 'lat') db.cities.lgt.compute = lambda r: compute_geoCode(r, 'lng') Anthony On Thursday, May 17, 2012 4:35:46 AM UTC-4, Gabriella Canavesi wrote: Hi all, I have a simple table with 3 computed fields, the function that set their values is almost the same. However, unfortunately I had to set up three different functions because I didn't find a better approach. The code: db.define_table('cities', Field('name', 'string', requires=IS_TRIM()), Field('full_address', 'string',requires=IS_TRIM()), Field(lat, double, label=T('Latitude')), Field(lgt, double, label=T('Longitude'))) db.cities.full_address.compute = compute_geoCode_place db.cities.lat.compute = compute_geoCode_lat db.cities.lgt.compute = compute_geoCode_lng def compute_geoCode_place(r): g = geocoders.Google() place, (lat, lng) = g.geocode(r.name [1]) return place def compute_geoCode_lat(r): g = geocoders.Google() place, (lat, lng) = g.geocode(r.name [2]) return lat def compute_geoCode_lng(r): g = geocoders.Google() place, (lat, lng) = g.geocode(r.name [3]) return lng What I would like to find is a way to fire the execution of a function when the form is submitted. More or less something like a compute action at table level. Regards, -- Paolo Links: -- [1] http://r.name [2] http://r.name [3] http://r.name [4] http://r.name/ -- Paolo
Re: [web2py] Re: Multi computed fields
Hi Niphlod, thanks for your answer. Actually, I am looking for something that I can put in my model without touch the code of the forms, e.g., I don't want to change the code of the admin application to solve the problem. In this case, I think caching in the compute_geoCode function is probably the best approach, but in general, if you want to execute a function (or set of functions) when doing inserts, updates, or deletes, you can append functions to the table's _before_insert, _before_update, _before_delete, _after_insert, _after_update, or _after_delete lists. The _after_insert functions receive a dictionary of the fields that were inserted as well as the record ID of the inserted record. After insert, you could update the record with the three values from the g.geocode() call. def compute_geoCode(r, id): g = geocoders.Google() place, (lat, lng) = g.geocode(r http://r.name/['name']) db.cities[id] = dict(full_address=place, lat=lat, lgt=lng) db.cities._after_insert.append(compute_geoCode) db.cities._after_update.append(compute_geoCode) That results in a second db operation (i.e., the update). An alternative would be to use a _before_insert function to call g.geocode() and cache the result, and then have the individual fields' compute functions retrieve the result from the cache. Note, the _before_ and _after_ functionality is available in trunk, but I don't think it's in the current stable release. Anthony
Re: [web2py] Re: Multi computed fields
This is perfect! Thank you very much Anthony. Paolo Il 17.05.2012 16:47 Anthony ha scritto: def compute_geoCode(r, component): g = geocoders.Google() place, (lat, lng) = cache.ram(r.name, lambda: g.geocode(r.name [9]), None) return eval(component) Anthony On Thursday, May 17, 2012 11:44:16 AM UTC-4, Gabriella Canavesi wrote: Hi Anthony, thanks for the answer, Your solution is pretty nice but I am still calling it 3 times which actually is the main problem since I am asking 'google' 3 times the same stuff. Is it possible to store the answer somewhere (cache?) the first time and then use the cache copy for the latter calls? Regards, Paolo Il 17.05.2012 15:09 Anthony ha scritto: To get it down to it down to one function, how about: def compute_geoCode(r, component): g = geocoders.Google() place, (lat, lng) = g.geocode(r.name [1] [4]) return eval(component) db.cities.full_address.compute = lambda r: compute_geoCode(r, 'place') db.cities.lat.compute = lambda r: compute_geoCode(r, 'lat') db.cities.lgt.compute = lambda r: compute_geoCode(r, 'lng') Anthony On Thursday, May 17, 2012 4:35:46 AM UTC-4, Gabriella Canavesi wrote: Hi all, I have a simple table with 3 computed fields, the function that set their values is almost the same. However, unfortunately I had to set up three different functions because I didn't find a better approach. The code: db.define_table('cities', Field('name', 'string', requires=IS_TRIM()), Field('full_address', 'string',requires=IS_TRIM()), Field(lat, double, label=T('Latitude')), Field(lgt, double, label=T('Longitude'))) db.cities.full_address.compute = compute_geoCode_place db.cities.lat.compute = compute_geoCode_lat db.cities.lgt.compute = compute_geoCode_lng def compute_geoCode_place(r): g = geocoders.Google() place, (lat, lng) = g.geocode(r.name [2] [1]) return place def compute_geoCode_lat(r): g = geocoders.Google() place, (lat, lng) = g.geocode(r.name [3] [2]) return lat def compute_geoCode_lng(r): g = geocoders.Google() place, (lat, lng) = g.geocode(r.name [4] [3]) return lng What I would like to find is a way to fire the execution of a function when the form is submitted. More or less something like a compute action at table level. Regards, -- Paolo Links: -- [1] http://r.name [5] [2] http://r.name [6] [3] http://r.name [7] [4] http://r.name/ [8] -- Paolo Links: -- [1] http://r.name [2] http://r.name [3] http://r.name [4] http://r.name [5] http://r.name [6] http://r.name [7] http://r.name [8] http://r.name/ [9] http://r.name/