C++ "for" loop condition in python - python

Is there a one-line way to translate this "for" loop from C++ to python?
for(int i = 0; i < = 10 && i != 6; i++)
I mean in C++ we have :
for(initial_value; condition(s); step)
and I am looking for the analogue version in Python where we can impose one or several conditions.

In C++ a loop like
for (a; b; c)
d;
is equivalent to
{
a;
while (b)
{
d;
c;
}
}
If you first translate your for loop to its corresponding while loop, then you could translate that while loop to Python.

Probably the simplest Pythonic articulation is
for i in range(11):
if i == 6:
continue
... stuff happens ...

If you want to express the idea "do something for numbers from 0 to 10, except 6", the correct C++ code for it cannot be a simple for-loop:
for (int i = 0; i <= 10; i++)
{
if (i != 6)
{
... // do the stuff
}
}
You can translate it literally to Python (see answer by tripleee) or make a real one-liner, like so:
Create a list of numbers for which you want to run the stuff: [x for x in range(11) if x != 6]. Then iterate on it:
for i in [x for x in range(11) if x != 6]:
... # do the stuff
From code readability standpoint, the solution with if or continue may be better than this one.

Related

Fibonacci algorithm in C

I am trying to rewrite a fibonacci algorithm from python to C, but am having some problems. Below is the algorithm in python and I get the correct answer, but after writing in C:
def fib(n):
a, b = 1,1
for i in range(n):
a, b = a+b, a
print(a, b)
return b
print(fib(8))
When I wrote it in C, I get the powers of 2 - I am not sure how and if possible to correct it.
#include<stdio.h>
int fib(n){
int a = 1;
int b = 1;
for (int i=0; i<n; i++){
a = a+b;
b = a;
}
return b;
}
int main(void){
int n;
printf("Enter the # of the fibonacci number in sequence:");
scanf("%d", &n);
int r = fib(n);
printf("%d\n", r);
}
Just add a 3rd variable for extra handling
#include <stdio.h>
int fib(int n) {
int a, b, c;
a = 0;
b = 1;
c = 0;
for (int i = 0; i < n; i++) {
a = b+c;
b = c;
c = a;
}
return a;
}
int main() {
int n;
n = fib(10); // 55
printf("%d\n", n);
}
Zero is a Fibonacci number too!
Try:
int fib(int n){
int a = -1;
int b = 1;
for (int i = 0; i < n; i++) {
int t = a + b;
a = b;
b = t;
}
return b;
}
Also, none of the answers so far (including this one) account for signed integer overflow which is undefined in C. Though, for a trivial program like this it's okay to ignore it. When n is greater than 47 it overflows on my pc.
It can be done with just two variables with a simple change b = a-b. However, an optimizing compiler will use a third register as a temp variable instead of doing b = a - b;
#include<stdio.h>
int fib(n){
int a = 1;
int b = 0;
for (int i = 0; i < n; i++){
a = a+b;
b = a-b;
}
return b;
}
int main(void){
int n;
printf("Enter the # of the fibonacci number in sequence:");
scanf("%d", &n);
int r = fib(n);
printf("%d\n", r);
return 0;
}
In Python, when a multiple assignment statement is executed, all expressions on the right-hand side are evaluated using the current values of the variables, and then these values are bound to the variables given in the left-hand side. For example, the statement
a, b = a+b, a
evaluates both the expressions a+b and a, using the current values of a and b, and then binds these values to a and b, respectively. If the current values are a=1, b=1, then the expressions have values 1+1=2 and 1, respectively, and so we get a=2, b=1.
However, your C code executes the two statements a=a+b and b=a in sequence, rather than in parallel (like Python does). First the expression a+b is evaluated (if a=1, b=1, then a+b=2), and its value is bound to the variable a (so a is 2), and finally the expression a in the second statement is evaluated (it has value 2), and its value is bound to b (so b=2). If you want to use the original value of a (a=1) in the statement b=a, then you must store that original value in a temporary variable before overwriting a by a+b, as follows:
temp=a;
a=a+b;
b=temp;
In general, you can figure out yourself what is wrong with the program by learning to do a hand simulation of the program, where you write down (on paper) the current values of each variable in the program. For example, you can write the variables a and b in separate lines, with their initial values 1 and 1, respectively, next to them. Each time you execute an assignment statement, evaluate the expression on the right-hand side using the current values, and overwrite the left-hand-side variable with this new value. So, when you encounter a=a+b, you would evaluate a+b to be 2 (using the current values), and then cross out the current value of 1 for a and replace it by 2. In this manner, you can obtain the output using pencil and paper, and figure out what is wrong with the program.

