error in "if" loop (Sage) - python

I'm using "Sage," but I do not think that it is relevant for this question.
I have made the following definitions, and attempted to implement an if loop:
Q = DiagonalQuadraticForm(ZZ,[1,1,1,1])
L = Q.representation_number_list(10)
for i in range(len(L)):
if L[i] == 0 % 2:
print i
Upon looking up Python demos, it seems as though my syntax is correct and (I haven't been made aware of any syntax errors.)
However, nothing is being printed! In fact, if I declare "i" in the next textbox, all that displays is "9," which doesn't change despite my fiddling with the modulus. What is wrong?

Modulus syntax in Python (and most other programming languages) is not the same as mathematical notation. In math, you write
a ≡ b (mod n)
to indicate that a and b are congruent modulo n. In programming languages, modulus is treated as an arithmetic operation on a and n, analogous with division (it returns the remainder of the division rather than the quotient). To determine if the number is congruent with another number, you compare that remainder with the number, so it's written as:
a % n == b
Therefore, your if statement should be:
if L[i] % 2 == 0:
When you write
if L[i] == 0 % 2:
it's parsed as:
if L[i] == (0 % 2):
And since the remainder of 0 / 2 is 0, it's equivalent to:
if L[i] == 0:
which isn't what you intended.

You intend to print even numbers? This should work:
Q = DiagonalQuadraticForm(ZZ,[1,1,1,1])
L = Q.representation_number_list(10)
for i, v in enumerate(L):
if v % 2 == 0:
print i
enumerate(...) can replace range(len(...))

Related

Fix the solution of "Binary period"

I found this task and completely stuck with its solution.
A non-empty zero-indexed string S consisting of Q characters is given. The period of this string is the smallest positive integer P such that:
P ≤ Q / 2 and S[K] = S[K+P] for 0 ≤ K < Q − P.
For example, 7 is the period of “abracadabracadabra”. A positive integer M is the binary period of a positive integer N if M is the period of the binary representation of N.
For example, 1651 has the binary representation of "110011100111". Hence, its binary period is 5. On the other hand, 102 does not have a binary period, because its binary representation is “1100110” and it does not have a period.
Consider above scenarios & write a function in Python which will accept an integer N as the parameter. Given a positive integer N, the function returns the binary period of N or −1 if N does not have a binary period.
The attached code is still incorrect on some inputs (9, 11, 13, 17 etc). The goal is to find and fix the bugs in the implementation. You can modify at most 2 line.
def binary_period(n):
d = [0] * 30
l = 0
while n > 0:
d[l] = n % 2
n //= 2
l += 1
for p in range(1, 1 + l):
ok = True
for i in range(l - p):
if d[i] != d[i + p]:
ok = False
break
if ok:
return p
return -1
I was given this piece of code in an interview.
The aim of the exercice is to see where lies the bug.
As an input of the function, you will type the integer to see the binary period of it. As an example solution(4) will give you a binary number of 0011.
However, the question is the following: What is the bug?
The bug in this occasion is not some crash and burn code, rather a behavior that should happen and in the code, do not happen.
It is known as a logical error in the code. Logical error is the error when code do not break but doesn't fullfill the requirements.
Using a brute force on the code will not help as there are a billion possibilities.
However if you run the code, let's say from solutions(1) to solutions(100), you will see that the code runs without any glitch. Yet if you are looking at the code, it should return -1 if there are errors.
The code is not givin any -1 even if you run solutions to a with bigger number like 10000.
The bug here lies in the -1 that is not being triggered.
So let's go step by step on the code.
Could it be the while part?
while n > 0:
d[l] = n % 2
n //= 2
l += 1
If you look at the code, it is doing what it should be doing, changing the number given to a binary number, even if it is doing from a backward position. Instead of having 1011, you have 1101 but it does the job.
The issue lies rather in that part
for p in range(1, 1 + l):
ok = True
for i in range(l - p):
if d[i] != d[i + p]:
ok = False
break
if ok:
return p
return -1
It is not returning -1.
if you put some print on some part of the code like this, this would give you this
for p in range(1, 1 + l):
ok = True
for i in range(l - p):
print('l, which works as an incrementor is substracted to p of the first loop',p,l-p)
if d[i] != d[i + p]:
ok = False
break
if ok:
return p
return -1
If you run the whole script, actually, you can see that it is never ending even if d[i] is not equal anymore to d[i+p].
But why?
The reason is because l, the incrementor was built on an integer division. Because of that, you need to do a 1+l//2.
Which gives you the following
def solution(n):
d = [0] * 30
l = 0
while n > 0:
d[l] = n % 2
n //= 2
l += 1
for p in range(1, 1 + l//2): #here you put l//2
ok = True
print('p est ',p)
for i in range(l - p):
if d[i] != d[i + p]:
ok = False
break
if ok:
return
Now if you run the code with solutions(5) for example, the bug should be fixed and you should have -1.
Addendum:
This test is a difficult one with a not easy algorithm to deal with in very short time, with variables that does not make any sense.
First step would be to ask the following questions:
What is the input of the algorithm? In this case, it is an integer.
What is the expected output? In this case, a -1
Is it a logical error or a crash and burn kind of error? In this case, it is a logical error.
These step-by-step (heuristic) will set you on the right direction to debug a problem.
Following up Andy's solution and checking #hdlopez comment, there is a border case when passing int.MaxVal=2147483647
and if you do not increase the array size to 31 (instead of 30). The function throws an index out of range, so two places need to be modified:
1- int[] d = new int[31]; //changed 30 to 31 (unsigned integer)
2- for (p = 1; p < 1 + l / 2; ++p) //added division to l per statement, P ≤ Q / 2

Understanding Collatz Conjecture Objective in Python

I'm trying to decipher the following homework question. My code is supposed to evaluate to 190 but instead evaluates to 114. So, I don't think I'm understanding the coding requirement.
The Collatz conjecture is an example of a simple computational process
whose behavior is so unpredictable that the world's best
mathematicians still don't understand it.
Consider the simple function f(n) (as defined in the Wikipedia page
above) that takes an integer n and divides it by two if n is even and
multiplies n by 3 and then adds one to the result if n is odd. The
conjecture involves studying the value of expressions of the form
f(f(f(...f(f(n))))) as the number of calls to the function f
increases. The conjecture is that, for any non-negative integer n,
repeated application of f to n yields a sequence of integers that
always includes 1.
Your task for this question is to implement the Collatz function f in
Python. The key to your implementation is to build a test that
determines whether n is even or odd by checking whether the remainder
when n is divided by 2 is either zero or one. Hint: You can compute
this remainder in Python using the remainder opertor % via the
expression n % 2. Note you will also need to use integer division //
when computing f.
Once you have implemented f, test the your implementation on the
expression f(f(f(f(f(f(f(674))))))). This expression should evaluate
to 190.
from __future__ import division
def collatz(n):
l = []
l.append(n)
while n != 1:
if n % 2 == 0:
n = n // 2
l.append(n)
else:
n = (3*n) + 1
l.append(n)
return l
print len(collatz(674))
You just misread the intermediary question. Your programs tries to answer the bigger question... This is what should return 190:
def f(n):
return n // 2 if n % 2 == 0 else 3*n + 1
print f(f(f(f(f(f(f(674)))))))

computes the logarithm of a number x relative to a base b.n other words [duplicate]

This question already has answers here:
What is the purpose of the return statement? How is it different from printing?
(15 answers)
Closed 4 months ago.
Write a simple procedure, myLog(x, b), that computes the logarithm of a number x relative to a base b.n other words, myLog should return the largest power of b such that b to that power is still less than or equal to x.
x and b are both positive integers; b is an integer greater than or equal to 2. Your function should return an integer answer.
Do not use Python's log functions; instead, please use an iterative or recursive solution to this problem that uses simple arithmatic operators and conditional testing.
What is wrong in the below code? As they have not mentioned what to return when the condition fails, so had kept false
def myLog(x, b):
count = 1
while x > 0 and b >= 2:
ans = b ** count
if (ans == x):
print str(count)
break
elif (ans > x):
print str(count-1)
break
count += 1
else:
return False
Since you haven't explained what problem you're trying to solve, all I can do is guess. But…
Your function never returns a number. If it succeeds, it prints out a number, then falls off the end of the function and returns None. If it fails, it returns False. And there's no other return anywhere in the code.
That's easy to fix: just return the value instead of print-ing it:
def myLog(x, b):
count = 1
while x > 0 and b >= 2:
ans = b ** count
if (ans == x):
return count
elif (ans > x):
return count-1
count += 1
else:
return False
You can improve performance by doing ans *= b each time through the loop instead of ans = b ** count. If the numbers are huge, dividing x by b might be better—division is usually slower than multiplication, but getting out of the huge-number domain early might help more than avoiding division.
It's also got some style problems, like the unnecessary parentheses some (but not all) of your conditions.
And finally, you may want to consider writing a "test driver". For example:
repcount = 100
errcount = 0
for _ in range(repcount):
x = generate_nice_random_x()
b = generate_random_base()
log1, log2 = myLog(x, b), int(math.log(x, b))
if log1 != log2:
print('log({}, {}): {} != {}'.format(x, b, log1, log2))
errcount += 1
print('{}/{} errors'.format(errcount, repcount))
Start with a small repcount to make sure you don't spam the screen; when you're happier with it, use a much larger one. Meanwhile, I'll leave it to you to figure out a good domain to choose from for testing log functions.
This is a question on an exam, that is currently ongoing.MITx: 6.00.1x Introduction to Computer Science and Programming

Ordering of evaluation using boolean or

So I've got this snippet of code. And it works (It says 1 is non-prime).:
n = 1
s = 'prime'
for i in range(2, n / 2 + 1):
if n == 1 or n % i == 0:
s= 'non-' +s
break
print s
My problem is that if I change the fourth line to: if n % i == 0 or n == 1:, it doesn't work (it says 1 is prime.)
Why is that? Since I'm using or should it be that either one of them is True so the order doesn't count?
(I'm still learning about boolean so I may be making some basic mistake.)
Thanks in advance!
EDIT: Thanks for the answers; I never realized my issue with the range() function. And about the code working and not working: I have no idea what happened. I may have made some mistake somewhere along the way (maybe forgot to save before running the script. Although I could've sworn that it worked differently :P ). Maybe I'm just getting tired...
Thanks for the answers anyways!
In both cases, the body of the loop does not run, because when 'n' is 1, it does not fall within the range of (n,n/2+1)
The code you posted says that 1 is prime (again, because the loop body does not execute at all)
The precedence is fine. % is evaluated first, then ==, then or, so it breaks down into:
___or___
/ \
== ==
/ \ / \
n 1 % 0
/ \
n i
Your problem is that your for loop is not being executed at all, so that s is still set to "prime".
The range 2,n/2+1 when n is 1 equates to 2,1 which will result in the body not being executed.
In fact it won't be executed where n is 2 either since 2/2+1 is 2 and the range 2,2 doesn't execute. The values are the start and terminating value, not start and end (last) value - it's just fortuitous there that 2 is considered a prime by virtue of the initialisation of s :-)
Try this instead:
#!usr/bin/python
n = 9
s = 'prime'
if n == 1:
s = 'non-prime'
else:
i = 2
while i * i <= n:
if n % i == 0:
s= 'non-prime'
break
i = i + 1
print s
It's wasteful going all the way up to n/2, the square root of n is all that's needed.
i think the problem is when n is 1, the loop is skipped.
Other answers already correctly addressed your specific problem (which, in other words, is that the loop executes only if n/2 + 1 > 2, that is, n/2 > 1, which means n > 2 with new-style division [[python 3 or suitable imports from the future or flags...]], n > 3 with classic style truncating division).
Wrt the specific question you posed:
Since I'm using or should it be that
either one of them is True so the
order doesn't count?
The order does count because or (like and) is a short-circuiting operator: specifically, or is guaranteed to go left to right, and stop if the left operand is true (because it does not need to know about the right one). This doesn't matter for your specific code, but it's crucial in cases such as, e.g.:
if i == 0 or n / i > 3: ...
If or wasn't going left-to-right (and stopping ASAP), the right-hand operand might get executed even when i equals 0 -- but then the division would raise an exception! With Python's rules, this code snippet won't raise exceptions (if i is an int, at least;-).
Again: this has nothing to do with the specific problem you're having (see other answers and the start of this one), but it's important for you to know for the future, so, since you asked, I took the opportunity to explain!-)
for n in range(101):
s = 'prime'
if n < 2 or not (n & 1): ## not(n & 1) == is even number (last bit 0) == not (n % 2)
s = 'non-'+s
else:
for i in range(3, int(n**0.5) + 1,2):
if not(n % i):
s= 'non-' +s
break
print "%i is %s" % (n,s)
You need not check all even numbers and you can stop the check at square root of n.

Python Syntax Problem

I'm just getting back into Project Euler and have lost my account and solutions, so I'm back on problem 7. However, my code doesn't work. It seems fairly elementary to me, can someone help me debug my (short) script?
Should find the 10001st Prime.
#!/usr/bin/env python
#encoding: utf-8
"""
P7.py
Created by Andrew Levenson on 2010-06-29.
Copyright (c) 2010 __ME__. All rights reserved.
"""
import sys
import os
from math import sqrt
def isPrime(num):
flag = True
for x in range(2,int(sqrt(num))):
if( num % x == 0 ):
flag = False
if flag == True:
return True
else:
return False
def main():
i, n = 1, 3
p = False
end = 6
while end - i >= 0:
p = isPrime(n)
if p == True:
i = i + 1
print n
n = n + 1
if __name__ == '__main__':
main()
Edit*: Sorry, the issue is it says every number is prime. :/
The syntax is fine (in Python 2). The semantics has some avoidable complications, and this off-by-one bug:
for x in range(2,int(sqrt(num))):
if( num % x == 0 ):
flag = False
range(2, Y) goes from 2 included to Y excluded -- so you're often not checking the last possible divisor and thereby deeming "primes" many numbers that aren't. As the simplest fix, try a 1 + int(... in that range. After which, removing those avoidable complications is advisable: for example,
if somebool: return True
else: return False
is never warranted, as the simpler return somebool does the same job.
A simplified version of your entire code (with just indispensable optimizations, but otherwise exactly the same algorithm) might be, for example:
from math import sqrt
def isPrime(num):
for x in range(3, int(1 + sqrt(num)), 2):
if num % x == 0: return False
return True
def main():
i, n = 0, 3
end = 6
while i < end:
if isPrime(n):
i += 1
print n
n += 2
if __name__ == '__main__':
main()
"Return as soon as you know the answer" was already explained, I've added one more crucial optimization (+= 2, instead of 1, for n, as we "know" even numbers > 3 are not primes, and a tweak of the range for the same reason).
It's possible to get cuter, e.g.:
def isPrime(num):
return all(num % x for x n range(3, int(1 + sqrt(num)), 2))
though this may not look "simpler" if you're unfamiliar with the all built-in, it really is, because it saves you having to do (and readers of the code having to follow) low level logic, in favor of an appropriate level of abstraction to express the function's key idea, that is, "num is prime iff all possible odd divisors have a [[non-0]] remainder when the division is tried" (i.e., express the concept directly in precise, executable form). The algorithm within is actually still identical.
Going further...:
import itertools as it
def odd():
for n in it.count(1):
yield n + n + 1
def main():
end = 5
for i, n in enumerate(it.ifilter(isPrime, odd())):
print n
if i >= end: break
Again, this is just the same algorithm as before, just expressed at a more appropriate level of abstraction: the generation of the sequence of odd numbers (from 3 included upwards) placed into its own odd generator, and some use of the enumerate built-in and itertools functionality to avoid inappropriate (and unneeded) low-level expression / reasoning.
I repeat: no fundamental optimization applied yet -- just suitable abstraction. Optimization of unbounded successive primes generation in Python (e.g. via an open-ended Eratosthenes Sieve approach) has been discussed in depth elsewhere, e.g. here (be sure to check the comments too!). Here I was focusing on showing how (with built-ins such as enumerate, all, and any, the crucial itertools, plus generators and generator expressions) many "looping" problems can be expressed in modern Python at more appropriate levels of abstraction than the "C-inspired" ones that may appear most natural to most programmers reared on C programming and the like. (Perhaps surprisingly to scholars used to C++'s "abstraction penalty" first identified by Stepanov, Python usually tends to have an "abstraction premium" instead, especially if itertools, well known for its blazing speed, is used extensively and appropriately... but, that's really a different subject;-).
Isn't this better?
def isPrime(num):
for x in range(2,int(sqrt(num))):
if( num % x == 0 ):
return False
return True
And this:
def main():
i, n = 1, 3
while i <= 6:
if isPrime(n):
i = i + 1
print n
n = n + 1
Also, I'm not seeing a 10001 anywhere in there...

Categories

Resources