Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

init = 0 if select_ == 1 else 0 is always == 0 #3

Closed
wants to merge 1 commit into from

Conversation

Twenkid
Copy link
Collaborator

@Twenkid Twenkid commented Jan 30, 2018

Shouldn't it be: init = 1 if select_ == 1 else 0

Shouldn't it be: init = 1 if select_ == 1 else 0
@Twenkid
Copy link
Collaborator Author

Twenkid commented Jan 30, 2018

Or rather ?

init = 1 if len(select_) == 1 else 0
or

init = 1 if len(select_) > 0 else 0

Because select_ == 1 (a list) in a console test seems == 1 either if it's empty [] or if it has elements.

@boris-kz
Copy link
Owner

Thanks Todor, so you are saying list != len(list)? I was told otherwise.

@Twenkid
Copy link
Collaborator Author

Twenkid commented Jan 30, 2018

Yes, at least I think so and this is what my tiny code tests show (run it if you wish):

Twenkid@83f8242

I haven't seen your syntax, so I wasn't sure if it were a rarely used feature - e.g. type inferring as lenght when there were a comparison with scalar. To me it's not reasonable, though. Even if it's "None" it seems to return "1".

There's similar syntax in C/C++, for a dynamic variable (pointer) which has not allocated memory yet and is set initially to 0 (NULL).

Then Var==0 would return TRUE (which is 1 in C) and after allocating memory, the expression would return FALSE, because the pointer would hold a valid address.

@boris-kz
Copy link
Owner

Thanks Todor, I corrected it. Also note that I sometimes have operations that directly change values in tuples, which is not legal. I guess I have to either unpack and repack these tuples, or convert them into lists.

@Twenkid
Copy link
Collaborator Author

Twenkid commented Jan 31, 2018

Right, this is a test with sample reassignment: https://github.com/Twenkid/CogAlg/blob/master/test.py

It's the expressions: dP[7]=, vP[7]=, alt_P[7] ...

Also if alt: semantics was suspicious**, similarly to if selection_, I assume you meant "any of the components is different than 0". Tests confirmed, it's always True even if it's 0,0,0, see also the cases in test.py.

Another solution for such cases when you watch for any change is to have a separate flag "changed".

@boris-kz
Copy link
Owner

boris-kz commented Feb 1, 2018

Thanks, I changed:
if alt:
to:
if alt[0]:
Is that ok?
Is there an easy way to convert tuples to lists?

@Twenkid
Copy link
Collaborator Author

Twenkid commented Feb 1, 2018

