linking jupyter widget text box to a function plotting a graph - function

I am trying to construct a user interface in Jupyter notebook that is able to link one function with a text widget and button widget.
My function creates a plot for the stock price of a given stock from a start date to end date. The functions is as follow
import pandas_datareader as pdr
from datetime import datetime
def company(ticker):
strt=datetime(2020,1,1)
end=datetime.now()
dat=pdr.get_data_yahoo(ticker, strt, end)
return dat['Close'].plot(grid=True)
The following command plots apple stock price.
company('AAPL')
Now i create a text and button widget as follow
import ipywidgets as ipw
box=ipw.Text(
value='Stock handle',
placeholder='Type something',
description='String:',
disabled=False)
btn=ipw.ToggleButton(
value=False,
description='Plot',
disabled=False,
button_style='', # 'success', 'info', 'warning', 'danger' or ''
tooltip='Description',
icon='check' # (FontAwesome names without the `fa-` prefix))
I tried to link the function company with box as follow:
box.on_submit(company)
When I write AAPL in box it gives me error "TypeError: object of type 'Text' has no len()
"
My goal is to create an interface where i write the name of the stock('AAPL') in the box and click the btn at which point the plot of the stock price will appear.
Any help is appreciated. Thank you.

When you attach a function with on_submit, the entire widget gets passed as the argument to the function (not just the text value). So within your company function, ticker is actually your instance of the Text widget. Hence the error, as you cannot call len on a widget.
To get the text value of the widget, use ticker.value, which you should be able to call len on just fine.
def print_it(ticker):
# print(len(ticker)) # raises TypeError, you're calling len on the Text widget
print(len(ticker.value)) # will work, as you're accessing the `value` of the widget which is a string
t = ipywidgets.Text(continuous_update=False)
t.on_submit(print_it)
t
NB. the on_submit method is deprecated as of ipywidgets 7.0, much better to create your box using use box.observe(), and when you create your box include continuous_update=False as a kwarg. With this method, a dictionary of info gets passed to your function, so you need to parse out the new value and print it.
def print_it(ticker):
print(ticker['new']) # will work, as you're accessing the string value of the widget
t = ipywidgets.Text(continuous_update=False)
t.observe(print_it, names='value')
t

Related

Ray[RLlib] Custom Action Distribution (TorchDeterministic)

We know that in the case of a Box (continuous action) Action Space, the corresponding Action Distribution is DiagGaussian (probability distribution).
However, I want to use TorchDeterministic (Action Distribution that returns the input values directly).
This is the code, taken from https://github.com/ray-project/ray/blob/a91ddbdeb98e81741beeeb5c17902cab1e771105/rllib/models/torch/torch_action_dist.py#L372:
class TorchDeterministic(TorchDistributionWrapper):
"""Action distribution that returns the input values directly.
This is similar to DiagGaussian with standard deviation zero (thus only
requiring the "mean" values as NN output).
"""
#override(ActionDistribution)
def deterministic_sample(self) -> TensorType:
return self.inputs
#override(TorchDistributionWrapper)
def sampled_action_logp(self) -> TensorType:
return torch.zeros((self.inputs.size()[0], ), dtype=torch.float32)
#override(TorchDistributionWrapper)
def sample(self) -> TensorType:
return self.deterministic_sample()
#staticmethod
#override(ActionDistribution)
def required_model_output_shape(
action_space: gym.Space,
model_config: ModelConfigDict) -> Union[int, np.ndarray]:
return np.prod(action_space.shape)
With the proper imports, I copied and pasted the contents of this class into a file named custom_action_dist.py.
I imported it with:
from custom_action_dist import TorchDeterministic
registered my custom_action_dist with:
ModelCatalog.register_custom_action_dist("my_custom_action_dist", TorchDeterministic)
and in config I specified:
"custom_action_dist": "my_custom_action_dist"
However, I’m getting the following error:
"File "/home/user/DRL/lib/python3.8/site-packages/ray/rllib/models/torch/torch_action_dist.py", line 38, in logp
return self.dist.log_prob(actions)
AttributeError: 'TorchDeterministic' object has no attribute 'dist'"
It seems that I must specify a probability distribution.
Can somebody help me, tell me which one that is?
Thank you and looking forward for your reply!

Get value of object in json file if var is equal to object name - python

I have a function that sees what card is in a player's hand and will add to their score depending on the card in their hand. I have all the card values stored in a JSON file. I have code this so far:
with open("values.json") as values:
value = json.load(values)
for i in range(0, len(hand)):
card = hand[i]
values.json
{
"3Hearts": 3
}
if the card is 3Hearts how could I get the 3 to be returned?
Or is there a better way to store the data?
I will admit I am not very familiar with json files. However if the json file is not a necessity you could just store the data in another .py file (Cards.py for example).
Also, because you are using python, you would be better off making a Card class and make Card objects.
This is what it would look like:
# Make Card Class
class Card:
def __init__(self, name, number):
self.name = name
self.number = number
# Make Card Objects
threehearts = Card("3Hearts", "3")
Here I used threehearts instead of 3Hearts because making an object name starting with a number is not good practice. To compensate I made an attribute Card.name where you can "name" the card "3Hearts" as you did in the question.
So assuming you are going to use that .py file to store your data, this is what I would propose:
# Import data here
from Cards import*
# Make the player's hand
hand = [threehearts]
# Display the number corresponding to the player's hand
for i in range(0, len(hand)):
card = hand[i]
print(card.number)
The output of this code will be:
3
You can also store hand = [threehearts] in the Cards.py file as well if you need to.

Removing characters from column in pandas data frame

My goal is to (1) import Twitter JSON, (2) extract data of interest, (3) create pandas data frame for the variables of interest. Here is my code:
import json
import pandas as pd
tweets = []
for line in open('00.json'):
try:
tweet = json.loads(line)
tweets.append(tweet)
except:
continue
# Tweets often have missing data, therefore use -if- when extracting "keys"
tweet = tweets[0]
ids = [tweet['id_str'] for tweet in tweets if 'id_str' in tweet]
text = [tweet['text'] for tweet in tweets if 'text' in tweet]
lang = [tweet['lang'] for tweet in tweets if 'lang' in tweet]
geo = [tweet['geo'] for tweet in tweets if 'geo' in tweet]
place = [tweet['place'] for tweet in tweets if 'place' in tweet]
# Create a data frame (using pd.Index may be "incorrect", but I am a noob)
df=pd.DataFrame({'Ids':pd.Index(ids),
'Text':pd.Index(text),
'Lang':pd.Index(lang),
'Geo':pd.Index(geo),
'Place':pd.Index(place)})
# Create a data frame satisfying conditions:
df2 = df[(df['Lang']==('en')) & (df['Geo'].dropna())]
So far, everything seems to be working fine.
Now, the extracted values for Geo result in the following example:
df2.loc[1921,'Geo']
{'coordinates': [39.11890951, -84.48903638], 'type': 'Point'}
To get rid of everything except the coordinates inside the squared brackets I tried using:
df2.Geo.str.replace("[({':]", "") ### results in NaN
# and also this:
df2['Geo'] = df2['Geo'].map(lambda x: x.lstrip('{'coordinates': [').rstrip('], 'type': 'Point'')) ### results in syntax error
Please advise on the correct way to obtain coordinates values only.
The following line from your question indicates that this is an issue with understanding the underlying data type of the returned object.
df2.loc[1921,'Geo']
{'coordinates': [39.11890951, -84.48903638], 'type': 'Point'}
You are returning a Python dictionary here -- not a string! If you want to return just the values of the coordinates, you should just use the 'coordinates' key to return those values, e.g.
df2.loc[1921,'Geo']['coordinates']
[39.11890951, -84.48903638]
The returned object in this case will be a Python list object containing the two coordinate values. If you want just one of the values, you can slice the list, e.g.
df2.loc[1921,'Geo']['coordinates'][0]
39.11890951
This workflow is much easier to deal with than casting the dictionary to a string, parsing the string, and recapturing the coordinate values as you are trying to do.
So let's say you want to create a new column called "geo_coord0" which contains all of the coordinates in the first position (as shown above). You could use a something like the following:
df2["geo_coord0"] = [x['coordinates'][0] for x in df2['Geo']]
This uses a Python list comprehension to iterate over all entries in the df2['Geo'] column and for each entry it uses the same syntax we used above to return the first coordinate value. It then assigns these values to a new column in df2.
See the Python documentation on data structures for more details on the data structures discussed above.

Groovy csv to string

I am using Dell Boomi to map data from one system to another. I can use groovy in the maps but have no experience with it. I tried to do this with the other Boomi tools, but have been told that I'll need to use groovy in a script. My inbound data is:
132265,Brown
132265,Gold
132265,Gray
132265,Green
I would like to output:
132265,"Brown,Gold,Gray,Green"
Hopefully this makes sense! Any ideas on the groovy code to make this work?
It can be elegantly solved with groupBy and the spread operator:
#Grapes(
#Grab(group='org.apache.commons', module='commons-csv', version='1.2')
)
import org.apache.commons.csv.*
def csv = '''
132265,Brown
132265,Gold
132265,Gray
132265,Green
'''
def parsed = CSVParser.parse(csv, CSVFormat.DEFAULT.withHeader('code', 'color')
parsed.records.groupBy({ it.code }).each { k,v -> println "$k,\"${v*.color.join(',')}\"" }
The above prints:
132265,"Brown,Gold,Gray,Green"
Well, I don't know how are you getting your data, but here is a general way to achieve your goal. You can use a library, such as the one bellow to parse the csv.
https://github.com/xlson/groovycsv
The example for your data would be:
#Grab('com.xlson.groovycsv:groovycsv:1.1')
import static com.xlson.groovycsv.CsvParser.parseCsv
def csv = '''
132265,Brown
132265,Gold
132265,Gray
132265,Green
'''
def data = parseCsv(csv)
I believe you want to associate the number with various values of colors. So for each line you can create a map of the number and the colors associated with that number, splitting the line by ",":
map = [:]
for(line in data) {
number = line.split(',')[0]
colour = line.split(',')[1]
if(!map[number])
map[number] = []
map[number].add(colour)
}
println map
So map should contain:
[132265:["Brown","Gold","Gray","Green"]]
Well, if it is not what you want, you can extract the general idea.
Assuming your data is coming in as a comma separated string of data like this:
"132265,Brown 132265,Gold 132265,Gray 132265,Green 122222,Red 122222,White"
The following Groovy script code should do the trick.
def csvString = "132265,Brown 132265,Gold 132265,Gray 132265,Green 122222,Red 122222,White"
LinkedHashMap.metaClass.multiPut << { key, value ->
delegate[key] = delegate[key] ?: []; delegate[key] += value
}
def map = [:]
def csv = csvString.split().collect{ entry -> entry.split(",") }
csv.each{ entry -> map.multiPut(entry[0], entry[1]) }
def result = map.collect{ k, v -> k + ',"' + v.join(",") + '"'}.join("\n")
println result
Would print:
132265,"Brown,Gold,Gray,Green"
122222,"Red,White"
Do you HAVE to use scripting for some reason? This can be easily accomplished with out-of-the-box Boomi functionality.
Create a map function that prepends the ID field to a string of your choice (i.e. 222_concat_fields). Then use that value to set a dynamic process prop with that value.
The value of the process prop will contain the result of concatenating the name fields. Simply adding this function to your map should take care of it. Then use the final value to populate your result.
Well it depends upon the data how is it coming.
If the data which you have posted in the question is coming in a single document, then you can easily handle this in a map with groovy scripting.
If the data which you have posted in the question is coming into multiple documents i.e.
doc1: 132265,Brown
doc2: 132265,Gold
doc3: 132265,Gray
doc4: 132265,Green
In that case it cannot be handled into map. You will need to use Data Process Step with Custom Scripting.
For the code which you are asking to create in groovy depends upon the input profile in which you are getting the data. Please provide more information i.e. input profile, fields etc.

web2py:Grid csv exports shows ids not values for reference fields

Table structure like -
db.define_table('parent',
Field('name'),format='%(name)s')
db.define_table('children',
Field('name'),
Field('mother','reference parent'),
Field('father','reference parent'))
db.children.mother.requires = IS_IN_DB(db, db.parent.id,'%(name)s')
db.children.father.requires = IS_IN_DB(db, db.parent.id,'%(name)s')
Controller :
grid = SQLFORM.grid(db.children, orderby=[db.children.id],
csv=True,
fields=[db.children.id, db.children.name, db.children.mother, db.children.father])
return dict(grid=grid)
Here grid shows proper values i.e names of the mother and father from the parent table.
But when I try to export it via csv link - resulted excelsheet shows ids and not the names of mother and father.
Please help!
The CSV download just gives you the raw database values without first applying each field's represent attribute. If you want the "represented" values of each field, you have two options. First, you can choose the TSV (tab-separated-values) download instead of CSV. Second, you can define a custom export class:
import cStringIO
class CSVExporter(object):
file_ext = "csv"
content_type = "text/csv"
def __init__(self, rows):
self.rows = rows
def export(self):
if self.rows:
s = cStringIO.StringIO()
self.rows.export_to_csv_file(s, represent=True)
return s.getvalue()
else:
return ''
grid = SQLFORM.grid(db.mytable, exportclasses=dict(csv=(CSVExporter, 'CSV')))
The exportclasses argument is a dictionary of custom download types that can be used to override existing types or add new ones. Each item is a tuple including the exporter class and the label to be used for the download link in the UI.
We should probably add this as an option.