I'm using RFX (Record Field Exchange) to move data from a ODBC data source to my Recordset object. Numbers are moved with RFX_Int (within DoFieldExchange) and apparently the database NULL (not a value) is mapped to a pseudo null value AFX_RFX_INT_PSEUDO_NULL. Unfortunately this sentinel value is defined as 0x7ee4 or 32484 in decimal. This value lies in the middle of the possible int number range and is a valid number to my application!
Following code part gives a wrong result with records containing the (valid) value 32484 in mainarticle.
std::vector<Article> getArticles() {
std::vector<Article> res;
CArticleRecordset tmp(&con.GetConnectedDB());
tmp.Open();
while (!tmp.IsEOF()) {
if (tmp.m_article.mainarticle == AFX_RFX_INT_PSEUDO_NULL)
tmp.m_article.mainarticle = 0;
res.push_back(tmp.m_article);
tmp.MoveNext();
}
return res;
}
How could I solve this?
The pseudo null values are defined in afxdb_.h (Visual Studio 2010):
#define AFX_RFX_SHORT_PSEUDO_NULL (0x7EE4)
#define AFX_RFX_INT_PSEUDO_NULL (0x7EE4)
#define AFX_RFX_LONG_PSEUDO_NULL (0x4a4d4120L)
#define AFX_RFX_BIGINT_PSEUDO_NULL (0x4a4d4120L)
#define AFX_RFX_BYTE_PSEUDO_NULL 255
RFX_Int is poorly named, it was meant to be used with short integers. Use RFX_Long instead.
Related
I am trying to create a method that will take a list of items with set weights and choose 1 at random. My solution was to use a Hashmap that will use Integer as a weight to randomly select 1 of the Keys from the Hashmap. The keys of the HashMap can be a mix of Object types and I want to return 1 of the selected keys.
However, I would like to avoid returning a null value on top of avoiding mutation. Yes, I know this is Java, but there are more elegant ways to write Java and hoping to solve this problem as it stands.
public <T> T getRandomValue(HashMap<?, Integer> VALUES) {
final int SIZE = VALUES.values().stream().reduce(0, (a, b) -> a + b);
final int RAND_SELECTION = ThreadLocalRandom.current().nextInt(SIZE) + 1;
int currentWeightSum = 0;
for (Map.Entry<?, Integer> entry : VALUES.entrySet()) {
if (RAND_SELECTION > currentWeightSum && RAND_SELECTION <= (currentWeightSum + entry.getValue())) {
return (T) entry.getKey();
} else {
currentWeightSum += entry.getValue();
}
}
return null;
}
Since the code after the loop should never be reached under normal circumstances, you should indeed not write something like return null at this point, but rather throw an exception, so that irregular conditions can be spotted right at this point, instead of forcing the caller to eventually debug a NullPointerException, perhaps occurring at an entirely different place.
public static <T> T getRandomValue(Map<T, Integer> values) {
if(values.isEmpty())
throw new NoSuchElementException();
final int totalSize = values.values().stream().mapToInt(Integer::intValue).sum();
if(totalSize<=0)
throw new IllegalArgumentException("sum of weights is "+totalSize);
final int threshold = ThreadLocalRandom.current().nextInt(totalSize) + 1;
int currentWeightSum = 0;
for (Map.Entry<T, Integer> entry : values.entrySet()) {
currentWeightSum += entry.getValue();
if(threshold <= currentWeightSum) {
return entry.getKey();
}
}
// if we reach this point, the map's content must have been changed in-between
throw new ConcurrentModificationException();
}
Note that the code fixes some other issues of your code. You should not promise to return an arbitrary T without knowing the actual type of the map. If the map contains objects of different type as key, i.e. is a Map<Object,Integer>, the caller can’t expect to get anything more specific than Object. Besides that, you should not insist of the parameter to be a HashMap when any Map is sufficient. Further, I changed the variable names to adhere to Java’s naming convention and simplified the loop’s body.
If you want to support empty maps as legal input, changing the return type to Optional<T> would be the best solution, returning an empty optional for empty maps and an optional containing the value otherwise (this would disallow null keys). Still, the supposed-to-be-unreachable code point after the loop should be flagged with an exception.
I want to have a null-safe comparator, but it does not work:
Comparator<Item> sort_high = (i1, i2)-> Double.compare(i2.getUser().getValue(), i1.getUser().getValue());
items.sort(Comparator.nullsFirst(sort_high));
However, I get a NPE, if item.getUser().getValue() (or item.getUser()) is null.
at Item.lambda$1(Item.java:270)
at java.util.Comparators$NullComparator.compare(Comparators.java:83)
at java.util.TimSort.countRunAndMakeAscending(TimSort.java:355)
at java.util.TimSort.sort(TimSort.java:220)
at java.util.Arrays.sort(Arrays.java:1438)
at java.util.List.sort(List.java:478)
What is wrong?
nullsFirst will take care of null Items ("i1"), but once two valid objects are found, your Comparator is invoked and you need to handle internal null references.
In your case, you could use something like:
items.sort(
Comparator.nullsFirst(
Comparator.comparing(Item::getUser,
Comparator.nullsFirst(Comparator.comparingDouble(User::getValue))
)
)
);
(Assuming getValue() returns a double)
But I hardly recommend such convoluted code.
Comparator.nullsFirst() doesn't mean that any NullPointerException thrown during the compare() method will be caught.
It says rather that a null compared object with always be less than a non null compared object and that if both are null, they are considered equal.
<T> Comparator<T> java.util.Comparator.nullsFirst(Comparator<? super
T> comparator)
Returns a null-friendly comparator that considers null to be less than
non-null. When both are null, they are considered equal. If both are
non-null, the specified Comparator is used to determine the order. If
the specified comparator is null, then the returned comparator
considers all non-null values to be equal.
In your case :
Comparator<Item> sort_high = (i1, i2)-> Double.compare(i2.getUser().getValue(), i1.getUser().getValue());
Compared objects are not null, that is i1 or i2 but fields of them are: i1.getUser() or i2.getUser().
You don't have a good use case for using directly Comparator.nullsFirst().
As workaround, you could use it to compare the User field in your compare() implementation as soon as one of two compared objects present a null User field.
I think that it is a good trade off between handling yourself null case and readability of the code :
private Comparator<User> comparatorUserNullFirst = Comparator.nullsFirst(Comparator.comparingDouble(User::getValue));
Comparator<Item> sortHigh = (i1, i2) -> {
if (i1.getUser() == null || i2.getUser() == null) {
return comparatorUserNullFirst.compare(i1.getUser(), i2.getUser());
}
return Double.compare(i2.getUser().getValue(), i1.getUser().getValue());
};
Another possibility, that is slightly more readable but does not distinguish between an item being null and an item having a user that is null, is the following:
Comparator<Item> sortLow = Comparator.comparing(item -> Optional.ofNullable(item)
.map(Item::getUser)
.map(User::getValue)
.orElse(null),
Comparator.nullsFirst(Comparator.naturalOrder())
);
I have the following code which work fine. I am trying to understand the syntax. The return statement has std::plus<double>(). The double over here has the return value data type. But the function definition has the return type as std::function<double(double, double)> which indicates two double parameters. How do these two relate to each other?
#include <functional>
#include <iostream>
using namespace std;
std::function<double(double, double)> GetFunction()
{
return std::plus<double>();
}
int main()
{
auto operation = GetFunction();
int a = operation(1, 4);
std::cout << std::plus<>{}(1, 4) << '\n';
return 0;
}
There is an implicit conversion from std::plus<double> to std::function<double(double,double)>, because the former has a member call operator double operator()(double, double). See the documentation for std::function constructors.
In std::function<double(double, double)>:
The first double is the return type of the function. You can remember that by realizing that it's on the left, just like in a normal function definition.
The doubles in parentheses are the parameter types of the function, just like in a normal function definition; minus the parameter names. There are 2 since the plus function takes 2 doubles.
This makes sense if you think about it. The plus function/operator is a binary operator, meaning it takes 2 parameters of a type, and returns a single value of the same type. This is why you only need to specify a single type when you write std::plus<double>; the parameters and the return type must be the same type. It would be error prone and useless to force the caller to specify the same type 3 times.
If your question is, why there is only one double in the template parameter of std::plus but three in std::function, then the answer is this:
For std::plus, both parameters and the returntype always have to be the same, so you only have to specify it once.
std::function on the other hand can hold any function like object with any combination of parameters and returntypes, so you have to basically state each of those types individually.
I am trying to convert from processing to processingjs and have something I just can't understand.
In processing the following code returns whichever letter you type in, though in processingjs it just comes back with the keycode value but I need the letter not the code.
String name="";
void setup(){
size(200,200);
}
void draw(){
}
void keyPressed() {
if(key==ENTER) {
name="";
}
else {
name+=key;
println(name);
}
}
After hours of searching and the above answer I've found the answer here peepproject.com/forums/thread/266/view more eloquently than I. Basically the solution is to convert the int to a char() before constructing a String and putting it into an array.
Instead of name += key, try name += key.toString().
Processing's println automatically does type conversion for you, so the char value of PApplet.key gets printed as a letter. JavaScript string concatenation works differently; the integer value of PApplet.key will be appended to the string as an integer and will not automatically be converted to a string. You have to do it manually.
You need to use the char conversion function in Processing and Processing.js:
http://processingjs.org/reference/char_/
The reason why it's displaying as a number is this line:
char x = 97; //supposed to be an 'a'
Does a cast in Java (may require char x = (char)97).
However in processing.js it is executed as:
var x = 97;
Since javascript has dynamic typing. You therefore need to explicitly force type casts such as from int->char.
i am using Visual Studio 2010 C++ Express and i mant to add an item to my ConcurrentDictionary:
i have such code:
String^ key = gcnew String("key");
int value = 123;
myDictionary->AddOrUpdate(key,value,/*WHAT TO ADD HERE?*/);
AddOrUpdate Method takes 3 argument, not like normal Dictionary 2.
Microsoft sites says it takes such arguments:
public:
TValue AddOrUpdate(
TKey key,
TValue addValue,
Func<TKey, TValue, TValue>^ updateValueFactory
)
on microsoft sites i also found code in C#:
cd.AddOrUpdate(1, 1, (key, oldValue) => oldValue + 1);
but it does not work in C++. what i must put as 3rd argument?
The third parameter is a delegate, which in the C# sample code you found is a lambda. However C++/CLI does not support lambdas, so you'd have to do it with a standalone method.
static int UpdateFunc(String^ key, int value)
{
return value + 1;
}
cd->AddOrUpdate("foo", 1, gcnew Func<String^, int, int>(MyClass::UpdateFunc));
However, you said "I want to add an item to my ConcurrentDictionary". There's no simple "add" method, because it's always the case that other thread may have modified the ConcurrentDictionary. Therefore, there are a couple choices for how to put stuff in the dictionary.
AddOrUpdate: Add a value, or modify an existing value if that key already exists. (Passes the current value to a delegate, which returns the modification.)
GetOrAdd: Add a value, or retrieve the existing value if that key already exists. (Doesn't modify the dictionary if the key already exists.)
this[] (Indexer, uses square brackets): Add a value, or replace the existing value with a constant value.
If all you want is a simple 'add', it's probably the square brackets you're interested in.
cd["foo"] = 1;