if alt[0]: Yes. (I didn't know yet for which exact element you expected a non-zero value.)

Tuples:
Yes, there are direct commands.
A discussion and answers: https://stackoverflow.com/questions/16296643/convert-tuple-to-list-and-back

alt = 1,0,0
alt_list = list(alt)
alt_tuple = tuple(alt_list)

There are examples for more complex cases, tuple of tuples.

If there is a complex structure with mixed tuples, lists, tuples of tuples etc., however I don't know could it be so straight or an explicit type-reflection would be needed (slow), that may require more checking. (But repetitive conversion may hit performance.)

@Twenkid
Copy link
Collaborator Author

Twenkid commented Feb 1, 2018

Also, besides numpy, if it can't be installed for some reason in a Pypy environment for example, there are also simple Python "array" module, but it holds same-type elements, like for input images: https://docs.python.org/3/library/array.html

@boris-kz
Copy link
Owner

boris-kz commented Feb 1, 2018

Thanks. I guess I could just initialize all tuples as lists (=[]), and they will stay lists after assignment?
But that should be a lot slower. Is there a structure that is fixed-length, contains different types, but mutable?

@Twenkid
Copy link
Collaborator Author

Twenkid commented Feb 2, 2018

Would lists stay lists after a tuple is assigned to the variable a = []? AFAIK - no. This code snippet turns a list into a tuple:

b = []

d = 56; g = 67; k=4
b = d, g, k
b
(56, 67, 4)

b = [2,5,6]
b = d,g,k
b
(56, 67, 4)

(Except if the type hints, TypeAlias, NewType don't work for it with some special constraining usage - see below).

However assignment of the components from lists seems the same:

def f4():
alt = [1, 45, 24]
alt_len, alt_vG, alt_dG = alt
print(alt)
print(alt_len, alt_vG, alt_dG)

[1, 45, 24]
1 45 24

The structure - well, I think the closest is Class, maybe not exactly as you asked, as of being sure that all instances are same-size, maybe they would, but I don't know would be of much advantage, because they would be likely to be complex objects with dynamic variables with dynamic size and their attributes may be not locally allocated in contiguous RAM-block, I don't know.

Actually lists and even int are also instances of classes.
Formally class is dynamic, it could be potentially extended in run-time and if it has lists or other dynamic size variables, it won't be same size.

Type hints, type aliases and NewType can be used, though, but I don't have experience with them, maybe it may serve as building a more C-like/C++ structures/classes:
https://docs.python.org/3/library/typing.html

However it's not yet clear does strict type-checking is applied or forced type-conversion when a not appropriate type is assigned.

One simple tests didn't do:
It returns float when float is sent:
def set(i: int) -> int:
... b = i
... return b
...

set(3)
3
set(3.57)
3.57

...

Also, I think performance-wise and precision-wise care should be taken about int/float mixing. I noticed that in some places you use integer division //.
There is also a Numpy dump with types, like "i4" (that's int 4 bytes): https://docs.scipy.org/doc/numpy-1.13.0/reference/arrays.dtypes.html
On the other hand the standard division / produces floats.
When float/int are mixed, the type assigned to the result variable will be float, even if integer division was used:

c = 8.53 // 5
c
1.0
c = 5 // 3.32
c
1.0
c = 5 // 5.98
c
0.0

(There would be type conversions + the calculations and the other overhead).

In current implementation, the image input is int, but once division kicks in: comp_P, fork_eval, the variables become float unless they were explicitly converted to int with int(...) c = int(a/b).

Such type conversion may apply also if the variables are class-attributes, also potentially change the type/recreate the variable (which itself is a class instance).

One way to partially limit this is to filter all accesses to class' attributes through methods (functions), however Python class elements by default are "public", there is a convention for "private" by adding underscores: classname, but it's for the developers, technically they are also accessible. See 9.6. Private Variables.

@Twenkid
Copy link
Collaborator Author

Twenkid commented Feb 2, 2018

I missed to mention the "struct" (import struct) - because it requires pack/unpack to binary representation of C-types and it seems cumbersome.

http://www.learntosolveit.com/python/design_struct_example.html
https://docs.python.org/3/library/struct.html

Also, do you know about the named tuples?

https://docs.python.org/dev/library/collections.html#namedtuple-factory-function-for-tuples-with-named-fields

@boris-kz
Copy link
Owner

boris-kz commented Feb 2, 2018

I don't get it. A list can take anything, why would assignment change it to tuple? Do you get a type error if you try append, +=, list[n] = x, etc., after assigning list = a,b,c?
I use // because match from division is defined as an integer part of ratio, not just to avoid floats.
Miss is a modulo, I compute indirectly, but probably should use % to avoid messing with a sign.

@Twenkid
Copy link
Collaborator Author

Twenkid commented Feb 2, 2018

list+= doesn't produce a type error, but the tuple is flatten and the items in the tuple are added as individual ones. I assume that the k[]; k = (1,2,3) type-change is due to the assignment operator - perhaps the type on the right hand has a higher priority.

l+=(5,6,4)
l
[1, 0, 0, 5, 6, 4]

Append and addressing an index work as expected intuitively:

alt
(1, 0, 0)
l.append(alt)
l
[1, 0, 0, 5, 6, 4, (1, 0, 0)]
l[0] = alt
l
[(1, 0, 0), 0, 0, 5, 6, 4, (1, 0, 0)]

l[5]=alt
l
[(1, 0, 0), 0, 0, 5, 6, (1, 0, 0), (1, 0, 0)]

Error if out of range:

l[10] = alt
Traceback (most recent call last):
File "", line 1, in
IndexError: list assignment index out of range
...

@boris-kz
Copy link
Owner

boris-kz commented Feb 2, 2018 via email

@Twenkid
Copy link
Collaborator Author

Twenkid commented Feb 2, 2018

No, I think there is a type change when there's a direct assignment of a tuple to a var declared as list.
At least that's the behaviour I see:

a = [1,2]
alt = 5,6,7
a = alt
a
(5, 6, 7)
a+=5
Traceback (most recent call last):
File "", line 1, in
TypeError: can only concatenate tuple (not "int") to tuple
a
(5, 6, 7)
a+=(10,9,8)
a
(5, 6, 7, 10, 9, 8)

It turns into a tuple.

Yes, if you append to a list, or insert into it, it's still a list.

@boris-kz
Copy link
Owner

boris-kz commented Feb 2, 2018 via email

@boris-kz boris-kz closed this Apr 9, 2018
boris-kz referenced this pull request in kwcckw/CogAlg Feb 6, 2021
- edits in comp_slice_draft, added section to merge PP, and the usage of fchecksign is not necessary.
boris-kz referenced this pull request in kwcckw/CogAlg Jan 18, 2024
1. Edits in agg_recursion.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants