class emojiPicker:

	def __init__(self):
		self.setupVariables()
		self.createGui()

		self.loadEmojis()

	def setupVariables(self):
		self.keyboardHeight = 650
		self.keyboardWidth = 1200

		self.categoryClickIndex = 0

		self.colWidth = 100
		self.colHeight = self.keyboardHeight
		self.rowHeight = 120

		self.rowWidth = self.keyboardWidth + 2 * self.colWidth

		#keyboard spacing variables
		self.midRowXOffset = .2
		self.keyboardYOffset = .5

		self.keyboardYSpacing = 1
		self.keyBoardXSpacing = 1

		self.TOOLTIPS = """<div>@names</div>"""
		self.TOOLTIPS =  """<div class="btn-group">
			  <button>@names πŸ”Š</button>
			  <button>Schadenfreude πŸ”Š</button>
			  <button>⻄⻇ πŸ”Š</button>
			</div> """

		# var audio = new Audio('emojiMessenger/static/audio.mp3');
		self.filename = "audio.mp3"
		self.playSound = CustomJS(args=dict(filename = self.filename), code = 
			"""
			var audio = new Audio('emojiMessenger/static/'.concat(filename));
			audio.play();
			"""
			)

	def loadEmojis(self):
		self.sessionId = emojiDber.getSessionId()
		self.friendId = emojiDber.checkForUnmatchedFriendId(self.sessionId)

		#main category
		self.mainCategoryNames = emojiDber.getMasterCategories()[1:]
		mainCategoryIcons = emojiDber.getSubCategoriesIcons("MASTER",self.mainCategoryNames)
		self.updateEmojiFigure("Main","Column",mainCategoryIcons)

		#pick the first main category
		self.activeMainCategory = self.mainCategoryNames[0]
		subCategories = emojiDber.getSubCategories(self.activeMainCategory)
		subCategoryIcons = emojiDber.getSubCategoriesIcons(self.activeMainCategory,subCategories)
		self.updateEmojiFigure("Sub","Column",subCategoryIcons)

		#pick the first subcategory
		self.activeSubCategory = subCategories[0]

		#get suggested emojis
		suggestedEmojis = emojiDber.getRelevantEmojis(self.activeMainCategory)
		self.updateEmojiFigure("Suggested","Row",suggestedEmojis)

		#get emojis to display on the keyboars
		subCategoryEmojis = emojiDber.getCategoryTopEmojis(self.activeSubCategory)

		#fill in the difference with main cateogry emojis
		numSubEmojis = len(subCategoryEmojis)
		mainCategoryEmojies = emojiDber.getCategoryTopEmojis(self.activeMainCategory,NUM_TO_GET = 26 - numSubEmojis)
		keyboardEmojisDict = {**subCategoryEmojis,**mainCategoryEmojies}

		self.updateKeyboardFigure(keyboardEmojisDict)

	def updateEmojiFigure(self,figureName,figureType,emojisDict):
		newData = self.createCategoryGlyphSource(emojisDict,figureType)
		self.gui.select_one({"name":figureName}).data = newData

	def updateKeyboardFigure(self,emojisDict):
		newNames = list(emojisDict.keys())
		newEmojis = list(emojisDict.values())

		numEmojis = len(newNames)
		if numEmojis < 26:
			diff = 26 - numEmojis
			newNames += [""] * diff
			newEmojis += [""] * diff

		keyboardSourceDict = (self.emojiKeyboard.select_one({"name":"emojis"})).data_source.data
		keyboardSourceDict["names"] = newNames
		keyboardSourceDict["text"] = newEmojis
		(self.emojiKeyboard.select_one({"name":"emojis"})).data_source.data = keyboardSourceDict

	def createCategoryGlyphSource(self,categoriesDict,figureType):
		categoryEmojies = list(categoriesDict.values())
		categoryNames = list(categoriesDict.keys())
		numCategories = len(categoriesDict.keys())
		indices = range(1,1+numCategories)

		categoryFills = [0] * numCategories

		categoryXs = [0] * numCategories
		categoryYs = range(numCategories)
		if figureType == "Row":
			categoryXs, categoryYs = categoryYs,categoryXs
		else:
			categoryFills[-1] = 1

		categoryGlyphSourceDict = dict(x=categoryXs, y=categoryYs, text=categoryEmojies,names = categoryNames,fills = categoryFills,indices=indices)
		return categoryGlyphSourceDict

	def createEmojiFigure(self,figureType,name):
		#creates either a row or column to display emojies in
		numCategories = 10
		if figureType == "Column":
			height = self.colHeight
			width = self.colWidth
			xRange = (-.5,.5)
			yRange = (-.5,numCategories-.5)
			yOffset = 20

		else:
			height = self.rowHeight
			width = self.rowWidth
			xRange = (-.5,numCategories-.5)
			yRange = (-.4,.6)
			yOffset = 20

		categoriesFigure = figure(title = "Title",
			plot_height = height, plot_width = width,
			x_range=xRange,y_range=yRange,
			toolbar_location = None,tools = "")

		categoriesFigure.axis.visible = False
		categoriesFigure.grid.visible = False

		categorySourceDict = dict(x=[], y=[], text=[],names = [],fills = [],indices=[])

		# categorySourceDict = self.createCategoryGlyphSource(categoriesDict,figureType)
		categorySource = ColumnDataSource(categorySourceDict,name = name)

		#text glyph to display emojies
		categoriesGlyph = Text(x="x", y="y", text="text", angle=0,y_offset=yOffset,
			text_color="black",text_alpha = 1,
			text_font_size='35pt',text_align = "center")

		categoriesFigure.add_glyph(categorySource, categoriesGlyph)

		if figureType == "Row":
			categoryIndexText =  Text(x="x", y="y", text="indices", angle=0,y_offset=-10,x_offset= -50,
				text_color="black",text_alpha = 1,
				text_font_size='20pt',text_align = "center")
			categoriesFigure.add_glyph(categorySource,categoryIndexText)

		#hidden circle glyph used to allow hovertool to work to show tooltips
		categoryCircleGlyph = Circle(x="x", y="y",radius=.45,fill_alpha = 0,line_alpha = "fills")
		circleGlyph = categoriesFigure.add_glyph(categorySource, categoryCircleGlyph, name = "circles")
		#create hover tool and add it to figure
		categoryHoverer = HoverTool(renderers=[circleGlyph], tooltips=self.TOOLTIPS)
		categoriesFigure.add_tools(categoryHoverer)

		return categoriesFigure

	def mainCategorySelectCallback(self,event):
		self.categoryClickIndex += 1
		x,y = (event.x, event.y)
		index = int(y)

		selectedCategory = self.mainCategoryNames[index]
		self.activeMainCategory = selectedCategory

		#update the selected category indicator		
		newFills = [0] * len(self.mainCategoryNames)
		newFills[index] = 1
		self.gui.select_one({"name":"Main"}).data["fills"] = newFills

		#update sub categories
		subCategories = emojiDber.getSubCategories(self.activeMainCategory)
		subCategoryIcons = emojiDber.getSubCategoriesIcons(selectedCategory,subCategories)
		self.updateEmojiFigure("Sub","Column",subCategoryIcons)

		#pick the first new subcategory
		self.activeSubCategory = subCategories[0]
		subCategoryEmojis = emojiDber.getCategoryTopEmojis(self.activeSubCategory)

		#fill in the difference with main cateogry emojis
		numSubEmojis = len(subCategoryEmojis)
		mainCategoryEmojies = emojiDber.getCategoryTopEmojis(self.activeMainCategory,NUM_TO_GET = 26 - numSubEmojis)
		keyboardEmojisDict = {**subCategoryEmojis,**mainCategoryEmojies}

		self.updateKeyboardFigure(keyboardEmojisDict)

	def subCategorySelectCallback(self,event):
		#keep track of how many categories clicked throiugh until an answer found
		self.categoryClickIndex += 1

		x,y = (event.x, event.y)
		index = int(y)
		subCategoryDict = self.gui.select_one({"name":"Sub"}).data

		#update the selected category indicator		
		newFills = [0] * len(subCategoryDict["fills"])
		newFills[index] = 1
		self.gui.select_one({"name":"Sub"}).data["fills"] = newFills

		#change the active categroy abd get the emojis belonging to it
		self.activeSubCategory = subCategoryDict["names"][index]
		subCategoryEmojis = emojiDber.getCategoryTopEmojis(self.activeSubCategory)

		numSubEmojis = len(subCategoryEmojis.keys())

		mainCategoryEmojies = emojiDber.getCategoryTopEmojis(self.activeMainCategory,NUM_TO_GET = 26 - numSubEmojis)
		keyboardEmojisDict = {**subCategoryEmojis,**mainCategoryEmojies}

		self.updateKeyboardFigure(keyboardEmojisDict)

	def suggestedSelectCallback(self,event):
		x,y = (event.x, event.y)
		index = int(x)
		suggestedEmojis = self.gui.select_one({"name":"Suggested"}).data["text"]

		clickedEmoji = suggestedEmojis[index]

		self.text_input.remove_on_change("value",self.textBoxcallback)
		self.text_input.value += (clickedEmoji)
		self.text_input.on_change("value",self.textBoxcallback)

		self.analyzeNgram(self.text_input.value,"tapped")

	def xyCoordsToKeyboardKey(self,x,y):
		"""given an (X,Y) cooridnate, returns the key pressed
		on a qwerty keyboard"""

		rowIndex = int(y/(self.keyboardYSpacing))
		colIndex = (x-(rowIndex*self.midRowXOffset))/self.keyBoardXSpacing
		clickedLetter = self.letters[int(rowIndex)][int(colIndex)]
		return clickedLetter


	def emojiDoubleTapCallback(self,event):
		#called when an emoji keyboard is double tapped
		#updates the suggested categories, but doesn't add it to the textbox
		print (1)

	def emojiTapCallback(self,event):
		#called when an emoji on the keyboard window is single tapped
		x,y = (event.x, event.y)
		index = int(x) + int(y)
		selectedChar = self.xyCoordsToKeyboardKey(x,y)

		emojiSourceData = (self.emojiKeyboard.select_one({"name":"emojis"})).data_source.data
		letterIndex = emojiSourceData["letters"].index(selectedChar)
		selectedEmoji = emojiSourceData["text"][letterIndex]

		self.text_input.remove_on_change("value",self.textBoxcallback)
		self.text_input.value += (selectedEmoji)
		self.text_input.on_change("value",self.textBoxcallback)

		self.filename = "cats.wav"

		self.analyzeNgram(self.text_input.value,"tapped")


	def analyzeNgram(self,ngram,methodOfEntry):
		#get the current category structure
		heirarchy = [self.activeMainCategory,self.activeSubCategory]

		emojiDber.addEnteredString(
			ENTERED_STRING = ngram,
			ENTRY_METHOD = methodOfEntry,
			CLICK_INDEX = self.categoryClickIndex,
			CATEGORY_STRUCTURE = heirarchy,
			SESSION_ID = self.sessionId)

		#reset category click index
		self.categoryClickIndex = 0

		#get new suggestions
		#split the currently entered string
		splitNgram = list(ngram)
		newSuggestionsDict = {}
		for emoji in splitNgram:
			suggestions = emojiDber.getRelevantEmojisFromEmoji(emoji)
			newSuggestionsDict = {**newSuggestionsDict,**suggestions}

		#get suggested emojis
		self.updateEmojiFigure("Suggested","Row",newSuggestionsDict)

	def createMainEmojiWindow(self):
		plot = figure(title="", plot_width=self.keyboardWidth, plot_height=self.keyboardHeight,
			x_range= (-.5,10-.5),y_range = (0,3*self.keyboardYSpacing),
		    h_symmetry=False, v_symmetry=False, min_border=0,
		    toolbar_location=None,tools = "")

		plot.grid.visible = False
		plot.axis.visible = False

		emojiGlyph = Text(x="x", y="y", text="text", angle=0, 
			text_color="black",text_alpha = 1,text_font_size='65pt',text_align = "center")

		source = self.createKeyboardCoordinates()

		plot.add_glyph(source, emojiGlyph,name = "emojis")

		circleGlyph = Circle(x="x", y="y",radius=.5,fill_alpha = 0,line_alpha = 0)
		circGlypher = plot.add_glyph(source, circleGlyph)

		emojiLetterText =  Text(x="x", y="y", text="letters", angle=0,y_offset=-80,x_offset= -40,
			text_color="black",text_alpha = 1,
			text_font_size='20pt',text_align = "center")
		plot.add_glyph(source,emojiLetterText)

		hoverer = HoverTool(renderers=[circGlypher], tooltips=self.TOOLTIPS)
		plot.add_tools(hoverer)

		plot.on_event(Tap,self.emojiTapCallback)
		# plot.on_event(DoubleTap,self.emojiDoubleTapCallback)

		return plot

	def englishBoxCallback(self,attr,old,new):
		#called when someone types something into the english box,
		#gets the suggested emojis and updates the list

		#check if the new value is drastically longer than the old one (indicating autocomplete)
		if (len(new) - len(old)) > 4:
			print ("CLICKED")
			clickedEmoji = new[-1]

			self.text_input.value += (clickedEmoji)
			self.englishInput.value = ""
			return

		suggestedEmojis = emojiDber.getRelevantEmojis(new)
		emojisList = []
		for name,emoji in suggestedEmojis.items():
			entry = name.replace("_"," ") + "   " + emoji
			emojisList.append(entry)

		self.englishInput.completions = emojisList

	def textBoxcallback(self,attr,old,new):
		if (len(old) > len(new)):
			return
		if not new:
			return

		newChar = new[-1]
		if newChar == " ":
			return

		if newChar.isdigit():
			newEmojiIndex = int(newChar)-1
			newEmoji = (self.gui.select_one({"name":"Suggested"})).data["text"][newEmojiIndex]
			self.text_input.remove_on_change("value",self.textBoxcallback)
			self.text_input.value = new[:-1] + newEmoji
			self.text_input.on_change("value",self.textBoxcallback)

		if newChar.isalpha():
			newCharStr = newChar.lower()
			emojiSourceData = (self.gui.select_one({"name":"emojis"})).data_source.data
			typedEmojiIndex = emojiSourceData["letters"].index(newCharStr)
			newEmoji = emojiSourceData["text"][typedEmojiIndex]
			self.text_input.remove_on_change("value",self.textBoxcallback)
			self.text_input.value = new[:-1] + newEmoji
			self.text_input.on_change("value",self.textBoxcallback)

		self.analyzeNgram(self.text_input.value,"typed")

	def createKeyboardCoordinates(self):
		#rectangle window

		topRowXs, topRowYs = list(range(10)),[2*self.keyboardYSpacing + self.keyboardYOffset]*10
		topRowLetters = ["q","w","e","r","t","y","u","i","o","p"]

		midRowXs, midRowYs = list(np.linspace(self.midRowXOffset,9-self.midRowXOffset,9)), [self.keyboardYSpacing + self.keyboardYOffset]*9
		midRowLetters = ["a","s","d","f","g","h","j","k","l"]

		lowRowXs, lowRowYs = list(np.linspace(2*self.midRowXOffset,7-3*self.midRowXOffset,7)),[self.keyboardYOffset]*7
		lowRowLetters = ["z","x","c","v","b","n","m"]
		self.letters = [lowRowLetters,midRowLetters,topRowLetters]
		xCoords = topRowXs + midRowXs + lowRowXs
		yCoords = topRowYs + midRowYs + lowRowYs
		letters = topRowLetters + midRowLetters + lowRowLetters

		self.numCoords = len(xCoords)

		emojis = [""] * self.numCoords
		names = [""] * self.numCoords
		source = ColumnDataSource(dict(x=xCoords, y=yCoords, text=emojis,names = names,letters = letters))
		return source

	###CHAT BOX 

	def createChatBox(self):
		#creates a datatable to show messages
		data = dict(sender=[],message=[])
		source = ColumnDataSource(data)

		columns = [
		        TableColumn(field="sender", title="From"),
		        TableColumn(field="message", title="Message"),
		    ]

		chatBox = DataTable(source=source, columns=columns,
			width=self.keyboardWidth, height=200)
		return chatBox

	def createMessageWindow(self):
		messageWindow = column([],css_classes=["message-box"],width = self.keyboardWidth - 300,height = 400)
		return messageWindow

	def sendMessage(self):
		#posts a message to the db and clears the text box, updates the chat window
		currentMessage = self.text_input.value

		emojiDber.postEnteredMessage(MESSAGE = currentMessage,SESSION_ID = self.sessionId)
		self.updateChatBox("You",currentMessage)

	def createSentDiv(self,message):
		return Div(text=message,height=30,width=self.keyboardWidth-400,css_classes = ["sent-speech-bubble"])

	def createReceivedDiv(self,message):
		return Div(text=message,height=30,width=self.keyboardWidth-400,css_classes = ["received-speech-bubble"])

	def updateChatBox(self,sender,newMessage):
		if sender == "You":
			newDiv = self.createSentDiv(newMessage)
		else:
			newDiv = self.createReceivedDiv(newMessage)

		self.messageWindow.children.append(newDiv)

		# chatBoxSource = self.chatBox.source.data
		# chatBoxSource["sender"].append(sender)
		# chatBoxSource["message"].append(newMessage)
		# self.chatBox.source.data = chatBoxSource



		self.text_input.value = ""



	def getReceivedMessages(self):
		#check if there's a friend id
		self.friendId = emojiDber.checkForUnmatchedFriendId(self.sessionId)

		#if its not found, return and try again later
		if not self.friendId: return

		unreadMessages = emojiDber.getUnreadMessages(SESSION_ID = self.friendId)

		for message in unreadMessages:
			messageText = message["MESSAGE"]
			messageTime = message["TIMESTAMP"]
			self.updateChatBox("Them",messageText)

			emojiDber.incrementMessageRead(SESSION_ID=self.friendId,TIMESTAMP = messageTime)

	def createGui(self):
		# self.chatBox = self.createChatBox()
		self.messageWindow = self.createMessageWindow()
		headerDiv = Div(text="<link rel='stylesheet' type='text/css' href='templates/styles.css'>")

		self.createKeyboardCoordinates()

		self.englishInput = AutocompleteInput(value = "",title = "English:",completions = ["bath","bathtub"])
		self.englishInput.on_change("value",self.englishBoxCallback)

		self.text_input = TextInput(value="", title="Message:",width = self.keyboardWidth - 300)
		self.text_input.on_change("value",self.textBoxcallback)

		sendButton = Button(label="↩",button_type = "primary")
		sendButton.on_click(self.sendMessage)
		self.suggestedCategoryRow = self.createEmojiFigure("Row","Suggested")
		self.suggestedCategoryRow.on_event(Tap,self.suggestedSelectCallback)

		self.suggestedCategoryRow.title.text = "πŸ’‘"
		self.suggestedCategoryRow.title.text_font_size = "20pt"

		mainCategoryFigure = self.createEmojiFigure("Column","Main")
		mainCategoryFigure.title.text = "πŸ˜πŸ“¦"
		mainCategoryFigure.title.text_font_size = "30pt"
		mainCategoryFigure.on_event(Tap,self.mainCategorySelectCallback)
		mainCategoryFigure.js_on_event(DoubleTap,self.playSound)

		subCategoryFigure = self.createEmojiFigure("Column","Sub")
		subCategoryFigure.title.text = "πŸ₯–πŸ“¦"
		subCategoryFigure.title.text_font_size = "30pt"
		subCategoryFigure.name = "sub"
		subCategoryFigure.on_event(Tap,self.subCategorySelectCallback)

		self.emojiKeyboard = self.createMainEmojiWindow()
		self.emojiKeyboard.title.text = "⌨"
		self.emojiKeyboard.title.text_font_size = "30pt"
		self.gui = column(
			headerDiv,
			self.messageWindow,
			row(self.englishInput,self.text_input,sendButton),
			self.suggestedCategoryRow,
			row(self.emojiKeyboard,subCategoryFigure,mainCategoryFigure)
		)

	def showGui(self):
		curdoc().add_root(self.gui)
		curdoc().add_periodic_callback(self.getReceivedMessages,1000)
		curdoc().on_session_destroyed(self.destroySession)
		curdoc().title = "Emoji Messenger"
		show(self.gui)

	def destroySession(self,session_context):
		emojiDber.deactivateSessionId(self.sessionId,self.friendId)
		print ("Session closed")
