invalid types 'int [3][double]' for array subscript - esp8266

When compiling a "arduino tamagotchi" I get the message
invalid types 'int [3][double]' for array subscript
What might be the issue?
Set before the void loop()
float poopometer=0;
int poops [3] = {
0,0,0,
};
The reported error is on the line:
poops[round(poopometer)]=random(20,display.width()+32);
void loop() {
button1State = digitalRead(button1Pin);
button2State = digitalRead(button2Pin);
button3State = digitalRead(button3Pin);
//char* str = "";
if(!dead){
/* -------- MODIFY PET STATS -------- */
// TODO: different gradients regarding to age
if(sleeping){
hunger-=0.00005;
poopometer+=0.00005;
if(happiness-0.0001>0){
happiness-=0.0001;
}
health-=0.00005+countPoops()*0.0001;
if(discipline-0.0001>0){
discipline-=0.0001;
}
}else{
hunger-=0.00025;
poopometer+=0.00025;
if(happiness-0.0002>0){
happiness-=0.0002;
}
health-=0.0001+countPoops()*0.0001;
if(discipline-0.0002>0){
discipline-=0.0002;
}
//discipline-=0.02;
}
age+=0.0000025;
//diarrhea :) for testing
//poopometer+=0.005;
//health-=1;
//health-=countPoops()*0.0001;
//health-=countPoops()*0.05;
if(poopometer>=10){
poopometer=countPoops();
poops[round(poopometer)]=random(20,display.width()+32);
if(soundEnabled){
tone(sound,200,50);
}
poopometer=0;
}

The round function returns a floating point number (double), you need to convert it into an integer. Always check the documentation, see: https://cplusplus.com/reference/cmath/round/
like this:
poops[(int)round(poopometer)]=random(20,display.width()+32);
Only positive integer values can be used as a index.

Related

How to typecast fixed size byte array as struct?

I want to reinterpret a stack allocated byte array as a stack allocated (statically guaranteed) struct without doing any work - just to tell the compiler that "Yes, I promise they are the same size and anything". How do I do that?
I tried transmute, but it doesn't compile.
fn from_u8_fixed_size_array<T>(arr: [u8; size_of::<T>()]) -> T {
unsafe { mem::transmute(arr) }
}
cannot transmute between types of different sizes, or dependently-sized types E0512
Note: source type: `[u8; _]` (this type does not have a fixed size)
Note: target type: `T` (this type does not have a fixed size)
There is also this variant of such a function, that compiles, but it requires T to be Copy:
fn from_u8_fixed_size_array(arr: [u8; size_of::<T>()]) -> T {
unsafe { *(&arr as *const [u8; size_of::<T>()] as *const T) }
}
With Rust 1.64 I have a compilation error on [u8; size_of::<T>()] (cannot perform const operation using T).
I tried with a const generic parameter but the problem is still the same (I cannot introduce a where clause to constrain this constant to match size_of::<T>()).
Since the array is passed by value and the result is a value, some bytes have to be copied ; this implies a kind of memcpy().
I suggest using a slice instead of an array and checking the size at runtime.
If you are ready to deal with undefined behaviour, you might consider the second version which does not copy anything: it just reinterprets the storage as is.
I'm not certain I would do that, however...
Edit
The original code was compiled with nightly and a specific feature.
We can simply use transmute_copy() to get the array by value and emit a value.
And, I think the functions themselves should be qualified with unsafe instead of just some of their operations, because nothing guaranties (statically) that these conversions are correct.
#![feature(generic_const_exprs)] // nightly required
unsafe fn from_u8_slice_v1<T>(arr: &[u8]) -> T {
let mut result = std::mem::MaybeUninit::<T>::uninit();
let src = &arr[0] as *const u8;
let dst = result.as_mut_ptr() as *mut u8;
let count = std::mem::size_of::<T>();
assert_eq!(count, arr.len());
std::ptr::copy_nonoverlapping(src, dst, count);
result.assume_init()
}
unsafe fn from_u8_slice_v2<T>(arr: &[u8]) -> &T {
let size = std::mem::size_of::<T>();
let align = std::mem::align_of::<T>();
assert_eq!(size, arr.len());
let addr = &arr[0] as *const _ as usize;
assert_eq!(addr % align, 0);
&*(addr as *const T) // probably UB
}
unsafe fn from_u8_fixed_size_array<T>(
arr: [u8; std::mem::size_of::<T>()]
) -> T {
std::mem::transmute_copy(&arr)
}
fn main() {
let a = [1, 2];
println!("{:?}", a);
let i1 = unsafe { from_u8_slice_v1::<i16>(&a) };
println!("{:?}", i1);
let i2 = unsafe { from_u8_slice_v2::<i16>(&a) };
println!("{:?}", i2);
let i3 = unsafe { from_u8_fixed_size_array::<i16>(a) };
println!("{:?}", i3);
}
/*
[1, 2]
513
513
513
*/

The operator '[]=' isn't defined for the type 'String'

I'm getting an error in this code:
void main() {
List<String> wave(String str) {
List<String> results = [];
String newStr;
int i = 0;
for (String ltr in str.split('')) {
newStr = str;
if (ltr != ' ') {
newStr[i] = ltr.toUpperCase();
results.add(newStr);
}
i++;
}
return results;
}
print(wave(' gap '));
}
the error is at the line:
newStr[i] = ltr.toUpperCase;
Despite when I try print(newStr[i]); I don't get an error and the code is executed correctly!
In Dart String operation, operator[] returns a string. Which means, array[index] is used for getting the string in the index position. That is why you're getting that error, because you can't set at specific index using this operator[] in dart. See the documentation for details.
To replace at the specific index in dart, you can use replaceFirst(Pattern from, String to, [int startIndex = 0]) as the other answer mentioned. Or, you can use substring(int start, [int? end]) as follows:
if (ltr != ' ' && i < newStr.length) {
newStr = newStr.substring(0, i) + ltr.toUpperCase() + newStr.substring(i+1);
results.add(newStr);
}
To make the code bug free, I've added the checking of the value of i in it. You should add the checking to avoid out of bound access.
try to replace
newStr[i] = ltr.toUpperCase();
to
newStr = newStr.replaceFirst(ltr,ltr.toUpperCase(),i);
So the result will be [ Gap , gAp , gaP ]
Honestly, I don't know how char is defined in Dart, but I think accessing index of String is kind of getter, thus cannot be set to a new value.

Cannot assign through subscript: subscript is get-only

I'm using Expression to create a very advanced calculator that takes string input from a user. I'm trying to add functions to give the calculator more features however I am not able to add custom or cast functions. Could you kindly explain me why the I am getting the following error.
Code that works
public static let mathSymbols: [Symbol: SymbolEvaluator] = {
var symbols: [Symbol: SymbolEvaluator] = [:]
symbols[.function("atan", arity: 1)] = { atan($0[0]) }
symbols[.function("abs", arity: 1)] = { abs($0[0]) }
symbols[.function("log", arity: 1)] = { log2($0[0]) }
return symbols
}()
Input that doesnt work
symbols[.function("number", arity: 1)] = { Float($0[0]) }
symbols[.function("number", arity: 1)] = { someFunction($0[0]) }
Error
Cannot assign through subscript: subscript is get-only
The error message is misleading. Expression.swift defines
public typealias SymbolEvaluator = (_ args: [Double]) throws -> Double
which means that the closure must return a Double:
symbols[.function("number", arity: 1)] = { Double($0[0]) }

Swift error, cannot convert type Int to int 16

This function compares the number with the sum of the cubes of the components of this number. For example abc=a^3 + b^3 + c^3. There is an error converting, please help.
func triKuba ( i:Int16, k:Int16, var array:[Int16]=[] ) ->Int16{
for var i=100;i<1000; i++ {
array.append(Int16(i))
if array[i] == pow(array[i]/10) + pow(array[i]/100) + pow(array[i]%10) {
return array[i]
} else {
return 0
}
}
}
triKuba(0, k: 0)
next error in line around method pow 'Cannot invoke pow with argument list of type Int16' if I understood correctly, method pow is a^3
I strongly suspect this is what you are looking for:
func arithmeticRoot3(var value: Int) -> Int {
var result = 0
while value > 0 {
let digit = value % 10
result += digit * digit * digit
value /= 10
}
return result
}
func triKuba() -> [Int] {
return (100...999).filter() {
$0 == arithmeticRoot3($0)
}
}
print(triKuba()) // [153, 370, 371, 407]
Rather than just solving your issue, I'm going to explain what the problem is, and why it throws an error. With this information you should be able to fix the issue (and similar ones in the future!).
In Swift, you can't always do things like multiply an Int with a Float, or return an Int16 from a Double type return function. To you, it might be obvious that 'casting' the variable to the intended type would be fine - but the compiler doesn't know that.
If you're sure it will be safe, you can 'cast' variables to the required type:
Int(int16Variable) // int16Variable has been casted to an 'Int'.
The method you posted had several syntax issues. I fixed them. Working method below:
func triKuba ( i:Int16, k:Int16, var array:[Int16]=[] ) ->Int16{
for var i=100;i<1000; i++ {
array.append(Int16(i))
if Double(array[i]) == pow(Double(array[i])/10, 3.0) + pow(Double(array[i]/100), 3.0) + pow(Double(array[i]%10), 3.0) {
return array[i]
} else {
return 0
}
}
}
Error you were getting was about missing cast from Int to Int16(i)
in your for loop you are declaring a new i variable which is implied to be of type Int as opposed to Int16. (Due to shadowing this is the variable being used in your function body, the parameter i you pass in is never being used.
I would advise either changing the type for your function parameters to be of type Int like so:
func triKuba (var i: Int, var k: Int, var array: [Int]=[] ) -> Int {
or cast your Int16 variables to Ints like so:
array.append(Int16(i))

Trying to convert a simple OBJC fucntion to Swift

I have a simple function in OBJ C to create a random number
+(NSString*)certRef
{
NSInteger rNumber = arc4random() % 100000000 + 1;
NSString *randomCertRef = [NSString stringWithFormat: #"%ld", (long)rNumber];
return randomCertRef;
}
Now im trying to convert it Swift:
Class ToolsCustomFunctions
func randomNumber(theNumber: String){
let rNumber = arc4random() % 100000000 + 1;
let rNumberString = "\(rNumber)"
println("THE RANDOM NUMBER IS: \(rNumberString)")
return (theNumber)
}
The above gives Error "string not convertible to ()
Then im trying access it in class B
let rNumberFuction = ToolsCustomFunctions()
//read randomised number string here//
Various attempts including println "the random number is \(rNumberFuction.randomNumber(theNumber: String))" result in not accessing/setting the randomised number from my function either through compiler error or a nil value
func randomNumber(theNumber: String) { ... }
is a function
taking one argument (a String), and
returning nothing (aka Void or ().
What you want is a function
without arguments, and
returning a string
which is declared as
func randomNumber() -> String { ... }
And the return value should be rNumberString, not theNumber.

Resources