I have this code:
var obj;
if (!instance_exists(oTextbox)) {
obj=instance_create(0,0,oTextbox)
obj.textfont=argument0
obj.text[0]=argument1
obj.text[1]=argument2
obj.text[2]=argument3
obj.text[3]=""
}
Its a simple way to draw text, but when I call it with less arguments I get a compile error(expected 4 arguments provided 3),
I just want a way to be able to provide less arguments so the code will ignore if I provided less arguments and will just go to the last line
Well not very sure what you mean exactly, you can try varargs to pass variable number of arguments and check length when using them:
public void DrawText(Object... args)
{
var obj;
if (!instance_exists(oTextbox)) {
obj=instance_create(0,0,oTextbox);
int len=args.Length;
obj.textfont = args[0].toString();
obj.text[0] = args[1].toString();
if(len>2){
obj.text[1] = args[2].toString();
}
if(len>3){
obj.text[2] = args[3].toString();;
}
if(len>4){
obj.text[3] = args[4].toString();
}
}
}
Supposing you will always pass at least two values, one for textfont and one for text[0].
Related
In the application combineLatest is used to combine three observables:
class SomeComponent {
private heightProvider = new SubjectProvider<any>(this);
private marginsProvider = new SubjectProvider<any>(this);
private domainProvider = new SubjectProvider<any>(this);
arbitraryMethod(): void {
combineLatest([
this.heightProvider.value$,
this.marginsProvider.value$,
this.domainProvider.value$
]).pipe(
map(([height, margins, domain]) => {
// ...
}
}
setHeight(height: number): void {
this.heightProvider.next(height);
}
setMargins(margins: {}): void {
this.marginsProvider.next(margins);
}
setDomain(domain: []): void {
this.domainProvider.next(domain);
}
}
However, I've noticed a few times already that I am sometimes forgetting to set one of these observables.
Is there a way I can build in error handeling that throws to console once one of these isn't set?
Observables aren't typically 'set' or 'not set'. I'm not sure what you mean by this. If you have a predicate that can check your observables, here is how you might use it.
// predicate
function notSet(o: Observable<any>): Boolean{
//...
}
scale$: Observable<any> = defer(() => {
const combining = [
this.heightProvider.value$,
this.marginsProvider.value$,
this.domainProvider.value$
];
const allSet = !combining.find(notSet)
if(!allSet) console.log("Not Set Error");
return !allSet?
EMPTY :
combineLatest(combining).pipe(
map(([height, margins, domain]) => {
// ...
}
Update
Ensursing source observables have emitted
If I understand your problem properly, you want to throw an error if any of your source observables haven't emitted yet. At its heart, this feels like a simple problem, but it happens to be a problem for which there doesn't exist a single general solution.
Your solution has to be domain-specific to some extent.
A simplified example of a similar problem
What you're asking a similar to this:
How do I throw an error if 'add' isn't invoked with a second number?
const add = (a: number) => (b: number): number => {
// How do I throw an error if this function
// isn't invoked with a second number?
return a + b;
}
/***********
* Example 1
***********/
// add is being called with one number
const add5 = add(5);
...
/* More code here */
...
// add is being called with a second number
const result = add5(50);
console.log(result); // Prints "55"
/***********
* Example 2
***********/
const result = add(5)(20); // Add is being called with both numbers
console.log(result); // Prints "55"
/***********
* Example 3
***********/
// add is being called with one number
const add5 = add(5);
...
/* More code here */
...
// add was never given a second number
return
// Add throws an error? How?
How can you write add such that it throws an error if the second number isn't 'set'? Well, there's no simple answer. add doesn't know the future and can't guess whether that second number was forgotten or will still be set in the future. To add, those two scenarios look the same.
One solution is to re-write add so that it must take both parameters at once. If either is missing, throw an error:
const add = (a: number, b: number): number => {
if(a != null && b != null){
return a + b;
}
throw "add: invalid argument error";
}
This solution fundamentally changes how add works. This solution doesn't work if I have a requirement that add must take its arguments one at a time.
If I want add to keep that behaviour, perhaps I can set a timer and throw an error if the second argument isn't given fast enough.
const add = (a: number) => {
const t = setTimeout(
() => throw "add: argument timeout error"),
1000 // wait 1 second
);
return (b: number): number => {
clearTimeout(t); // cancel the error
return a + b;
}
}
Now add takes its arguments one at a time, but is a timeout really how I want this to work? Maybe I only care that add is given a second parameter before some other event (an API call returns or a user navigates away from the page) or something.
Hopefully, you can begin to understand how such a "simple" problem has only domain-specific solutions.
Observables
Your question, as writ, doesn't tell us enough about what you're trying to accomplish to guess what behaviour you want.
Observables have a lot of power built into them to allow you to design a solution specific to your needs. It's almost certain that you can throw an error if one of your observables isn't set, but first, you must define what this even means.
Is it not set quickly enough? Is it not set in time for a certain function call? Not set when an event is raised? Never set? How would you like to define never? When the program is shut down?
Maybe you could switch your Subjects for BehaviourSubjects so that they MUST always have a value set (sort of like add taking both arguments at once instead of one at a time).
All of these things (and many many many more) are possible.
UserList is a list of dictionaries, like:
[
{Name:"Alex",Age:25},
{Name:"Peter",Age:35},
{Name:"Muhammad",Age:28},
{Name:"Raul",Age:29}
]
RowColorList is a list of colors: [#bcf,#fc0]
The new UserList should contain one RowColor for every name, taken in sequence from RowColorList:
[
{Name:"Alex",Age:25,RowColor:#bcf},
{Name:"Peter",Age:35,RowColor:#fc0},
{Name:"Muhammad",Age:28,RowColor:#bcf},
{Name:"Raul",Age:29,RowColor:#fc0}
]
I tried the following code:
UserList.Zip(RowColorList,(user,color) => user.Add("RowColor",color))
With this code, the new UserList will only contain as many entries as are in RowColorList. I would like him to start from the beginning of RowColorList again, whenever the available colors are used up. How?
You can create a function to return an infinite enumerable of Color / string (or whatever the type of RowColor is), by using yield return as a lazy generator:
public IEnumerable<Color> InfiniteColors()
{
while (true)
{
foreach (var color in RowColors)
{
yield return color;
}
}
}
This can then be used with any of the Linq IEnumerable extension methods such as Zip.
UserList.Zip(InfiniteColors(),(user,color) => user.Add("RowColor",color))
Edit - Explanation
The reason why InfiniteColors doesn't hang is because the state machine will yield back to the caller after each result, and Zip will terminate on the first enumerable to complete, which is because the other collection being zipped is finite (i.e. UserList)
Obviously you shouldn't try and Zip the InfiniteColors enumerable with itself, nor should you try and materialize InfiniteColors, i.e. don't call InfiniteColors.ToList() or such :-):
Something like this should do the trick:
var i = 0;
var l = RowColorList.Count;
UserList.ForEach(user => user.Add("RowColor", RowColorList[(i++) % l]));
The % operator will guarantee "cyclic" access to the RowColorList.
I am issuing calls that return an Option that contains a Result which contains another Option that contains custom variants.
I am only ever interested in a specific chain of variant results like this:
if let Some(Ok(Some(CustomVariant(Some(value))))) = expr {
// handle value case
}
This is getting quite verbose and not really helpful, since I actually treat it as a single Result in all of my code. Can I somehow alias this code so that instead of writing the entire chain of Options and Results I can do something similar to:
alias TheCase(value) = Some(Ok(Some(CustomVariant(Some(value))));
if let TheCase(value) = expr {
//handle value
}
You don't need such an alias, just use a function to retrieve the one case you want:
fn oneCaseICareAbout(value: &Option<Result<Option<Foo>, Bar>>) -> Option<&Foo> {
if let Some(Ok(Some(CustomVariant(Some(value)))) = value {
Some(value)
} else {
None
}
}
if let Some(value) = oneCaseICareAbout(expr) {
//handle value
}
I would however consider refactoring your code not to use such a type. Option<Result<_, _>> is already a red flag, but Some(Ok(Some(CustomVariant(Some(…)))) is just on the edge of insanity!
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.
This code actually works fine, the question I have with my code is how do you store the enum constant in any variable, and why do we use enum? and what does the statement mean HouseType houseType;? Thank you so much in advance.
import java.util.Scanner;
public class HomeBuying {
public enum HouseType{UNKNOWN,SINGLEFAMILY,TOWNHOUSE,CONDOMINIUM};
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("Enter the type of house you want to purchase"); //1.Single Family/n" " 2. Townhouse/n" " 3. Condominium/n");
int choice = input.nextInt();
HouseType houseType;
switch(choice) {
case 1:
houseType = HouseType.SINGLEFAMILY;
break;
case 2:
houseType = HouseType.TOWNHOUSE;
break;
case 3:
houseType = HouseType.CONDOMINIUM;
break;
default:
houseType = HouseType.UNKNOWN;
break;
}
System.out.println(houseType);
}
The code snippet you provided already stores an Enum value in a variable.
HouseType houseType; //declaration of variable of type HouseType (means it can store values of the HouseType enum)
houseType = HouseType.UNKNOWN; //put value into the houseType variable
We use enums whenever we need to represent values from some known and finite set. For example if you want your program to keep track of whether it is day or night, you could just make up some rule for yourself and use integers, say 1 represents day and 0 represents night. But then what the other numbers mean? Or you could just use boolean for that (again, with some arbitrary meaning attached to false and true).
enum TimePeriod{
DAY,
NIGHT
}
Enums represent a better alternative by letting you to be explicit about what values mean. This is not just a convenience - being explicit in your intentions is what makes your program readable by others.