I'm working on an information system (in C#) that (while my users use it) gathers statistical data on what pieces of information (tables & records) each user is requesting the most, and what parts of the interface he/she uses most. I'm using this statistical data to make the application adaptive to the user's needs, both in the way the interface presents itself (eg: tab/pane-ordering) as in the way of using the frequently viewed information to (eg:) show higher in search results/suggestion-lists.
What i'm looking for is an algorithm/formula to determine the current 'hotness'/relevance of these objects for a specific user. A simple 'hitcounter' for each object won't be sufficient because the user might view some information quite frequently for a period of time, and then moving on to the next, making the old information less relevant. So i think my algorithm also needs some sort of sliding/historical principle to account for the changing popularity of the objects in the application over time.
So, the question is:
Does anybody have some sort of algorithm that accounts for that 'popularity over time' ?
Preferably with some explanation on the parameters :)
Thanks!
PS I've looked at other posts like Popularity algorithm but i could't quite port it to my specific case. Any help is appreciated.
Rather than try and guess what the user wants, why not ask the user to design the layout of the information.
My Yahoo, as an example, allows the user to specify what types of information he or she wants to see, and where on the screen the information is placed.
Your statistical information could be used to make suggestions to the user of where to place the information on the screen. Basically, the system could suggest that the most accessed information over the last month be placed on the upper left. But ideally, each user should decide which layout of the information makes the most sense for him or her.
Related
I am developing a custom Steam bot from scratch that will react to numerous callbacks emitted by Steam, like OnConnected, OnTradeOfferReceived etc. The callbacks contain parameters like IDs or data.
I wish to give the user freedom to define how should the system react when a specified callback is received.
This can be easily solved by forcing the user to manually program the "reacting" parts, but I really wish to avoid that, because a big part of the possible user base are not programmers at its slightest.
The already existing SteamBot on GitHub does this, leading to questions like "how to build SteamBot.sln".
I thought of a GUI for specifying conditions and executing actions if the conditions are true, but I fail to come up with how to parse them in code without going through each and every option.
By actions, I mean replying to a trade offer, sending a chat message to someone, adding an item to a live trade etc.
Maybe the GUI should generate the actual code (based on user's input) and recompile the bot? Any help or suggestions would be appreciated.
I am working on a project for which I must use Sitecore's E-Commerce Module (and Sitecore 6.5 rev. 120706 - aka 'Update 5') to create a web-store. One of the features that I am trying to implement is a generic promotional/discount code system - customer enters a code at checkout which grants a discount like 'free shipping', '20% off', etc. At the moment, I am looking for some guidance (a high-level solution, a few pseudo-ideas, some references to review, etc) as to how this can be accomplished.
Summary:
What I am looking for is a way to detect whether or not the user entered a promo code at a previous stage in the checkout line, and to determine what that promo code is, if they did.
Progress Thus Far:
I have thoroughly reviewed all of the Sitecore E-Commerce Services (SES) documentation, especially "SES Order Line Extension" documentation (which I believe will have to be modified/extended in order to accomplish this task).
Additionally, I have thoroughly reviewed the Sitecore Community article Extending Sitecore E-Commerce - Pricing and believe that it may be a useful guide for applying a discount statically, but does not say much in the way of applying a discount dynamically.
After reviewing these documents, I have come up with the following possible high-level solution to start from:
I create a template to represent a promotional code, which holds all data relevant to the promotion (percent off, free shipping, code, etc).
I then create another template (based on the Product Search Group template) that holds a link to an item within a global "Promotional Code" items folder.
Next, I use the Product Search Group features of my new template to choose which products to apply the discount to.
In the source code for the checkout I create a class that checks if a code has been entered and, if so, somehow carry it through the rest of the checkout process. This is where I get stuck.
More Details:
No using cookies
No GET requests
No changing/creating/deleting items in the Sitecore Database during the checkout process (e.g., no manipulation of fields of a discount item during checkout to signal that the discount has been applied)
must stay within the scope of C#
Last Notes:
I will update this post with any more information that I find/progress that I make.
I upgrade all answers that are relevant and detailed, thought-provoking, or otherwise useful to me and potentially useful to others, in addition to any high-level answers that serve as a feasible solution to this problem; even if your idea doesn't help me, if I think it will help someone else I will still upgrade it.
Thanks, in advance, for all your help! :)
I sent the link to this question around my office and one of my co-workers who doesn't have a Stack Overflow account suggested this high-level solution, which I am posting on his behalf:
If you cannot use cookies then what I would do is post the entered
code back to the server somehow and store it in session.
You could either use an UpdatePanel control or some JS
Please note that THIS IS NOT MY ANSWER and I am still looking for more potential solutions.
I was working with another co-worker who had some experience using SES in the past and he and I managed to find a DiscountCode field in the Sitecore.Ecommerce.Orders namespace. I have not yet found any methods that actually use this field (and I know for a fact that there are none in that particular namespace), but it does demonstrate that the discount code feature is, at least in some small part, built into the module.
Because it is not in the documentation and there are no results in Google that I have found that refer to this, I am going to leave this question up, rather than delete it. I will be accepting the other answer, as it is a good solution, which we will probably be implementing unless we find more treasure in the DLLs.
I have an application that visitors come and go.
I m working with a data provider that gives me information about users such as their gender, age, location, and information about their personalities etc.
Now, i d like to target these users with appropriate content.
In short, I have content and users with their personality information, i need to display the best content that matches their character, personality etc.
I am aware that given a list of content and a user, i will be searching for the best possible content for the user, ie: A* search.
How would you design and implement such application?
Which algorithm(s)/data structures you would use? graphs ? adjacency list? matrix?
I would suggest solving this problem using Bayesian inference.
Bayesian Classifiers
As the problem is currently stated, the only classification of the content that is available is the distribution of the users which have visited it and the characteristics of those users. The joint probability distribution across all user-characteristic dimensions for all users is the classifier for that content.
So how does one use the above information? Given content A with user access distribution B for all users and a target user characteristic profile C, one can compute the probability that the latter user would be interested in content A. If one performs this computation against all content relative to user profile C, one gets a list of interest probability values for all of the content. Sort that list by the probability values to identify the best possible content for the target user.
In many cases, only a subset of user characteristic parameters may be predictive of the value of a given content item to users. This is a common situation for Bayesian classifiers in general and has led to the development of Bayesian networks, which are structured graphs of key variables and their conditional dependencies. Such networks can be modeled via Bayesian inference methods as well.
Bayesian Network Software
The WEKA Data Mining software is an open-source Java library which implements many common classification methods including Bayesian network classifiers, and it is well worth trying out. I can't recommend any specific C# equivalent packages, but a quick web search identified at least one commercial Bayesian package for .NET, Bayes Server.
Recommended Reading
There is a pretty large body of literature surrounding bayesian classifiers, and it is a very sound technique that is use in SPAM filtering, drug discovery, etc. Two books that I can recommend for this are listed below. Bolstad's book is for beginners, while Pearl's book is more advanced.
Bolstad, William M. (2007). Introduction to Bayesian Statistics, Second Edition, John Wiley.
Judea Pearl (2000). Causality: Models, Reasoning, and Inference, Cambridge University Press.
Very interesting question!
You're talking about best possible content. But you didn't mention a measurement. I guess under content you've meant some form of advertisement and “best” means most efficient, i.e. having highest CTR.
So you have a function:
f(gender, age, location, personality, ..., advertisement) -> CTR
Each visit you get fixed gender, age, location, etc. Under fixed I mean: you already have this visitor, you can't vary his age. And you have a parameter that you can change: advertisement. Your goal is to maximize CRT.
Varying advertisements you can gather statistics for CTR under different combinations. Once you have minimal initial knowledge you can try to use optimization theory methods, particularly nonlinear programming to find optimal advertisement parameter for given gender, age, location, etc. Continue to gather CTR statistics to make subsequent decisions more and more precise.
P.S. There was a startup showcase on TechCrunch. They did similar thing and have had fantastic results. So if you will success, think about starting your own business ;)
In informal conversations with our customer service department, they have expressed dissatisfaction with our web-based CSA (customer service application). In a callcenter, calls per hour are critical, and lots of time is wasted mousing around, clicking buttons, selecting values in dropdown lists, etc. What the dirrector of customer service has wistfully asked for is a return to the good old days of keyboard-driven applications with very little visual detail, just what's necessary to present data to the CSR and process the call.
I can't help but be reminded of the greenscreen apps we all used to use (and the more seasoned among us used to make). Not only would such an application be more productive, but healthier for the reps to use, as they must be risking injury doing data entry through a web app all day.
I'd like to keep the convenience of browser-based deployment and preserve our existing investment in the Microsoft stack, but how can I deliver this keyboard-driven ultra-simple greenscreen concept to the web?
Good answers will link to libraries, other web applications with a similar style, best practices for organizing and prioritizing keyboard shortcut data (not how to add them, but how to store and maintain the shortcuts and automatically resolve conflicts, etc.
EDIT: accepted answers will not be mini-lectures on how to do UI on the web. I do not want any links, buttons or anything to click on whatsoever.
EDIT2: this application has 500 users, spread out in call centers around North America. I cannot retrain them all to use the TAB key
I make web based CSR apps. What your manager is forgetting is now the application is MUCH more complex. We are asking more from our reps than we did 15 years ago. We collect more information and record more data than before.
Instead of a "greenscreen" application, you should focus on making the web application behave better. For example,dont have a dropdown for year when it can be a input field. Make sure the taborder is correct and sane, you can even put little numbers next to each field grouping to indicate tab order. Assign different screens/tabs to F keys and denote them on the screen.
You should be able to use your web app without a mouse at all with no loss of productivity if done correctly.
Leverage the use of AJAX so a round trip to the server doesn't change the focus of their cursor.
On a CSR app, you often have several defaults. you should assign each default a button and allow the csr to push 1 button to get the default they want. this will reduce the amount of clicking and mousing around.
Also very important You need to sit with the CSR's and watch them for a while to get a feel for how they use the app. if you haven't done this, you are probably overlooking simple changes that will greatly enhance their productivity.
body { background: #000; color: #0F0; }
More seriously, it's entirely possible to bind keyboard shortcuts to actions in a web app.
You might consider teaching your users to just use the Tab key - that's how I fill out most web forms. Tab to a select list and type out the first few letters of the option I'm attempting to select. If the page doesn't do goofy things with structure and tabindexes, I can usually fill out most web forms with just the keyboard.
As I had to use some of those apps over time, will give my feedback as a user, FWIW, and maybe it helps you to help your users :-) Sorry it's a bit long but the topic is rather close to my heart - as I had myself to prototype the "improved" interface for such a system (which, according to our calculations, saves very nontrivial amounts of money and avoids the user dissatisfaction) and then lead the team that implemented it.
There is one common issue that I noticed with quite a few of CRMs: there is 20+ fields on the screen, of which typically one uses 4-5 for performing of 90% of operations. But one needs to click through the unnecessary fields anyway.
I might be wrong with this assumption, of course (as in my case there was a wide variety of users with different functions using the system). But do try to sit down with the users and see how they are using the application and see if you can optimize something UI-wise - or, if really it's a matter of not knowing how to use "TAB" (and they really need to use each and every of those 20 fields each time) - you will be able to coach a few of them and check whether this is something sufficient for them - and then roll out the training for the entire organization. Ensure you have the intuitive hotkey support, and that if a list contains 2000 items, the users do not have to scroll it manually to find the right one, but rather can use FF's feature to select the item by typing the start of its text.
You might learn a lot by looking at the usage patterns of the application and then optimizing the UI accordingly. If you have multiple organizational functions that use the system - then the "ideal UI" for each of them might be different, so the question of which to implement, and if, becomes a business decision.
There are also some other little details that matter for the users - sometimes what you'd thought would be the main input field for them in reality is not - and they have an empty textarea eating up half of the screen, while they have to enter the really important data into a small text field somewhere in the corner. Or that in their screen resolution they need the horizontal scrolling (or, scrolling at all).
Again, sitting down with the users and observing should reveal this.
One more issue: "Too fast developer hardware" phenomenon: A lot of the web developers tend to use large displays with high resolution, showing the output of a very powerful PCs. When the result is shown on the CSR's laptop screen at 1024x768 of a year-old laptop, the layout looks quite different from what was anticipated, as well as the rendering performance. Tune, tune, tune.
And, finally - if your organization is geographically disperse, always test with the longest-latency/smallest bandwidth link equivalent. These issues are not seen when doing the testing locally, but add a lot of annoyance when using the system over the WAN. In short - try to use the worst-case scenario when doing any testing/development of your application - then this will become annoying to you and you will optimize its use - so then the users that are in better situation will jump in joy over the apps performance.
If you are in for the "green screen app" - then maybe for the power users provide a single long text input field where they could type all the information in the CLI-type fashion and just hit "submit" or the ENTER key (though this design decision is not something to be taken lightly as it is a lot of work). But everyone needs to realize that "green-screen" applications have a rather steep learning curve - this is another factor to consider from the business point of view, along with the attrition rate, etc. Ask the boss how long does the typical agent stay at the same place and how would the productivity be affected if they needed a 3-month term to come to full speed. :) There's a balance that is not decided by the programmers alone, nor by the management alone, but requires a joint effort.
And finally a side note in case you have "power users": you might want to take a look at conkeror as a browser - though fairly slow in itself, it looks quite flexible in what it can offer from the keyboard-only control perspective.
I can't agree with the others more when they say the first priority of the redesign should be going and talking to / observing your users and see where they have problems. I think you would see far more ROI if you find out the most common tasks and the most common errors your users make and streamline those within the bounds of your existing UI. I realize this isn't an easy thing to do, but if you can pull it off you'll have much happier users (since you've solved their workflow issues) and much happier bosses (since you saved the company money by not having to re-train all the users on a completely new UI).
After reading everyone else's answers and comments, I wanted to address a few other things:
EDIT: accepted answers will not be mini-lectures on how to do UI on the web. I do not want any links, buttons or anything to click on whatsoever.
I don't mean to be argumentative, but this sounds like you've already made up your mind without having thought of the implications on the users. I can immediately see a couple pitfalls with this approach:
A greenscreen-esque UI may not be
more productive for your users. For
example, what's the average age of
your users? Most people 25 and
younger have had little to no
exposure to these types of UIs.
Suddenly imposing this sort of
interface on them could cause a
major backlash from your users. As an example, look at what happened
when Facebook decided to change its
UI to the "stream" concept - huge
outrage from the users!
The web wasn't really designed with this sort of interface in mind. What I mean is that people are not used to having command-line-like interfaces when they visit a website. They expect visual medium (images, buttons, links, etc.) in addition to text. Changing too drastically from this could confuse your users.
Programming this type of interface will be tough. As in my last point, the web doesn't play well with command-line-like or text-only interfaces. Things like function keys, keyboard shortcuts (like ctrl- and alt-) are all poorly and inconsistently supported which means you'll have to come up with your own ways of accessing standard things like help (since F1 will map to the web browser's help, not your app's).
EDIT2: this application has 500 users, spread out in call centers around North America. I cannot retrain them all to use the TAB key
I think this argument is really just a strawman. If you are introducing a wholly new UI, you're going to have to train your users on it. Really, it should be assumed that any change to your UI will require training in one form or another. Something simple like adding tab-navigation to the UI is actually comparatively small in the training department. If you did this it would be very easy to send out a "handy new feature in the UI" email, or even better, have some sort of "tip of the day" (that users can toggle off, of course) which tells them about cool timesaving features like tab navigation.
I can't speak for the other posters here, but I did want to say that I hope you don't think we're being too argumentative here as that's not our (well OK, my) intent. Rather the reaction comes from us hearing the idea for your UI and not being convinced that it is necessarily the best thing for your users. You are fully welcome to say I'm wrong and that this is what your users will benefit most from; but before you do, just remember that at the end of the day it's your users who matter most and if they don't buy in to your new UI, no one will.
It's really more of a keyboard-centric mentality when developing. I use the keyboard for as much as possible and the apps I build tend to show that (so I can quickly go through my use cases).
Something as simple as getting the tab order correct could be all your app needs (I guess I'm not sure if you can set this in ASP.NET...). A lot of controls will auto-complete for the rest.
This was a hard question for me to summarize so we may need to edit this a bit.
Background
About four years ago, we had to translate our asp.net application for our clients in Mexico. Extensibility and scalability were not that much of a concern at the time (oh yes, I just said those dreadful words) because we only have U.S. and Mexican customers.
Rather than use resource files, we replaced every single piece of static text in our application with some type of server control (asp.net label for example). We store each and every English word in a SQL database. We have added the ability to translate the English text into another language and also can add cultural overrides. For example, hello can be translated to ¡hola! in one language and overridden to ¡bueno! in a different culture. The business has full control over these translations because will built management utilities for them to control everything. The translation kicks in when we detect that the user has a browser culture other than en-us. Every form descends from a base form that iterates through each server control and executes a translation (translation data is stored as a datatable in an application variable for a culture). I'm still amazed at how fast the control iteration is.
The problem
The business is very happy with how the translations work. In addition to the static content that I mentioned above, the business now wants to have certain data translated as well. System notes are a good example of a translation they want. Example "Sent Letter #XXXX to Customer" - the business wants the "Sent Letter to Customer" text translated based on their browser culture.
I have read a couple of other posts on SO that talk about localization but they don't address my problem. How do you translate a phrase that is dynamically generated? I could easily read the English text and translate "Sent", "Letter", "to" and "Customer", but I guarantee that it will look stupid to the end user because it's a phrase. The dynamic part of the system-generated note would screw up any look-ups that we perform on the phrase if we stored the phrase in English, less the dynamic text.
One thought I had... We don't have a table of system generated note types. I suppose we could create one that had placeholders for dynamic data and the translation engine would ignore the placeholder markers. The problem with this approach is that our SQL server database is a replication of an old pick database and we don't really know all the types of system generated phrases (They are deep in the pic code base, in subroutines, control files, etc.). Things like notes, ticklers, and payment rejection reasons are all stored differently. Trying to normalize this data has proven difficult. It would be a huge effort to go back and identify and change every pick program that generated a message.
This question is very close; but I'm not dealing with just system-generated status messages but rather an infinite number of phrases and types of phrases with no central generation mechanism.
Any ideas?
The lack of a "bottleneck" -- what you identify as the (missing) "central generation mechanism" -- is the architectural problem in this situation. Ideally, rearchitecting to put such a bottleneck in place (so you can keep using your general approach with a database of culture-appropriate renditions of messages, just with "placeholders" for e.g. the #XXXX in your example) would be best.
If that's just unfeasible, you can place the "bottleneck" at the other end of the pipe -- when a message is about to be emitted. At that point, or few points, you need to try and match the (English) string that's about to be emitted with a series of well-crafted regular expressions (with "placeholders" typically like (.*?)...) and thereby identify the appropriate key for the DB lookup. Yes, that still is a lot of work, but at least it should be feasible without the issues you mention wrt old translated pick code.
We use technique you propose with insertion points.
"Sent letter #{0:Letter Num} to Customer {1:Customer Full Name}"
Which might be (in reverse Pig Latin, say):
"Ustomercay {1:Customer Full Name} asway entsay etterlay #{0:Letter Num}"
Note that this handles cases where the particular target langue reverses the order of insertion etc. It does not handle subtleties like first, second, etc, which have to be handled with application logic/more phrases:
"This is your {0:first, second, third} warning"
In a pinch I suppose you could try something like foisting the job off onto Google if you don't have a translation on hand for a particular phrase, and stashing the translation for later.
Stashing the translations for later provides both a data collection point for building a message catalog and a rough (if sometimes laughably wonky) dynamically built starter set of translations. Once you begin the process, track which translations have been reviewed and how frequently each have been hit. Frequently hit machine translations can then be reviewed and refined.
Dynamic machine translation is not suitable for a product that you actually expect people to pay money for. The only way to do it is with static templates containing insertion points (as Cade Roux has demonstrated in his answer).
There's no getting around a thorough refactoring of your code to make this feasible. The alternative is to do nothing with those phrases (which is what you're doing now, and it's working out okay, right?). Usually no translation is better than embarrassingly bad translation.