Basic Python loop - loops

How does Python know what "i" is when it is not defined, shouldn't there be an error? Probably a simple explanation, but I am new to learning Python.
def doubles (sum):
return sum * 2
myNum = 2
for i in range (0,3):
myNum = doubles(myNum)
print (myNum)

Haha :-) People are marking down your question, but I know that is one question must have came in every person's mind. Specially those who learned Python through Online courses and not through a teacher in person.
Well let me explain that in layman's term,
The method that you used is specially used for 1) lists and 2) lists within lists.
For eg,
example1= ['a','b','c'] # This is a simple list
example2 = [['a','b','c'],['a','b','c'],['a','b','c']] # This is list within lists.
Now, 'a','b' & 'c' are items in list.
So by saying,
for i in example1:
print i
we are actually saying,
for item in the list(example1):
print item
-------------------------
People use 'i', probably taken as abbreviation to item, or something else.
I don't know the history.
But, the fact is that, we can use anything instead or 'i' and Python will still consider it as an item in list.
Let me give you examples again.
example1= ['a','b','c'] # This is a simple list
example2 = [['a','b','c'],['a','b','c'],['a','b','c']] # This is list within lists.
for i in example1:
print i
[out]: a
b
c
now in example2, items are lists within lists. --- also, now i will use the word 'item' instead of 'i' --- the results regardless would be the same for both.
for item in example2:
print item
[out]: ['a','b','c']
['a','b','c']
['a','b','c']
people also use singulars and plurals to remember things,
so lets we have a list of alphabet.
letters=['a','b','c','d']
for letter in letters:
print letter
[out]: a
b
c
d
Hope that helps. There is much more to explain.
Keep researching and keep learning.
Regards,
Md. Mohsin

Using a variable as a loop control variable does assign to it each time through the loop.
As to "what it is"... Python is dynamically typed. The only thing it "is" is a name, just like any other variable.

i is assigned the value in the loop itself, it has no value (it is not defined) before the Python interpreter reaches the for line.
Its similar to how other for loops define variables. In C++ for example:
for(int i=0; i<5; i++){
cout << i << endl;
}
Here the variable i is only exists once the for loop is called.

i is assigned a value when the for loop runs, so the Python interpreter will not raise an error when the loop is run

long story short it creates a new variable without having to be defined and its value is whatever number your loop is on, for example if you had written:
num = 0
for i in range(3):
print(num)
num = num + 1
so for the first time this loop ran 'i' would equal 0 (because python lists/loops etc always start on 0 not 1), the second time it would equal 1, etc. and the 'num' you can ignore it's just an example of code you could have in a loop which would print out numbers in ascending order.
Levin

Related

Ruby partner pairing program not working?

I am new to ruby and have this program that takes in a number of names and sorting them into pairs of two, and throwing the odd person in a random group. Sometimes it works perfect, sometimes it throws the extra person into an array of their own, and im not sure why. I know there is a cleaner way to do this but Im just trying to understand how the code works. For example it should return "Apple" "Banana" "Orange" as ["Banana", "Orange", "Apple"] and will most of the time, but sometimes it give me ["Banana","Orange",] ["Apple"] Any advice?
def randomArray
classNames = []
puts "Please enter a list of names to sort"
while true
input = gets.chomp
break if input.empty?
classNames << input
end
classRandom = classNames.shuffle
splitNames = classRandom.each_slice(2).to_a
arrayPos = 0
splitNames.length.times do
if splitNames[arrayPos].length == 2
arrayPos+=1
else splitNames[arrayPos].length == 1
splitNames.sample << splitNames[arrayPos].pop
arrayPos+=1
end
end
x = 0
splitNames.length.times do
break if splitNames[x].empty?
puts "Group number #{x+1} is #{splitNames[x]}"
x+=1
end
end
randomArray
Your problem is this: splitNames.sample << splitNames[arrayPos].pop
sample can return any element of the array, including the element that has the odd person you're trying to assign! So if it samples that person, it removes them from their group of 1 and then adds them right back in.
To fix it, take advantage of the fact that either all groups will be pairs, or the last group will have a single person. Don't iterate over the array, just check splitNames[-1]. If they are alone, add them to splitNames[0...-1].sample.

Lua: Unexpected Iteration Result with Table

I was playing around in Lua with a simple 'isPrime' function I made, and, ignoring the actual 'isPrime' function, which is irrelevant to this query, wrote the following code:
out = {}
for i = -10,20 do
out[i] = isPrime(i)
end
for k,v in ipairs(out) do
print(k,v)
end
My expectation was that the program would print every single key and its respective value, -10 through 20, but found instead that only 1 through 20 were printed. -10 through 0 were in the table, I found, after checking specifically for those key-value pairs, but oddly, they were never printed.
Can anyone explain why this happened? I feel I do not fully understand how Lua iterates and accesses its keys through the ipairs() function.
ipairs(t) will iterate over the key–value pairs (1,t[1]), (2,t[2]), ..., up to the first nil value. That's not what you want. Just use the style of your first loop
for i = -10,20 do
print(i, out[i])
end

Efficient allocation of cell array in matlab

I have some which converts a cell array of strings into a cell array of characters.
Note. For a number of reasons, both the input (C) and the output (C_itemised) must be cell arrays.
The cell array of strings (C) is as follows:
>> C(1:10)
ans =
't1416933446'
''
't1416933446'
''
't1416933446'
''
't1416933446'
''
't1416933446'
''
I have only shown a portion of the array here. In reality it is ~28,000 rows in length.
I have some code which does this, although it is very inefficient. The cellstr function takes up 72% of the code's time, as it is currently called thousands of times. The code is as follows:
C_itemised=cell(length(C),500);
for i=3:length(C)
temp=char(C{i});
for j=1:length(temp)
C(i-2,j)=cellstr(temp(j));
end
end
I have a feeling that some minor modifications could take out the inner loop, thus cutting down the overall running time substantially. I have tried a number of ways to do this, but I think I keep getting confused about whether to use {} or (), and haven't been able to find anything online that can help me. Can anyone see a way to make the code more efficient?
Please also note that this function is used in conjunction with other functions, and does work, although it is running slower than would be ideal. Therefore, I do not wish to change the format of C_itemised.
EDIT:
(A sample of) the output of my current function is:
C_itemised(1,1:12)
ans =
Columns 1 through 12
't' '1' '4' '1' '6' '9' '3' '3' '4' '4' '6' []
One thing I can suggest is to use the undocumented function sprintfc. This function is hidden from normal use in MATLAB, but it is used internally with a variety of other functions. Mainly, if you tried doing help sprintfc, it'll say that there's no function found! It's cool to sniff around the source sometimes!
How sprintfc works is that you provide it a formatting string, much like printf, and the data you want printed. It will take each individual element in the data and place them into individual cell arrays. As an example, supposing I had a string D = 'abcdefg';, if we did:
out = sprintfc('%c', D);
We get:
>> celldisp(out)
out{1} =
a
out{2} =
b
out{3} =
c
out{4} =
d
out{5} =
e
out{6} =
f
out{7} =
g
As such, it takes each element in your string and places them as individual characters serving as individual elements in a new cell array. The %c formatting string means that we want to print a single character per element. Check out the link to Undocumented MATLAB that I posted above if you want to learn more!
Therefore, try simplifying your loop to this:
C_itemised=cell(length(C));
for i=1:length(C)
C_itemised{i} = sprintfc('%c', C{i});
end
C_itemised will be a cell array, where each element C_itemised{i} is another cell array, with each element in this cell array being a single character that is composed of the string C{i}.
Minor Note
You said you were confused about {} and () in MATLAB for cells. {} is used to access individual elements inside the cell. So doing C{1} for example will grab whatever is stored in the first element of the cell array. () is used to slice and index into the cells. For example, if you wanted to make another cell array that is a subset of the current one, you would do something like C(1:3). This will create a three element cell array which is composed of the first three cells in C.

Printing out a set of lists in the ti-84 ti-basic