Example #2
0
# Set up data table for summary statistics
datatable_columns = [
    TableColumn(field="parameter", title="Parameter"),
    TableColumn(field="value_all", title="All Data"),
    TableColumn(field="value_selection", title="Selected Data"),
]

data_table = DataTable(source=datatable_source,
                       columns=datatable_columns,
                       width=450,
                       height=125,
                       index_position=None)

# callback for updating the plot based on a changes to inputs
station_name_input.on_change('value', update_station)
simulation_number_input.on_change('value', update_n_simulations)
msmt_error_input.on_change('value', update_msmt_error)
sample_size_input.on_change('value', update_simulation_sample_size)
toggle_button.on_click(update_simulated_msmt_error)

# see documentation for threading information
# https://docs.bokeh.org/en/latest/docs/user_guide/server.html

update()

# widgets
ts_plot = create_ts_plot(peak_source, peak_flagged_source)

peak_source.selected.on_change('indices', update_UI)
Example #3
0
index_select.on_change('value', update_index)
index_type_select.on_change('value', update_index)
dt_pckr_start.on_change('value', update_index)
dt_pckr_end.on_change('value', update_index)

# Add Stock Analysis
stock_auto_input = AutocompleteInput(value = '601318', completions = initializer.update_code_list(), title = 'θ‚‘η₯¨δ»£η ')
# DatePciekr
stock_pckr_start = DatePicker(title='开始ζ—₯期', value = date.today() - timedelta(days = 100), min_date = date(2000,1,1), max_date = date.today())
stock_pckr_end = DatePicker(title='θ‚‘η₯¨ζ—₯期', value = date.today(), min_date = date(2000,1,1), max_date = date.today())