Porting python code to C++ / (Printing out arrays in c++)

I am currently learning C++ and being quite proficient in python, I decided to try porting some of my python code to C++. Specifically I tried porting this generator I wrote that gives the fibonacci sequence up to a certain given stop value.
def yieldFib(stop):
a = 0
b = 1
yield i
for i in range(2):
for i in range(stop-2):
fib = a+b
a = b
b = fib
yield fib
fib = list(yieldFib(100))
print(fib)
to this
int* fib(int stopp){
int a = 0;
int b = 1;
int fibN;
int fibb[10000000];
fibb[0] = 0;
fibb[1] = 1;
for(int i=2; i<stopp-2; i++){
fibN = a+b;
a = b;
b = fibN;
fibb[i] = fibN;
}
return fibb;
}
int main(){
int stop;
cin >> stop;
int* fibbb = fib(stop);
cout << fibbb;
}
I admit the c++ is very crude, but this is just to aid my learning. for some reason the code just crashes and quits after it takes user input, I suspect it has something to do with the way i try to use the array, but I'm not quite sure what. Any help will be appreciated
An integer array of size 10000000 is generally too large to be allocated on the stack, which causes the crash. Instead, use a std::vector<int>. In addition to that:
The variable b is unused.
fibN is not initialized. Its value will be indeterminate.
Returning a pointer to stack memory will not work, as that pointer is no longer valid once the function has returned.
The code would print the value of an integer pointer instead of the values of the array. Instead, iterate over the array and print the values one by one.
On a side note: It seems that you are trying to learn C++ by trial-and-error, while it is best learned from the ground up using a book or course.
In provided code, I see many mistakes.
First: You're creating int-array with 10000000 length inside stack (you're not allocating memory) what is 40 MB! You just exceed the stack length (1 MB, as I remember). Just allocate it with new operator. If you don't want to work with this kind of array (or don't want to calculate its precise length), you can use std::vector which can expand himself in memory.
int* fibb = new int[precise_length];
//or
std::vector<int> fibb = std::vector<int>(); //and fill it by calling fibb.push_back()
Second: cout usage. You try to print array POINTER, not contents. Print every member of array separately.
#include<bits/stdc++.h>
using namespace std;
vector<int> fib( const int& n ){
vector<int> v = {0, 1};
for(int i = 2; i <= n; i++){
v.push_back( v[i - 1] + v[i - 2] );
}
return v;
}
int main(){
int n;
cin >> n;
vector<int> _fib = fib( n );
for( auto x : _fib ){
cout << x << ' ';
}
return 0;
}

Fibonacci sequence: C vs Python