I want to be able to print out L1 up to Lk (lists in the ti-84) for some arbitrary number k.
Lists in ti-basic are essentially one-dimensional arrays used to store a real or complex number into each of their elements.
Below I made my own lists named L1, ... L3 (not built in, in reality can be accessed and printed by typing LL1, ... LL3)
I will show you some of what I tried, etc.
let L5 = {5,5,5}
If I try the following code snippet:
PROGRAM: ITRTLST
:ClrHome
:Disp LL1
:For(J,1,3
:Disp J
:Disp LL5
:End
This code outputs:
1
{5,5,5}
2
{5,5,5}
3
{5,5,5}
Note the first 'L' in LL5 is a token (accessible by pressing [2nd]+[LIST(STAT)] OPS B:)
However if I try the following code snippet:
PROGRAM: ITRTLST
:ClrHome
:Disp LL1
:For(k,1,3
:Disp J
:Disp LLk
:End
I get ERR:UNDEFINED
This is because it thinks of 'LLK' as a list name rather than LL1, LL2, LL3
We can see this if I let LLK = {1,2,3} then the above code outputs
1
{1,2,3}
2
{1,2,3}
3
{1,2,3}
This can be done but it is a pain, and will probably be very slow.
Try this code, with [Max] replaced with a number:
:ClrHome
:For(I,1,[Max])
:"Convert I into a string, this is slow
:I/10→D
:sub("0123456789",10*fPart(D)+1,1)→Str1
:int(D)→D
:While D>0
:D/10→D
:sub("0123456789",10*fPart(D)+1,1)+Str1→Str1
:int(D)→D
:End
:"Display the I'th list
:Disp expr("ʟL" + Str1)
:End
Note that the lines starting with " are just comments and can be removed.
This is a pretty ugly (and possibly the only) method, but it is possible to do this by running a bunch of If commands.
For example,
Disp ʟL1
If K≥2
Disp ʟL2
If K≥3
Disp ʟL3
If K≥4
Disp ʟL4
If K≥5
Disp ʟL5
So on and so forth.
EDIT: I don't know if you still need an answer to this question, but I found a way to do exactly what you want. It's still very messy, though.
Convert your number to a string, like Str0 (You can choose from a couple ways: link1 link2).
Concatenate that number with the list name. For example, "ʟL" + Str0 → Str0.
Evaluate the string with expr(.
As I said, this is very much ugly, and all those number-to-string conversions can't be too efficient, so you're probably better off copy-pasting a bunch of If statements for each condition.
Alternatively, you can compress all the lists you're using into a single big list, and have the start positions of each list stored in another list. Then you can extract any sublist you want from the big compress list with the seq( command.
There's no way to do that in TI-Basic. Just as there's no way to go from a string "X" to the contents of the variable X, there's no way to go from a number ot a list with that number in its name.
UPDATE: It turns out you can use expr("X") to get the value of X. And you can do that same with lists.
But alternatively, if you want to store a 2-dimensional array of data, TI-Basic does have matrices, although they are somewhat restricted compared to lists (in particular, you cannot create named matrices). If you need some data structure more complex than that, you may have reached the limits of this language.

Finding whether a value is equal to the value of any array element in MATLAB

Can anyone tell me if there is a way (in MATLAB) to check whether a certain value is equal to any of the values stored within another array?
The way I intend to use it is to check whether an element index in one matrix is equal to the values stored in another array (where the stored values are the indices of the elements which meet a certain criteria).
So, if the indices of the elements which meet the criteria are stored in the matrix below:
criteriacheck = [3 5 6 8 20];
Going through the main array (called array) and checking if the index matches:
for i = 1:numel(array)
if i == 'Any value stored in criteriacheck'
%# "Do this"
end
end
Does anyone have an idea of how I might go about this?
The excellent answer previously given by #woodchips applies here as well:
Many ways to do this. ismember is the first that comes to mind, since it is a set membership action you wish to take. Thus
X = primes(20);
ismember([15 17],X)
ans =
0 1
Since 15 is not prime, but 17 is, ismember has done its job well here.
Of course, find (or any) will also work. But these are not vectorized in the sense that ismember was. We can test to see if 15 is in the set represented by X, but to test both of those numbers will take a loop, or successive tests.
~isempty(find(X == 15))
~isempty(find(X == 17))
or,
any(X == 15)
any(X == 17)
Finally, I would point out that tests for exact values are dangerous if the numbers may be true floats. Tests against integer values as I have shown are easy. But tests against floating point numbers should usually employ a tolerance.
tol = 10*eps;
any(abs(X - 3.1415926535897932384) <= tol)
you could use the find command
if (~isempty(find(criteriacheck == i)))
% do something
end
Note: Although this answer doesn't address the question in the title, it does address a more fundamental issue with how you are designing your for loop (the solution of which negates having to do what you are asking in the title). ;)
Based on the for loop you've written, your array criteriacheck appears to be a set of indices into array, and for each of these indexed elements you want to do some computation. If this is so, here's an alternative way for you to design your for loop:
for i = criteriacheck
%# Do something with array(i)
end
This will loop over all the values in criteriacheck, setting i to each subsequent value (i.e. 3, 5, 6, 8, and 20 in your example). This is more compact and efficient than looping over each element of array and checking if the index is in criteriacheck.
NOTE: As Jonas points out, you want to make sure criteriacheck is a row vector for the for loop to function properly. You can form any matrix into a row vector by following it with the (:)' syntax, which reshapes it into a column vector and then transposes it into a row vector:
for i = criteriacheck(:)'
...
The original question "Can anyone tell me if there is a way (in MATLAB) to check whether a certain value is equal to any of the values stored within another array?" can be solved without any loop.
Just use the setdiff function.
I think the INTERSECT function is what you are looking for.
C = intersect(A,B) returns the values common to both A and B. The
values of C are in sorted order.
http://www.mathworks.de/de/help/matlab/ref/intersect.html
The question if i == 'Any value stored in criteriacheck can also be answered this way if you consider i a trivial matrix. However, you are proably better off with any(i==criteriacheck)

Resources