stock_select_row = row(stock_auto_input, stock_pckr_start, stock_pckr_end)
stock_layout = column(stock_select_row, create_stock_figure_column(stock_auto_input.value, stock_pckr_start.value, stock_pckr_end.value))

stock_auto_input.on_change('value', update_stock)
stock_pckr_start.on_change('value', update_stock)
stock_pckr_end.on_change('value', update_stock)

# Market Data
# DatePciekr
market_title = Div(text="ζ•΄δ½“εΈ‚εœΊζ¦‚ε†΅", width=120, height=40, margin=[25, 0, 0, 0], style={'font-size': '150%', 'color': 'blue'})
market_pckr_start = DatePicker(title='开始ζ—₯期', value = date.today() - timedelta(days = 100), min_date = date(2000,1,1), max_date = date.today())
market_pckr_end = DatePicker(title='θ‚‘η₯¨ζ—₯期', value = date.today(), min_date = date(2000,1,1), max_date = date.today())
market_select_row = row(market_title, market_pckr_start, market_pckr_end)
market_layout = column(market_select_row, create_market_figure_column(market_pckr_start.value, market_pckr_end.value))

market_pckr_start.on_change('value', update_market)
market_pckr_end.on_change('value', update_market)

# Capital Data
###################################################

text_input = AutocompleteInput(title='Select a sentence',
                               completions=sentences)


