I have written a simple Proof-of-Concept application to test out autocomplete fields using Oracle ADF, and although it mostly works the maxSuggestedItems attribute doesn't seem to have any effect. Oracle's documentation indicates that putting a value other than -1 should limit the list of values returned and include a "More..." item at the bottom that will cause the entire list to be returned. Instead, the entire list is always returned.
Is this something I have to implement manually? If so, how would one approach that?
The JSFF page has the following code in it:
<af:inputText label="Accessories:" id="it4">
<af:autoSuggestBehavior suggestItems="#{accessorySuggest.onAccessorySuggest}"
maxSuggestedItems="5"/>
</af:inputText>
The method which returns the suggested values (all hard-coded of course) is as follows:
private static final String[] accessories =
{ "Alloy Wheel", "All-Weather Cargo/Trunk Mat", "All-Weather Floor Mats",
"Audio Unit - Base", "Audio Unit - Premium", "Auto-Dimming Mirror",
"Bluetooth", "Body Side Moldings", "Capert Floor Mats - Premium",
"Car Cover", "Cargo Hooks", "Cargo Liner", "Suggestion 1",
"Suggestion 2", "Suggestion 3", "Suggestion 4", "Suggestion 5",
"Suggestion 6", "Suggestion 7", "Suggestion 8", "Suggestion 9",
"Suggestion 10", "Suggestion 11", "Suggestion 12", "Suggestion 13",
"Suggestion 14", "Suggestion 15", "Suggestion 16", "Suggestion 17",
"Suggestion 18", "Suggestion 19", "Suggestion 20", "Suggestion 21",
"Suggestion 22", "Suggestion 23", "Suggestion 24", "Suggestion 25",
"Suggestion 26", "Suggestion 27", "Suggestion 28", "Suggestion 29",
"Suggestion 30" };
public List onAccessorySuggest(FacesContext context,
AutoSuggestUIHints hints) {
ArrayList<SelectItem> suggestItems = new ArrayList<SelectItem>();
String submittedValue = hints.getSubmittedValue();
//don't return anything until the user has entered at least 3 characters
if(hints.getSubmittedValue().length() < 3) {
return suggestItems;
}
for (String s : accessories) {
if (s.toUpperCase().startsWith(submittedValue.toUpperCase())) {
suggestItems.add(new SelectItem(s));
}
}
return suggestItems;
}
see http://jdevadf.oracle.com/adf-richclient-demo/docs/apidocs/oracle/adf/view/rich/model/AutoSuggestUIHints.html
Actually its is your implementation that should access and consider the max suggest items value passed in. The only use case for which this may work out-of-the-box is if the suggest list is coming from a model driven LOV list in ADF BC
So in summary, you access the max items from AutoSuggestUIHints an dshorten your return list
Frank
Related
Can we change the sequence of json items?
For example:
[
{
"category": "Science: Mathematics",
"type": "multiple",
"difficulty": "medium",
"question": "In a complete graph G, which has 12 vertices, how many edges are there?",
"correct_answer": "66",
"incorrect_answers1": "67",
"incorrect_answers2 : "34",
"incorrect_answers3 : "11"
},
{
"category": "Science: Mathematics",
"type": "multiple",
"difficulty": "medium",
"question": "In base 2, what is 1 + 1?",
"incorrect_answers1": "2",
"incorrect_answers2 : "01",
"correct_answer": "10",
"incorrect_answers3 : "11"
},
{
"category": "Science: Mathematics",
"type": "multiple",
"difficulty": "medium",
"question": "In the hexadecimal system, what number comes after 9?",
"incorrect_answers1": "10",
"incorrect_answers2 : "The Number 0",
"correct_answer": "The Letter A",
"incorrect_answers3 : "16"
}
]
As mentioned in the comments that re-ordering JSON data is impossible and also not required.
For the current situation, you have to loop across the parent array containing the JSON objects, create a local array variable to get the list of re-ordered answers, push all the answers to this array and shuffle it using a library like lodash (https://lodash.com/docs/#shuffle) or a custom random functions, whatever works for your needs.
You can place this array within each object of this JSON while looping and give it a meaningful key like shuffled_answers.
So now your item structure will look like this:
{
"category": "Science: Mathematics",
"type": "multiple",
"difficulty": "medium",
"question": "In base 2, what is 1 + 1?",
"incorrect_answers1": "2",
"incorrect_answers2" : "01",
"correct_answer": "10",
"incorrect_answers3" : "11",
"shuffled_answers": ["2", "11", "10", "11"]
}
You can then use this array to display answer choices in your UI to ask user the question and use the correct_answer key to compare the correct answer from the user's choice.
I'm linking here a video tutorial for a very similar App developed in Vue using the above logic. You can refer for more insight about apps like these and use it for your requirements.
Hope that helps.
Okay, I'm a bit new to JSON in Discord.js Bot Development, And I'm currently making a command where it grabs all of the data in a json file and splits it so it looks nicely formatted.
Currently have:
let Games = {
"1": "Jailbreak",
"2": "Adopt Me",
"3": "Bubble Gum Simulator",
"4": "Thick Legends",
"5": "Arsenal",
"6": "Legends Of Speed",
"7": "Speed Champions",
"8": "Build A Boat For Treasure",
"9": "Boxing Simulator",
"10": "Flight Simulator",
"11": "Mad City",
"12": "Redwood Prison",
"13": "Horrific Housing",
"14": "Welcome To Bloxburg",
"15": "Tower Of Hell"
}
function getGames(lol) {
lol = JSON.parse(Games[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]);
for (let j in lol) {
return "• " + lol[j];
}
}
I want to group all of the Games and make it output:
"• example\n"
Any answers?
You can get all object values, use map to add • and join it with '\n'.
Like this:
let Games = {
"1": "Jailbreak",
"2": "Adopt Me",
"3": "Bubble Gum Simulator",
"4": "Thick Legends",
"5": "Arsenal",
"6": "Legends Of Speed",
"7": "Speed Champions",
"8": "Build A Boat For Treasure",
"9": "Boxing Simulator",
"10": "Flight Simulator",
"11": "Mad City",
"12": "Redwood Prison",
"13": "Horrific Housing",
"14": "Welcome To Bloxburg",
"15": "Tower Of Hell"
}
console.log(getGames(Games))
function getGames(gameList) {
return Object.values(gameList).map(game => `• ${game}`).join('\n')
}
Live example
let Games = {
"1": "Jailbreak",
"2": "Adopt Me",
"3": "Bubble Gum Simulator",
"4": "Thick Legends",
"5": "Arsenal",
"6": "Legends Of Speed",
"7": "Speed Champions",
"8": "Build A Boat For Treasure",
"9": "Boxing Simulator",
"10": "Flight Simulator",
"11": "Mad City",
"12": "Redwood Prison",
"13": "Horrific Housing",
"14": "Welcome To Bloxburg",
"15": "Tower Of Hell"
}
console.log(getGames(Games))
function getGames(gameList) {
return Object.values(gameList).map(game => `• ${game}`).join('\n')
}
You can get an array of the object values with Object.values()
let gamenames = Object.values(games)
Then,you can loop through the array elements to add them to a string.
let myString = "List: \n"
gamenames.forEach((val) => {
myString += `• ${val} \n`
})
myString is now equal to an organized list of the games! It should look like:
List:
• Jailbreak
• Adopt me
...etc..
(The list does put every single value on a seperate line,but StackOverflow doesn't want to show them properly for some reason)
Hope this helped! If it did,please mark my question as a valid answer.
I'm testing a Node.js application, in which addresses are stored in a Postgresql database using Sequelize. In order to test the 'getAll()' function, I wrote a test that does the following (see below):
1. create two addresses, and store them ('create' function of Sequelize)
2. call the getAll() function
3. (try to) assert that the returned array contains the created addresses, using expect.arrayContaining()
I tested the same setup without Sequelize in between (adding numbers/objects to an array and match a subset in the same way I did here), which works fine.
it("Should get all addresses", async () => {
const address_1 = await Address.create({
street: VALID_STREET,
number: VALID_NUMBER,
city: VALID_CITY,
country: VALID_COUNTRY
});
const address_2 = await Address.create({
street: "street 2",
number: "2",
city: "City 2",
country: "Country 2"
});
const allAddresses = await controller._getAll();
expect(allAddresses).toEqual(
expect.arrayContaining([address_1, address_2])
);
});
I expected the test to succeed, but it fails, giving me this errormessage that contains the two exact same arrays, except for the 'ArrayContaining' part.
expect(received).toEqual(expected) // deep equality
Expected: ArrayContaining [{"city": "A city", "country": "Belgium", "createdAt": 2019-08-21T14:05:23.063Z, "fullAddress": "valid street 123 A, A city, Belgium", "id": 296, "number": "123 A", "postalCode": null, "street": "valid street", "updatedAt": 2019-08-21T14:05:23.063Z}, {"city": "City 2", "country": "Country 2", "createdAt": 2019-08-21T14:05:23.066Z, "fullAddress": "street 2 2, City 2, Country 2", "id": 297, "number": "2", "postalCode": null, "street": "street 2", "updatedAt": 2019-08-21T14:05:23.066Z}]
Received: [{"city": "A city", "country": "Belgium", "createdAt": 2019-08-21T14:05:23.063Z, "fullAddress": "valid street 123 A, A city, Belgium", "id": 296, "number": "123 A", "postalCode": null, "street": "valid street", "updatedAt": 2019-08-21T14:05:23.063Z}, {"city": "City 2", "country": "Country 2", "createdAt": 2019-08-21T14:05:23.066Z, "fullAddress": "street 2 2, City 2, Country 2", "id": 297, "number": "2", "postalCode": null, "street": "street 2", "updatedAt": 2019-08-21T14:05:23.066Z}]
So, does anyone know how to fix this? Is this a Sequelize problem, or am I missing something here?
EDIT:
For people running into the same problem, I do have a workaround, which is to use the array.some() function, but this seems to be too verbose and I feel like the expect.arrayContaining() function should be used for this purpose.
expect(
allAddresses.some(address => {
address.id === address_2.id &&
address.street === address_2.street &&
address.number === address_2.number &&
address.city === address_2.city &&
address.country === address_2.country;
})
);
I think it's not a good idea to compare the whole Models (lot's of stuff you don't care about in there). Try to compare the dataValues instead. Make sure you don't use raw: true in your findAll call because then you don't have the dataValues property.
const allAddresses = await controller._getAll();
const addressesPlain = allAddresses.map(address => address.dataValues);
expect([address_1.dataValues, address_2.dataValues]).toEqual(addressesPlain);
If you're interested in the small test case I wrote: https://pastr.io/view/QKNmua
Another way to do it using arrayContaining matcher, not any better just a little more explicit IMO:
const allAddresses = await controller._getAll();
const addressesPlain = allAddresses.map(address => address.dataValues);
expect(addressesPlain).toEqual(expect.arrayContaining([address_1.dataValues, address_2.dataValues]);
I've found that searching for a single item in an array to be a little confusing using jest's matchers as well so for just checking that a single object is in an array this has been useful:
expect(addressesPlain).toContainEqual(address_1.dataValues)
toContainEqual, as their docs state, "recursively checks the equality of all fields, rather than checking for object identity." while toContain does check for objectIdentity which will fail with the above check.
I'm new to programming (especially JSON format), so please forgive me not for using proper terminology :)
Using Python 3.7 Requests module, I receive a JSON response. To keep things simple, I made an example:
{
"Bob":
{
"Age": "15",
"LastExamGrade": "45",
},
"Jack":
{
"Age": "16",
"LastExamGrade": "58",
}
}
What I would like to do is parse the JSON responses to extract two items from each response/structure and save it to a list like this (I think this is called a tuple of tuples?):
[("Bob","45"),("Jack","58")]
Then, after receiving doing this, I will receive another similar response, such as the following (where the only thing that changed is the exam grade):
{
"Bob":
{
"Age": "15",
"LastExamGrade": "54",
},
"Jack":
{
"Age": "16",
"LastExamGrade": "70",
}
}
I want to also save the name and grade into a tuple of tuples (list).
Lastly, I would like to subtract the first exam score of each person from their last exam score, and save this into a final list, which includes the name, final exam grade, and grade improvement, like this:
[("Bob","54","9"),("Jack","67","12")]
What is the simplest way to do this using Python 3? As for my own research, I've searched all throughout StackOverflow, but couldn't find out how to parse a JSON like mine (For example, in mine, the name is outside of the curly braces), and had difficulty doing math operations for JSON items.
I'd recommend using a dedicated package for calculations like pandas:
first_exam_grades = pd.DataFrame.from_dict(first_exam_results, orient='index').astype(int)
second_exam_grades = pd.DataFrame.from_dict(second_exam_results, orient='index').astype(int)
improvements = second_exam_grades.LastExamGrade.to_frame()
improvements['Improvement'] = second_exam_grades.LastExamGrade - first_exam_grades.LastExamGrade
This will give you something that looks like this:
Now you can output it anyway you'd like
list(zip(*([improvements.index.tolist()] + [improvements[c].values.tolist() for c in improvements])))
This will give you [('Bob', 54, 9), ('Jack', 70, 12)] as you want.
One possible solution, using coroutines. Coroutine receive_message holds up to last two values LastExamGrade from the message for each student and produces list of student name, last grade and improvement over last grade:
json_messages = [
# 1st message:
{
"Bob":
{
"Age": "15",
"LastExamGrade": "45",
},
"Jack":
{
"Age": "16",
"LastExamGrade": "58",
}
},
# 2nd message
{
"Bob":
{
"Age": "15",
"LastExamGrade": "54",
},
"Jack":
{
"Age": "16",
"LastExamGrade": "70",
}
},
# 3nd message (optional)
{
"Bob":
{
"Age": "15",
"LastExamGrade": "14",
},
"Jack":
{
"Age": "16",
"LastExamGrade": "20",
}
}
]
def receive_message():
d, message = {}, (yield)
while True:
for k, v in message.items():
d.setdefault(k, []).append(v['LastExamGrade'])
d[k] = d[k][-2:] # store max last two messages
message = yield [(k, *tuple(v if len(v)==1 else [v[1], str(int(v[1])-int(v[0]))])) for k, v in d.items()]
receiver = receive_message()
next(receiver) # prime coroutine
for msg in json_messages:
print(receiver.send(msg))
Prints:
[('Bob', '45'), ('Jack', '58')]
[('Bob', '54', '9'), ('Jack', '70', '12')]
[('Bob', '14', '-40'), ('Jack', '20', '-50')]
How can I use parsed data from the data.rb file in the main.rb file ?
I'm trying to count the number of times the year "2017" occurs, and how many times "2014" occurs.
I want to return both counts to the method count_years which is in main.rb. How is this properly done?
main.rb
def count_years
File.open('data.rb'))[:phone_data]
if :phone_data."Year" == 2017
year_2017.count #new variable year_2017
end
if :phone_data."Year" == 2014
year_2014.count #new variable year_2014
end
end
data.rb
let(:phone_data) {
JSON.parse('[
{
"Phone": "iPhone 6",
"Year": "2014"
},
{
"Phone": "iPhone 7",
"Year": "2016"
},
{
"Car": "iPhone 8",
"Year": "2017"
},
{
"Car": "Galaxy S8",
"Year": "2017"
}
]')
}
main.rb
The data.rb file is set up to be used by RSpec. Even in that context, it's a little awkward. I would move the JSON data to JSON file and then you can access it from both places. There are other options as well but I would need to know more about your application and how and where you're using this data.
data.json:
[
{
"Phone": "iPhone 6",
"Year": "2014"
},
{
"Phone": "iPhone 7",
"Year": "2016"
},
{
"Car": "iPhone 8",
"Year": "2017"
},
{
"Car": "Galaxy S8",
"Year": "2017"
}
]
data.rb:
require 'json'
let(:phone_data) {
JSON.parse(File.read('data.json'))
}
main.rb:
require 'json'
def count_years
JSON.parse(File.read('data.json'))
.group_by { |h| h['Year'] }
.map { |year, entries| [year, entries.size] }
.to_h
end
The method will return a hash where the keys are the years and the values are the counts:
count_years # => {"2014"=>1, "2016"=>1, "2017"=>2}