This is a code I wrote in C for Fibonacci sequence:
#include <stdio.h>
#include <stdlib.h>
int fib(int n)
{
int a = 0, b = 1, c, i;
if (n == 0)
return a;
for (i = 2; i <= n; i++) {
c = a + b;
a = b;
b = c;
}
return b;
}
int main()
{
printf("%d",fib(1000));
return 0;
}
And this is the direct translation in Python:
def fib(n):
a=0
b=1
if n == 0:
return a
for _ in range(n-1):
c = a + b
a = b
b = c
return b
print(fib(1000))
The C program outputs:
1556111435
Where Python (correctly) outputs:
43466557686937456435688527675040625802564660517371780402481729089536555417949051890403879840079255169295922593080322634775209689623239873322471161642996440906533187938298969649928516003704476137795166849228875
I realize the problem with C is with the variable type (since the fib(50) works just fine in C), but I have two major questions:
How should I correct the C program in a way that I can calculate fib of any number? In other words, rather than just using double (which has its own limitation), how can I calculate any fib in C?
How does Python handle this? Because apparently, it has no limitation in the size of integers.
C does not offer any dynamically sized integer types directly. The biggest you can go within the language itself is long long. However there is nothing stopping you from writing your own big-integer functions that allocate memory and handle carry as needed.
Or you can just use someone else's big integer lib, for instance BigInt.
(Looking at BigInt's source code will also answer the question how Python does this.)
Edit: I just had a bit of a closer look at BigInt myself. Beware that it uses the regular pen&paper method unconditionally for multiplication, which is fast for "small" numbers, but for "large" numbers has worse performance than the Karatsuba method. However please note that the border between "small" and "large" in this context is probably so high, that in most practical cases the pen&paper method is enough (see the linked Wiki article). It's also worth noting that you can combine both algorithms for multiplication, by writing them recursively and having Karatsuba's method fall back to pen&paper if the number of bits is below a given threshold.

array include range from python in c++

I have an array in python, which is declared as follow:
u[time][space]
My code in Python's for loop requires me to do the following:
for n in range(0,10):
u[n][:] = 1
This colon indicates the whole range of my [space].
Now, how would I go about to use the colon (:) to indicate the whole range when doing for loop in c++?
Thanks
for(auto& inner : u)
std::fill(inner.begin(), inner.end(), 1);
Use two loops as suggested.
Something like:
int n, s;
for(n=0; n<10; n++){
for(s=0; s<space; s++){
u[n][s] = 1;
}
}
should work.
C++ does not have an equivalent to
for n in range(0,10):
u[n][:] = 1
You are going to have to write the loop that u[n][:] = 1 represents. Fortunately with ranged based for loops it is pretty trivial. That would look like
int foo[3][3];
for (auto& row : foo)
for (auto& col : row)
col = 1;
I don't remember a quick way to do it in C++. I'm afraid you'd have to loop in each table.
This would look like this (admitting that space is a known integer):
for (int i = 0; i < 10; i++)
for (int j = 0; j < space; j++)
u[i][j] = 1;
You're going to have to use two loops. Modern C++ has some tricks up its sleeve to make initializing these loops simple, but here is a basic C example that will work anywhere:
#define TIME_MAX 100
#define SPACE_MAX 350
int u[TIME_MAX][SPACE_MAX];
int i, j;
for (i = 0; i < TIME_MAX; i++)
for (j = 0; j < SPACE_MAX; j++)
u[i][j] = 1;

Vectorizing a nested for-loop in python for index-dependent function

I'm currently porting a C++ program to Python using Numpy arrays. I'm looking for a way to implement, if possible, the following loops in a more Pythonic way:
for (int j = start_y; j < end_y; j++)
{
for (int i = start_x; i < end_x; i++)
{
plasmaFreq[i][j] = plasmaFreq_0*(tanh((i - 50)/10) - tanh((i - (nx - 50))/10))/2.0;
}
}
Above, plasmaFreq_0 is a constant passed into the surrounding function, as is nx. Obviously it's easy to vectorize the loop bounds to operate on a particular region of a numpy array, but this leaves me with the issue of how to map the above index-dependent function across the array.
You'll need an array i,
i = np.arange(start_x, end_x)
plasmaFreq[start_x:end_x, start_y: end_y] = plasmaFreq_0 *(np.tanh((i - 50)/10) - np.tanh((i - (nx - 50))/10))/2.0
I think that broadcasting should take it from there.
Note that your original code is quite inefficient1... First, you're calculating the right hand side for each j, but it doesn't depend on j, so you only really need to calculate it once. Second, your inner loop is over the slow index so you won't be effectively using your cache. I would probably write it as:
for (int i = start_x; i < end_x; i++)
{
rhs = plasmaFreq_0*(tanh((i - 50)/10) - tanh((i - (nx - 50))/10))/2.0;
for (int j = start_y; j < end_y; j++)
{
plasmaFreq[i][j] = rhs;
}
}
1How inefficient depends on how well the compiler can do figuring out the loops. Someday maybe some compilers could generate the same code from yours and mine

Categories

Resources