I have a function that looks similar to this:
def some_function(self, case, index):
with threading.Lock:
return{
'case1':function1(index),
'case2':function2(index)
}[case]
And elsewhere this function is being called as such:
for i in range(4)
self.module.some_function('case1', i)
Which should iterate function1 for indices within the specified range. Instead, both function1 and function2 are iterated for the indices. Is there a problem with the implementation above? What could be causing both function1 and function2 to be called when only a single key is given?
Indeed, this dict literal expression is evaluated first:
{
'case1':function1(index),
'case2':function2(index)
}
and only then the key you specify after it, is selected from it, but at that time the two functions have already executed.
So, you should do it differently: first the correct function must be selected using the case variable, and only after that selection the function should be executed by passing the argument to it.
There are several solutions, but here is one:
return [function1, function2][case == 'case2'](index)
Or with a dict literal:
return {
'case1': function1,
'case2': function2
}[case](index)
Or with an inline if:
return function1(index) if case == 'case1' else function2(index)
Or avoiding the repetition of (index):
return (function1 if case == 'case1' else function2)(index)
Or you can use a plain if:
if case == 'case1':
return function1(index)
return function2(index)
Related
I am writing a Function with 2 Parameters, 1st is integer type marked [[maybe_unused]] and 2nd is Boolean Type with Default Argument false.
int preOrderTraversial([[maybe_unused]] int searchData, bool forDisplay = false)
This is the function declaration. The function is used for pre-order Traversal in Binary Search Tree. I want to use the same function for Displaying the Tree and Traversing it for searching a Node with specific Data. But only for 1 of both problems at once. Not for searching AND displaying you see.
So, obviously, it works fine for the searching part but when I call the function for Displaying the function call looks like this:
preOrderTraversal(true)
or
bool forDisplay = true;
preOrderTraversal(forDisplay);
Now the Compiler (even with the parameter DECLARED as a BOOL) still considers this bool parameter as an int and uses it for searchData (integer) parameter of the function and not for the forDisplay (bool) parameter.
Is there a way to force or tell compiler which of both parameters I am trying to work with?
[[maybe_unused]] means that the function body may not use it, but the signature of the function always have it. Actually event the default value for the boolean does not modify the signature of your function; Thus your function always take 2 arguments, the first being a integer, and the second being a boolean (that may be set to the default if you didn't put it). You end up with calling:
bool forDisplay = true;
preOrderTraversal(/* integer searchData; bool geting casted to int */ forDisplay,
false /* the forDisplay (2nd param) default value*/);
which does not meet your expectations.
[EDIT]
how to overcome?
There is not builtin way to use named parameters in C++ but you may workaround using a helper class:
struct PreOrderTraversal {
bool _forDisplay = false;
int _searchData = 0; /* FIXME What is the default here? */
auto& forDisplay() { _forDisplay = true; return *this; }
auto& searchData(int x) { _searchData = x; return *this; }
void run() { if (_forDisplay) ;//do the right things
else ;// use data
}
};
then you can use it with:
PreOrderTraversal().forDisplay().run();
PreOrderTraversal().searchData(123).run();
This kinda mimics that named parameter feature.
I have a LUA callback in C/++ and I'm trying to use lua_gettop() to detect an optional first parameter. The problem is that lua_gettop(L) == 1 is always true, even when I don't provide any parameters in LUA.
Here's the basics of my callback function in C/++:
int LuaFile::l_cpp_my_callback(lua_State *L) {
LuaFilePtr my_this = lua_map_[L];
if ( lua_gettop(L) == 0 ) {
// I never get here
} else if(lua_gettop(L) == 1) {
// Always gets here
} else {
return 1;
}
return 1;
}
This is the context of the call in the LUA code:
function my_function()
if ... then
if not ... then
if ... then
someOtherCallback(param, param, param)
someOtherCallback(param)
end
if ... then
someOtherCallback(param)
end
end
else
if not ... then
if ... then
someOtherCallback(param, param, param)
someOtherCallback(param)
end
if ... then
someOtherCallback(param)
end
end
var = my_callback()
...
end
end
I used lua_gettype(L, 1) to debug and it returns '5', which lua_typename(L, 5) says is a 'table'. I'm guessing this is a metatable of the stack?
I understand that 0 isn't a valid index in the LUA stack but then what's the proper way to determine optional first parameters?
As #nate mentioned in his comment, any "object-based" function call, that is, calling a member function--or method, if you prefer--results in the object being the first thing on the Lua stack. lua_gettop would return 1, assuming nothing else was passed to the member function as an argument.
As for checking an optional first argument to the member function, which would be located at index 2 on the Lua stack if you were using an object-based call, functions like luaL_optstring are very helpful. (Reference page here. In case you are unaware, functions prefixed with luaL are located in lauxlib.h.) There are also equivalent functions for other types. It allows one to provide an index and a default argument: if a value exists at the given index on the Lua stack, it is returned; otherwise, the default value supplied to the function is returned.
I want to write a function that returns every item in a List that is not the first or the last item (a via point). The function gets a generic List<*> as input. A result should only be returned if the elements of the list are of the type Waypoint:
fun getViaPoints(list: List<*>): List<Waypoint>? {
list.forEach { if(it !is Waypoint ) return null }
val waypointList = list as? List<Waypoint> ?: return null
return waypointList.filter{ waypointList.indexOf(it) != 0 && waypointList.indexOf(it) != waypointList.lastIndex}
}
When casting the List<*> to List<Waypoint>, I get the warning:
Unchecked Cast: kotlin.collections.List
to kotlin.colletions.List
I can't figure out a way to implement it otherwise. What's the right way to implement this function without this warning?
In Kotlin, there's no way to check the generic parameters at runtime in general case (like just checking the items of a List<T>, which is only a special case), so casting a generic type to another with different generic parameters will raise a warning unless the cast lies within variance bounds.
There are different solutions, however:
You have checked the type and you are quite sure that the cast is safe. Given that, you can suppress the warning with #Suppress("UNCHECKED_CAST").
#Suppress("UNCHECKED_CAST")
val waypointList = list as? List<Waypoint> ?: return null
Use .filterIsInstance<T>() function, which checks the item types and returns a list with the items of the passed type:
val waypointList: List<Waypoint> = list.filterIsInstance<Waypoint>()
if (waypointList.size != list.size)
return null
or the same in one statement:
val waypointList = list.filterIsInstance<Waypoint>()
.apply { if (size != list.size) return null }
This will create a new list of the desired type (thus avoiding unchecked cast inside), introducing a little overhead, but in the same time it saves you from iterating through the list and checking the types (in list.foreach { ... } line), so it won't be noticeable.
Write a utility function that checks the type and returns the same list if the type is correct, thus encapsulating the cast (still unchecked from the compiler's point of view) inside it:
#Suppress("UNCHECKED_CAST")
inline fun <reified T : Any> List<*>.checkItemsAre() =
if (all { it is T })
this as List<T>
else null
With the usage:
val waypointList = list.checkItemsAre<Waypoint>() ?: return null
To improve #hotkey's answer here's my solution:
val waypointList = list.filterIsInstance<Waypoint>().takeIf { it.size == list.size }
This gives you the List<Waypoint> if all the items can be casted, null otherwise.
In case of generic classes casts cannot be checked because type information is erased in runtime. But you check that all objects in the list are Waypoints so you can just suppress the warning with #Suppress("UNCHECKED_CAST").
To avoid such warnings you have to pass a List of objects convertible to Waypoint. When you're using * but trying to access this list as a typed list you'll always need a cast and this cast will be unchecked.
I made a little variation to #hotkey answer when used to check Serializable to List objects :
#Suppress("UNCHECKED_CAST")
inline fun <reified T : Any> Serializable.checkSerializableIsListOf() =
if (this is List<*> && this.all { it is T })
this as List<T>
else null
Instead of
myGenericList.filter { it is AbstractRobotTurn } as List<AbstractRobotTurn>
I like doing
myGenericList.filter { it is AbstractRobotTurn }.map { it as AbstractRobotTurn }
Not sure how performant this is, but no warnings at least.
Kotlin ensures type safety for operations involving generics at compile time, while, at runtime, instances of generic types don't hold information about their actual type arguments. For example, List is erased to just List<*>. In general, there is no way to check whether an instance belongs to a generic type with certain type arguments at runtime.
https://kotlinlang.org/docs/typecasts.html#type-erasure-and-generic-type-checks
I would like to log the return value of a function. The problem is that the function might have many exit points and I don't want to add a log call before every one of them.
I thought about having an inner object that's responsible on making the Log call. But still, I would have to notify it about the return value before each return statement.
I also thought about creating a macro that calls the logger before returning from the function. Something like:
#define RETURN(ret) Logger.log(__FUNCTION__, ret); return ret;
But I want to avoid doing that.
Any other thoughts on how I can achieve that nicely and easily?
Thanks
I don't think you can do that more nicely and easily. In this case I think the solution with least impact on the source is to use the preprocessor, but you shouldn't do it the way you do because it has surprices built in. Fx:
if( done )
RETURN(something);
expands to:
if( done )
Logger.log("function_name", something); return something;
which means that something is sent to the log if done is true, then something is returned anyway.
To make the expansion fit into a single statement it's normally wrapped in a do { ... } while(0) which would make that example log and return only if done is true.
But there's still a surprise since the macro argument is expanded twice, consider the case where you write RETURN(something++); then it will expand to Logger.log(__FUNCTION__, something++); return something++; which means unfortunate side effects. This was a real problem in C, but not in C++. Here templates are handy:
template<typename T>
T const& log_and_return(char const* func, const T& value)
{
Logger.log(func, value);
return value;
}
#define RETURN(value) return log_and_return(__func__, value)
Note that it is called __func__ in the standard (an not __FUNCTION__).
I was working on some c++ code like this:
//c++ code
class MovieInfo;
MovieInfo getMovieInfoByName(String movieName)
{
//search the movieInfoList with movieName
if(FOUND)
return movieInfo;
//TODO: **what should i return if the movieInfo can't be found in the list?**
}
The question is what should i return if the movieInfo can't be found in the list?
You have several options:
Define the MovieInfo class such that an "invalid" instance is possible (similarly to how a default-constructed std::thread doesn't represent an actual thread) and return such an instance.
Make it a precondition of getMovieInfoByName() that the name corresponds to a valid movie info, and simply return a random value if it doesn't (as "violating preconditions leads to undefined behaviour").
Throw an exception when the name is not found.
Return something like boost::optional<MovieInfo>.
Give getMovieInfoByName() an extra parameter of type MovieInfo which would be used as the return value in case no match for the name is found.
It all depends on your intended use of the function.
It depends on the context and preconditions that must be met. For example if you are not sure whether the list contains such a movie by the time you call it, then it would be reasonable to do:
bool getMovieInfoByName(const std::string& movieName, MovieInfo& movieInfo)
{
...
if (FOUND) {
movieInfo = ...;
return true;
}
return false;
}
since the caller will most likely have to know whether the movie with such a movie exists or not.
If it shouldn't happen that getMovieInfoByName will not find the movie, i.e. the caller should already know whether the list contains such a movie by other means, then it is perfectly reasonable to throw an exception since it is exceptional state and rather indicates the wrong usage of this method.
There's also a design pattern called Null Object, which is based on constructing an object, state of which can indicate whether it is a valid / initialized object or it is a dummy instance representing NULL.
In this case the caller would most likely still have to check whether appropriate MovieInfo instance has been returned and this class should provide a method such as bool isValid();.