How to use IN with a block instead of an object? - object

The IN function in Rebol finds out if a field is in an object:
USAGE:
IN object word
DESCRIPTION:
Returns the word or block in the object's context.
IN is a native value.
ARGUMENTS:
object (any-object! block!)
word -- (modified if series) (any-word! block! paren!)
The claim is it works with objects or blocks. It works okay if I try it with an object:
>> in object [foo: 10 bar: 20] 'foo
== foo
But if I just try it with a raw block, it gives back NONE:
>> in [foo: 10 bar: 20] 'foo
== none
Guess I'd understand if it didn't support blocks (Rebol2 didn't). But what's the case in which it wouldn't return NONE that blocks are allowed for?
And at the risk of making this two questions in one, what's the deal with accepting BLOCK! for the word parameter? I'd think it would take a block if you had a set of words you were looking for, but it seems to just return the block:
>> in object [foo: 10 bar: 20] [mumble frotz bar]
== [mumble frotz bar]
>> in object [foo: 10 bar: 20] [mumble frotz]
== [mumble frotz]
And at the further risk of making this three questions, what meaning would taking a PAREN! for word have?

The IN function isn't primarily meant for searching an object for a word, it is for returning a word or block of words that are in the object, or in Rebol terms bound to the object. It's a variant of the BIND function that is useful in different circumstances than BIND.
If there is no word of that name in the object, it returns none, sensibly enough. This gives it the side benefit of being able to be used in conditional expressions as a word detection function, but that's not its main use.
IN can take a block of objects for its object parameter and then try to bind the word to each object in turn, returning a word bound to the first object in the block that has that word. This was meant as a relatively quick way to do overriding word lookup for an old design of the Rebol 3 GUI, but it turned out to not be the best approach in that case so the GUI doesn't use that design now. However, IN block word was kept as a potentially useful feature for future use elsewhere.
In your example, there were no objects in that block, so there was nothing that IN could bind the word to. That is why IN returned none.
If you pass IN a block for the word parameter, it binds the block to the object before it returns it. This is to allow code like do in obj [print a]. It doesn't do a bind/copy though, so you should be careful about code like that. Or maybe IN object block should copy - is it too late to change that? Passing a paren for the word argument should have the same binding behavior as passing a block.
When last I checked, we didn't support having both the object an word parameters be blocks. This is because we couldn't figure out a good model for what that behavior should be, at least obviously. The overriding word lookup doesn't really work with a block of words because the results would be inconclusive.
It would be useful to have a function that rebound a block to a series of objects in order, especially for recreating Rebol's not-really-nested scopes, but it would be really confusing for that function to be IN.

This might not be as useful, but since it is not explicitly mentioned, and I think is the 'right' way to solve your first question for now:
red>> first find [foo: 10 bar: 20] 'foo
== foo:
This doesn't work on rebol2 tho, but quoteing the set-word! does :
>> first find [foo: 10 bar: 20] quote [foo:]
== foo:
Still has the slight disadvantage of returning a set-word!

Related

iterating over list in list; python

I have a simple problem. I'm new to python and programming so I think i miss something.
The variable "account_info" is assigned earlier and is a list of lists with 4 elements each. The variable current is a user input value, which (should) appear as the first element of the lists in the list account_info.
I want to iterate over the lists in the list and compare if the first element is equal to "current".
This is the code:
for i in account_info:
if current == account_info[i][0]:
email = account_info[i][1]
additional = account_info[i][2]
pw = account_info[i][3]
print(email)
I get an error in pycharm, when running that code. It seems that I can't iterate over the lists like that, can please someone explain and show a different solution?
Thank you
As #ForceBru commented, your issue is due to how for loops in Python work. The value you get from the loop is not an index into the iterable object you're looping on, rather, it's a value from the iterable. That makes your indexing with it later almost certainly wrong (though in certain contexts it might make sense, if you have a list that contains indexes into itself).
In your case, you probably want to do something more like this:
for account in accounts_info:
if current == account[0]: # note, only the inner indexing is needed
email = account[1]
additional = account[2]
pw = account[3]
Since you're expecting the inner lists to contain four values, you could even unpack the account values that you get from iterating directly into the inner variables. Though this would happen unconditionally, so it might not do what you want. Here's what that would look like, with the print call you were doing after the loop instead moved inside the conditional (so you only print the one email address that corresponds to the value in current):
for account_id, email, additional, pw in account_info: # unpack unconditionally
if account_id == current: # use the convenient name here
print(email) # print only in the conditional
In the rare case where you really do need to iterate over indexes, you can use the range type, which behaves like a sequence of integers (starting at zero by default). So you could replace your loop with this version and the body would work as you had intended (though this is less idiomatic Python than the previous versions).
for i in range(len(accounts_info)):
If you need both the index and the current value, you can use the enumerate function, which yields 2-tuples of index and value as you iterate over it. This is often handy when you need to reassign values in a list some times:
for i, account in enumerate(accounts_info):
if account[0] == current:
accounts_info[i] = new_value # replace the whole account entry

Perl6 - What is the $: for in some subroutine Signatures

I came across this error message in another question and I would like to know what is the meaning of the $: part of the signature, please?
Cannot resolve caller index(Str: Str, Any); none of these signatures match:
(Str:D $: Cool:D $needle, *%_)
(Str:D $: Str:D $needle, *%_)
(Str:D $: Cool:D $needle, Cool:D $pos, *%_)
(Str:D $: Str:D $needle, Int:D $pos, *%_)
The $: is two distinct unrelated tokens, a $ and a :, that have been smooshed together.
The $ represents a single item1 aka a scalar2.
The single item / scalar hasn't been given a name, so there's no way to reference it. And there's already enough of a parameter (the Str:D) to let you and the compiler know that this parameter is a scalar (a single string). Either way, the $ is redundant and Elizabeth has made a related change.
The : is a special parameter separator. (The usual parameter separator is a comma ,.)
It may only be used immediately after the first parameter of a method or standalone signature. It may not be used in the signature of a routine that is not a method.
If used as a parameter separator after the first parameter in a signature, it marks that parameter as corresponding to a method's "invocant".
(If not used, the invocant parameter is implicit.)
The corresponding invocant argument will arrive anyway, and be aliased to self, whether or not the signature explicitly lists an invocant parameter. But if the invocant parameter is explicitly specified, it's possible to give it an additional/alternate name and/or explicitly constrain its type.
Crazy over-the-top footnotes for added entertainment. If they confuse you, just forget you ever read them.
1 A single item refers to data that is naturally a single thing, like the number 42, OR data that is naturally a composite thing (like an array) that is being treated like it's a single thing (like an array). (Did you see what I did there?) I like to point out the mnemonic that a $ symbol is like an S (for single) overlaid with an I (for item), or vice-versa. To me this represents the idea of emphasizing the single item nature of any data, hiding any plural aspect even if it's actually an array or other composite data item.
2 "scalar" is a traditional computing term. Wikipedia's Scalar disambiguation page lists "Variable (computing), or scalar, an atomic quantity that can hold only one value at a time" as a definition. Also, a single item aka scalar (all lowercase) is often/usually a Scalar (uppercase S), a special case of a single item that's a Single Item container that contains a Single Item (which can be composite data being treated as a single thing).
The : mark the first argument as an invocant.
my $word = "bananarama";
say $word.index( "r", 0 );
In this case, it indicates the invocant is going to be treated as an scalar, since it's constrained by a single $

Python3: Building dictionary from .fasta - "strange" printout for value

I am parsing a .fasta-File containing one big sequence into python by using:
for rec in SeqIO.parse(faFile, "fasta"):
identifier=(rec.id)
sequence=(rec.seq)
Then, I am building a dictionary:
d={identifier:sequence}
When printing sequence only, I get the following result:
CAGCCAGATGGGGGGAGGGGTGAGCGCTCTCCCGCTCAAAACCTCCAGCACTTT...CAT
Note: All letters are printed, I made dots to shorten this
When printing the dictionary, I get:
{'NC_003047.1': Seq('CAGCCAGATGGGGGGAGGGGTGAGCGCTCTCCCGCTCAAAACCTCCAGCACTTT...CAT', SingleLetterAlphabet())}
Where does the "Seq" and the SingleLetter alphabet come from?
Desired result would be:
{'NC_003047.1':'CAGCCAGATGGGGGGAGGGGTGAGCGCTCTCCCGCTCAAAACCTCCAGCACTTT...CAT'}
Update1:
following the link in the comments, I tried
input_file=open(faFile)
d=SeqIO.to_dict(SeqIO.parse(faFile,"fasta"))
resulting in:
{'NC_003047.1': SeqRecord(seq=Seq('CAGCCAGATGGGGGGAGGGGTGAGCGCTCTCCCGCTCAAAACCTCCAGCACTTT...CAT', SingleLetterAlphabet()), id='NC_003047.1', name='NC_003047.1', description='NC_003047.1 Sinorhizobium meliloti 1021 chromosome, complete genome', dbxrefs=[])}
So, sadly, this does not help :(
Thanks in advance for your time and effort :)
SeqIO doesn't return a string, it returns an object. When you print it, you print the object's string representation, which in this case is not just the data contained in (some attribute of) the object.
(Some objects are designed so that printing the object will print just the data inside it. This depends on how the library is put together and how the programmer designed its __str__() method. This is probably not useful for you at this point, but might help you understand other related resources you find if you pursue this further.)
I'm not familiar with SeqIO but quick googling suggests you probably want
d={identifier: sequence.seq}
to put just the SeqIO object's seq attribute as the value for this identifier.

prolog recursive searching with contraints

I have a house with rooms that are defined with connections for when you can go from one room to another eg.
connection(garage,sidehall).
connection(sidehall,kitchen).
connection(kitchen,diningroom).
canget(X,Y):-connection(X,Y).
canget(X,Y):-connection(X,_),
write('player goes from '),write(X),write(' to '),write(Y),nl,
canget(_,Y).
Im trying to figure out how make it so the player can only get from one room to another when they have a specific item, such as you can only be in the kitchen when items = gloves.
canget(X,Y,Item):-connection(X,Y,Item),canbein(Y,Item).
canget(X,Y,Item):-connection(X,Somewhere,Item),canbein(Somewhere,Item),canget(Somewhere,Y,Item).
tried defining canbein with:
canbein(kitchen):- item(sword).
canbein(sidehall):- item(hat).
but that doesnt work!
Have defined my items as such, not sure if this is right either:
item(gloves,sword,helm,cheese).
Basically, have i declared my item values correctly?
How can i use the specific item value to make canget x to y false?
Thank you!
Well, I see a few problems with your code. Firstly, you call canbein with two arguments (from canget predicate). However, canbein is defined as single-argument predicate. Therefore, the call always fails as no canbein/2 predicate exists.
I suggest the following modification:
canbein(kitchen, sword).
canbein(sidehall, hat).
Than, the item definition is not required. Let's think about what happens during the unification of
canget(X,Y,Item) :- connection(X,Y,Item), canbein(Y,Item).
Let's assume the following setting X=sidehall, Y=kitchen, Item==sword. This predicate should be OK. Assuming the conection predicate is OK, prolog tries to find canbein(Y, Item) i.e. canbein(kitchen, sword) and it succeeds.
On the contrary, if the Item is different the unification fails, hence it works as expected.
The second problem is the item predicate. By your definition, it expects 4 arguments. That's nonsense, of course. You should declare it like
item(gloves).
item(sword).
item(helm).
item(cheese).
However, I don't think this predicate is necessary at all. Just to be clear, try to call item(X) and obtain all results (the four declared). Try it with the prior definition - what should you even ask for?
I hope it helps :)

groovy: use brackets on method calls or not?

this is a fairly general question about whether people should be using brackets on method calls that take parameters or not.
i.e.
def someFunc(def p) {
...
}
then calling:
someFunc "abc"
vs...
someFunc("abc")
Is this just a question of consistency, or is there specific use cases for each?
It's primarily a question of consistency and readability, but note that Groovy won't always let you get away with omitting parentheses. For one, you can't omit parentheses in nested method calls:
def foo(n) { n }
println foo 1 // won't work
See the section entitled "Omitting parentheses" in the Style guide.
There's no specific case where you must remove them, you can always use them. It's just prettier to leave them out.
There are cases where you can't do that (where you could confuse a list/map parameter with a subscript operator for instance, nested calls, or when the statement is an assignment), but the general rule is that the outmost call can have no parenthesis if there is no ambiguity.
(deleted several lines, as I've just received notification that there is a post already with that info)
Groovy 1.8 will allow even more cases to omit parenthesis, you can check them out at
http://groovyconsole.appspot.com/script/355001
"an empty pair of parentheses is just useless syntactical noise!"
It seems to me that they are encouraging you to use parenthesis when they serve a purpose, but omit them when they are just "noise"

Resources