def update_sentences(attr, old, new):
    sentence = text_input.value
    ind = [
        j for j, sent in enumerate(source_sentences.data['sentence'])
        if sent == sentence
    ]
    source_sentences.selected.indices = ind


text_input.on_change('value', update_sentences)

###################################################
# ADD RESET BUTTON
###################################################

reset_button = Button(label='ALL WORDS', button_type='primary')
reset_button.js_on_click(
    CustomJS(args=dict(source=source_words_visible, words=source_words, p=p),
             code="""
    p.reset.emit()
    source.data = words.data
"""))

###################################################
# CREATION OF THE LAYOUT
Example #5
0
def recommender_tab_simple(recommender):

    # create a list of divs
    def make_div_list(textlist, max_lines, fmt_str="""%s""", **attribs):
        """create a list of divs containing text to display"""
        divs = []
        for i in range(max_lines):
            if len(textlist) > i:
                divs.append(Div(text=fmt_str % (textlist[i]), **attribs))
            else:
                divs.append(Div(text=fmt_str % (' '), **attribs))
        return divs

    def make_rec_list(titles, max_lines):
        """create a recommendation list of games,
        with a thumbnail, game title, info and Amazon buy links"""
        global games_by_title
        fmt_str1 = """
            <div class="rec-post-container">                
                <div class="rec-post-thumb"><img src="%s" /></div>
                <div class="rec-post-content">
                    <h3 class="rec-post-title">%s<br>
                    <a href="%s" target="_blank">Info</a><span>&nbsp;&nbsp;</span>
                    <a href="%s" target="_blank">Buy on Amazon</a> </h3>
                </div>
            </div>"""
        fmt_str2 = """"""
        divs = []
        for i in range(max_lines):
            # there is a title available for this list slot
            if len(titles) > i:
                divs.append(
                    Div(text=fmt_str1 %
                        (games_by_title['pic_url'].loc[titles[i]], titles[i],
                         'https://boardgamegeek.com/boardgame/' +
                         str(games_by_title['id'].loc[titles[i]]),
                         'https://www.amazon.com/s?k=' +
                         titles[i].replace(' ', '+') + '&i=toys-and-games')))
            # there no title available for this list slot
            else:
                divs.append(Div(text=fmt_str2))
        return divs

    # update the 'liked games' list UI elements
    def update_liked_list(titlelist):
        global max_liked
        ctl_liked_games.children = make_div_list(titlelist,
                                                 max_liked,
                                                 fmt_str=liked_list_fmt,
                                                 render_as_text=False)

    # update the 'recommended games' list UI elements
    def update_recommended_list(titlelist):
        global n_recommendations
        ctl_recommended_games.children = make_rec_list(titlelist,
                                                       n_recommendations)

    def show_searching_message():
        ctl_recommended_games.children = [
            Div(text='<h1>Searching for recommendations...</h1>')
        ]

    # called when a control widget is changed
    def update_preflist(attr, old, new):
        global liked_games
        liked_games.append(ctl_game_entry.value)
        liked_games = list(filter(None, set(liked_games)))
        # get control values
        update_liked_list(liked_games)
        ctl_game_entry.value = ''

    # clear out the list of preferred games
    def reset_preferred_games():
        global liked_games
        liked_games = []
        update_liked_list(liked_games)

    # user wants some recommendations (clicked the rec button)
    def recommend_games():
        global liked_games, recommended_games
        global games_all, n_recommendations, title_list
        global title_list_lower

        # display a "Searching for recommendations..." message
        # Note: Bokeh doesn't do redraw while inside handlers
        show_searching_message()

        # get some default filter parameters:
        weight = []
        minrating = 6.5
        categories = ['Any category']
        mechanics = ['Any mechanism']
        for title in liked_games:
            idx = (np.array(title_list_lower) == title.lower()).nonzero()[0][0]
            info = games_all.iloc[idx, :]
            weight.append(info['weight'])
            categories += info['categories'].split(',')
            mechanics += info['mechanics'].split(',')

        # select a range of weights around the liked game weights
        weightrange = [
            max(1,
                np.min(weight) - 0.25),
            min(5,
                np.max(weight) + 0.25)
        ]

        # get game IDs for titles
        liked_ids = recommender.get_item_title_id(liked_games)

        # select games to search from based on filters:
        recommended_games = recommender.recommend_items_by_pref_list(
            liked_ids,
            num2rec=n_recommendations,
            weightrange=weightrange,
            minrating=minrating,
            categories_include=categories,
            categories_exclude=['Expansion for Base-game'],
            mechanics_include=mechanics,
            mechanics_exclude=[])

        update_recommended_list(recommended_games)

    # NOTE: I'm using globals because I'm running into variable scope
    #  problems with the bokeh handlers. Easiest to declare globals
    global liked_games, recommended_games, games_all
    global n_recommendations, max_liked, title_list, title_list_lower
    global games_by_title

    # layout params
    n_recommendations = 10
    max_liked = 8

    # Format to use for liked list.
    # This needs to be changed to work like rec list
    liked_list_fmt = """<div style="font-size : 14pt; line-height:14pt;">%s</div>"""

    # variables used by the tab
    liked_games = []
    recommended_games = []
    weight_range = [1, 5]
    games_all = recommender.item_data  # use all games for search
    games_by_title = recommender.item_data.set_index('name')

    # list of all game titles
    title_list = games_all['name']
    title_list_lower = [s.lower() for s in title_list]

    # preferred game entry text control
    ctl_game_entry = AutocompleteInput(completions=list(title_list) +
                                       list(title_list_lower),
                                       min_characters=1,
                                       title='Enter some game names you like:')
    ctl_game_entry.on_change('value', update_preflist)

    # reset liked game list button
    ctl_reset_prefs = Button(label='Reset game list',
                             width_policy='min',
                             align='end')
    ctl_reset_prefs.on_click(reset_preferred_games)

    # liked list title
    ctl_liked_list_title = Div(
        text=
        """<div style="font-size : 18pt; line-height:16pt;">Games you like:</div>"""
    )

    # liked game entries
    ctl_liked_games = WidgetBox(
        children=make_div_list(liked_games, max_liked, fmt_str=liked_list_fmt))

    # recommended list title
    ctl_recommended_list_title = Div(
        text=
        """<div style="font-size : 18pt; line-height:16pt;">Games we recommend:</div>"""
    )

    # recommended games list widget
    ctl_recommended_games = WidgetBox(
        children=make_rec_list(recommended_games, n_recommendations))

    # Recommend games button
    ctl_recommend = Button(label='Recommend some games!', width_policy='min')
    ctl_recommend.on_click(recommend_games)

    # controls to select preferred games
    pref_controls = WidgetBox(ctl_liked_list_title, ctl_liked_games,
                              Spacer(min_height=20),
                              ctl_game_entry, ctl_reset_prefs,
                              Spacer(min_height=40), ctl_recommend)

    # recommendation results
    results_controls = WidgetBox(ctl_recommended_list_title,
                                 ctl_recommended_games)

    # Create a row layout
    layout = row(pref_controls, results_controls)

    # Make a tab with the layout
    tab = Panel(child=layout, title='Simple Game Recommender')

    return tab
Example #6
0
def update_air_temp_units(attr, old, new):
    air_temperature_input.value = str(
        u.Quantity(air_temperature_input.value,
                   old).to(new, equivalencies=u.temperature()).value)


air_temp_unit.on_change('value', update_air_temp_units)


def update_material_density(attr, old, new):
    # if the material is changed then update the density
    material_density_input.value = str(get_density(material_input.value).value)


material_input.on_change('value', update_material_density)


def update_detector_density(attr, old, new):
    # if the material is changed then update the density
    detector_density_input.value = str(
        get_density(detector_material_input.value).value)


detector_material_input.on_change('value', update_detector_density)

curdoc().add_root(
    layout(
        [
            [plot],
            [checkbox_group, plot_checkbox_group],
Example #7
0
def recommender_tab_advanced(recommender):
    def make_div_list(textlist, max_lines, fmt_str="""%s""", **attribs):
        """create a list of divs containing text to display"""
        divs = []
        for i in range(max_lines):
            if len(textlist) > i:
                divs.append(Div(text=fmt_str % (textlist[i]), **attribs))
            else:
                divs.append(Div(text=fmt_str % (' '), **attribs))
        return divs

    def make_rec_list(titles, max_lines):
        """create a recommendation list of games,
        with a thumbnail, game title, info and Amazon buy links"""
        global games_by_title
        fmt_str1 = """
            <div class="rec-post-container">                
                <div class="rec-post-thumb"><img src="%s" /></div>
                <div class="rec-post-content">
                    <h3 class="rec-post-title">%s<br>
                    <a href="%s" target="_blank">Info</a><span>&nbsp;&nbsp;</span>
                    <a href="%s" target="_blank">Buy on Amazon</a> </h3>
                </div>
            </div>"""
        fmt_str2 = """"""
        divs = []
        for i in range(max_lines):
            # there is a title available for this list slot
            if len(titles) > i:
                divs.append(
                    Div(text=fmt_str1 %
                        (games_by_title['pic_url'].loc[titles[i]], titles[i],
                         'https://boardgamegeek.com/boardgame/' +
                         str(games_by_title['id'].loc[titles[i]]),
                         'https://www.amazon.com/s?k=' +
                         titles[i].replace(' ', '+') + '&i=toys-and-games')))
            # no title, so fill with blank
            else:
                divs.append(Div(text=fmt_str2))
        return divs

    # update the 'liked games' list UI elements
    def update_liked_list(titlelist):
        global max_liked
        ctl_liked_games.children = make_div_list(titlelist,
                                                 max_liked,
                                                 fmt_str=liked_list_fmt,
                                                 render_as_text=False)

    # update the 'recommended games' list UI elements
    def update_recommended_list(titlelist):
        global n_recommendations
        ctl_recommended_games.children = make_rec_list(titlelist,
                                                       n_recommendations)

    # called when a control widget is changed
    def update_filters(attr, old, new):
        global category_includes, mechanics_includes
        global category_excludes, mechanics_excludes

        category_includes = [
            ctl_category_selection1.labels[i]
            for i in ctl_category_selection1.active
        ]
        category_includes += [
            ctl_category_selection2.labels[i]
            for i in ctl_category_selection2.active
        ]

        mechanics_includes = [
            ctl_mechanics_selection1.labels[i]
            for i in ctl_mechanics_selection1.active
        ]
        mechanics_includes += [
            ctl_mechanics_selection2.labels[i]
            for i in ctl_mechanics_selection2.active
        ]

        # NOTE: this will need to be changed if I ever implement exclude selections!
        if ctl_include_expansions.active:
            category_excludes = []
        else:
            category_excludes = ['Expansion for Base-game']

    # called when a control widget is changed
    def update_preflist(attr, old, new):
        global liked_games
        liked_games.append(ctl_game_entry.value)
        liked_games = list(filter(None, set(liked_games)))
        # get control values
        update_liked_list(liked_games)
        ctl_game_entry.value = ''

    # reset preferred games list
    def reset_preferred_games():
        global liked_games
        liked_games = []
        update_liked_list(liked_games)

    # recommend some games
    def recommend_games():
        global liked_games, recommended_games
        global games_all, n_recommendations, title_list
        global category_includes, mechanics_includes

        # get game IDs for titles
        liked_ids = recommender.get_item_title_id(liked_games)

        # select games to search from based on filters:
        recommended_games = recommender.recommend_items_by_pref_list(
            liked_ids,
            num2rec=n_recommendations,
            weightrange=ctl_game_weight.value,
            minrating=ctl_game_min_rating.value,
            categories_include=category_includes,
            categories_exclude=category_excludes,
            mechanics_include=mechanics_includes,
            mechanics_exclude=mechanics_excludes)

        # show the recommended games
        update_recommended_list(recommended_games)

    # NOTE: I'm using globals because I'm running into variable scope
    #  problems with the bokeh handlers. Easiest to declare globals
    global liked_games, recommended_games, games_all
    global n_recommendations, max_liked, title_list, title_list_lower
    global category_includes, mechanics_includes
    global category_excludes, mechanics_excludes
    global games_by_title

    # layout params
    n_recommendations = 10
    max_liked = 8
    num_check_options = 20

    # Format to use for liked list.
    # This needs to be changed to work like rec list
    liked_list_fmt = """<div style="font-size : 14pt; line-height:14pt;">%s</div>"""

    # variables used by the tab
    games_all = recommender.item_data  # use all games for search
    liked_games = []
    recommended_games = []
    weight_range = [1, 5]
    category_includes = []
    mechanics_includes = []
    category_excludes = []
    mechanics_excludes = []

    # list of all game titles
    title_list = games_all['name']
    title_list_lower = [s.lower() for s in title_list]
    games_by_title = recommender.item_data.set_index('name')

    # preferred game entry text control
    ctl_game_entry = AutocompleteInput(completions=list(title_list) +
                                       list(title_list_lower),
                                       min_characters=1,
                                       title='Enter some game names you like:')
    ctl_game_entry.on_change('value', update_preflist)

    # reset liked game list button
    ctl_reset_prefs = Button(label='Reset game list',
                             width_policy='min',
                             align='end')
    ctl_reset_prefs.on_click(reset_preferred_games)

    # liked list title
    ctl_liked_list_title = Div(
        text=
        """<div style="font-size : 18pt; line-height:16pt;">Games you like:</div>"""
    )

    # liked game entries
    ctl_liked_games = WidgetBox(
        children=make_div_list(liked_games, max_liked, fmt_str=liked_list_fmt))

    # recommended list title
    ctl_recommended_list_title = Div(
        text=
        """<div style="font-size : 18pt; line-height:16pt;">Games we recommend:</div>"""
    )

    # recommended games list widget
    ctl_recommended_games = WidgetBox(
        children=make_rec_list(recommended_games, n_recommendations))

    # Recommend games button
    ctl_recommend = Button(label='Recommend some games!',
                           width_policy='min',
                           align='center')
    ctl_recommend.on_click(recommend_games)

    # game weight slider
    ctl_game_weight = RangeSlider(
        start=1,
        end=5,
        value=(1, 5),
        step=.1,
        title='Game weight range',
        width_policy='min',
    )
    ctl_game_weight.on_change('value', update_filters)

    # min game rating slider
    ctl_game_min_rating = Slider(start=1,
                                 end=10,
                                 value=7,
                                 step=.1,
                                 title='Minimum average rating',
                                 width_policy='min')
    ctl_game_min_rating.on_change('value', update_filters)

    # collect all category and mechanics labels from recommender data
    categories, mechanics = recommender.get_categories_and_mechanics()

    # game category selection
    category_list = ['Any category'] + list(categories['tag'].values)
    ctl_category_selection1 = CheckboxGroup(
        labels=category_list[:int(num_check_options / 2)],
        width_policy='min',
        active=[0])
    ctl_category_selection1.on_change('active', update_filters)
    ctl_category_selection2 = CheckboxGroup(
        labels=category_list[int(num_check_options / 2):num_check_options],
        width_policy='min')
    ctl_category_selection2.on_change('active', update_filters)

    # game mechanism checkbox group
    mechanics_list = ['Any mechanism'] + list(mechanics['tag'].values)
    ctl_mechanics_selection1 = CheckboxGroup(
        labels=mechanics_list[:int(num_check_options / 2)],
        width_policy='min',
        active=[0])
    ctl_mechanics_selection1.on_change('active', update_filters)
    ctl_mechanics_selection2 = CheckboxGroup(
        labels=mechanics_list[int(num_check_options / 2):num_check_options],
        width_policy='min')
    ctl_mechanics_selection2.on_change('active', update_filters)

    # select whether to include expansions
    ctl_include_expansions = CheckboxGroup(labels=['Include game expansions'],
                                           width_policy='min')

    ctl_include_expansions.on_change('active', update_filters)
    # controls to select preferred games
    pref_controls = WidgetBox(
        ctl_liked_list_title,
        ctl_liked_games,
        Spacer(min_height=20),
        ctl_game_entry,
        ctl_reset_prefs,
        Spacer(min_height=5),
    )

    ctl_liked_list_title = Div(
        text=
        """<div style="font-size : 18pt; line-height:16pt;">Game Categories:</div>"""
    )

    filter_controls = WidgetBox(
        row(ctl_game_weight, Spacer(min_width=50), ctl_game_min_rating),
        row(ctl_include_expansions),
        column(
            row(
                Div(text=
                    """<div style="font-size : 18pt; line-height:16pt;">Game Categories:</div>"""
                    ), Spacer(min_width=50), ctl_recommend),
            row(ctl_category_selection1, ctl_category_selection2),
            Spacer(min_height=5),
            Div(text=
                """<div style="font-size : 18pt; line-height:16pt;">Game Mechanics:</div>"""
                ),
            row(ctl_mechanics_selection1, ctl_mechanics_selection2),
        ))

    # recommendation results
    results_controls = WidgetBox(
        ctl_recommended_list_title,
        ctl_recommended_games,
        Spacer(min_height=10),
    )

    # Create a row layout
    layout = row(column(pref_controls, filter_controls), Spacer(min_width=50),
                 results_controls)

    # Make a tab with the layout
    tab = Panel(child=layout, title='Advanced Game Recommender')

    return tab
Example #8
0
                                                                        cat=dd)
    # select gene expression value
    umis = get_umi(anndat, gene)
    # update factor color
    clusters = anndat.obs[dd]
    cats = sorted(clusters.unique().tolist())
    fcmap['transform'].factors = [str(c) for c in cats]
    fcmap['transform'].palette = color_palette[:len(cats)]
    ## update source data
    source.data.update(color=clusters.astype(str).tolist())
    ## update violin
    volin_change(gene, clusters, umis, bins=1000)


### input on change
symbol.on_change('value', lambda attr, old, new: gene_change())
select.on_change('value', lambda attr, old, new: factor_change())

# set up layout
sb = column(symbol, select, message)

series_t = row(t1, t2, sb)
series_u = row(u1, u2, volin)
series_p = row(
    p1,
    p2,
)
layout = column(
    series_t,
    series_u,
    series_p,
Example #9
0
kms.on_change('value',lambda attr,old,new:kmsfunc())

sfms=MultiSelect(title='Subfams',\
                options=[x[0] for x in collections.Counter(ptree.leaf_cds.data['subfamstr']).most_common()],\
                width=150,height=70)
sfms.on_change('value',lambda attr,old,new:sfmsfunc())

tcb=Button(label='CalcTC',width=80,height=40)
tcb.on_click(tcbfunc)
#splist=list(set(ptree.leaf_cds.data['species']))
#splist.sorted(key=ptree.leaf_cds.data['species'])
#acw=AutocompleteInput(title='Organism name',completions=list(set(ptree.leaf_cds.data['species'])),width=200,height=50)
acw=AutocompleteInput(title='Organism name',\
    completions=[x[0] for x in collections.Counter(ptree.leaf_cds.data['species']).most_common()],\
    width=200,height=50)
acw.on_change('value',lambda attr,old,new:acfunc())

accacw=AutocompleteInput(title='Accession',\
    completions=ptree.leaf_cds.data['gbacc'][:],width=200,height=50)
accacw.on_change('value',lambda attr,old,new:accacfunc())


if len(sys.argv)>3:
    preselfpath=os.path.join(os.environ['SCIENCEDIR'],'GHSeqs',ghfam.upper(),sys.argv[3])
    with open(preselfpath,'r') as f:
        preselections=[x.strip() for x in f.readlines()]
        print(preselections)
else:
    preselections=[]

psb=Button(label='Show Presels',width=80,height=40)
    :return: [{"y": ..., "x": ..., "source": ..., "color": ...}, same]
    """
    global source
    defaults = {"x": "start", "source": source}
    y_and_color_based_on_plus_dominance = {
        True: {"1y": "minus", "1c": "#48AFE8", "2y": "plus", "2c": "firebrick"},  # True if plus dominates
        False: {"1y": "plus", "1c": "firebrick", "2y": "minus", "2c": "#48AFE8"},  # False if plus does not dominate
    }
    vmap = y_and_color_based_on_plus_dominance[temp_plus_dominates[provider]]
    return [{"y": "temp_{}_{}".format(provider, vmap["1y"]), "color": vmap["1c"], **defaults},
            {"y": "temp_{}_{}".format(provider, vmap["2y"]), "color": vmap["2c"], **defaults}]


city_picker = AutocompleteInput(value="Tartu", title="\n",
                                completions=list(CITY_MAP))
city_picker.on_change("value", lambda attr, old, new: update())

source = ColumnDataSource(
    data=dict(
        start=[],  # Python datetime objects
        temp_emhi=[],  # All EMHI temperatures - needed for the positioning of cloud-symbols.
        temp_emhi_plus=[],  # EMHI temperatures above 0.
        temp_emhi_minus=[],  # EMHI temperatures below 0.
        precipitation_emhi=[],
        temp_yrno=[],
        temp_yrno_plus=[],
        temp_yrno_minus=[],
        precipitation_yrno=[],
        symbol_yrno=[],  # Cloud-symbols
        symbol_emhi=[]
    )