Python Forum
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Error in Pycharm
#1
I'm using Pycharm as a Python IDE. Is it advisable to do so?
I wrote a program and it gives me the following error messages (the code works, Pycharm says its a warning and a weak warning)

Error:
Name 'length' can be undefined Name 'n' can be undefined Multi-step list initialization can be replaced with a list literal
My code is (if required to help me):
numerator = float(input("Enter numerator: "))
denominator = float(input("Enter denominator: "))

numerator = int(round((numerator * 100 / denominator), 0))
denominator = 100

numbers_list = []
numbers_list.append(numerator)
numbers_list.append(numerator - 1)

sum_is_1 = False
difference_is_0 = False

test_number_1 = (numerator / 100) + ((numerator - 1) / 100)

doubling = 1

while not sum_is_1 and not difference_is_0:
    length = len(numbers_list)
    fractions_total = 0
    doubling = doubling * 2
    for i in range(length):
        numbers_list[i] = numbers_list[i] * 2
    for i in range(length - 1):
        numbers_list.insert(i + 1, numbers_list[i] - 1)
    length = len(numbers_list)
    for i in range(length):
        fractions_total = fractions_total + numbers_list[i] / (100 * doubling)
    test_number_2 = fractions_total
    if fractions_total >= 1:
        sum_is_1 = True
    difference = abs(test_number_1 - test_number_2)
    test_number_1 = test_number_2
    if difference <= 0.0001:
        difference_is_0 = True

print("For fraction " + str(numerator / denominator) +
      ", we can construct fractions <= " + str(numerator / denominator) +
      " such that their sum = 1")

print()

print("The list of numbers that had to be created")
print(numbers_list)

print()

print("the fractions are: ")
for i in range(length):
    print(numbers_list[i] / (100 * doubling))

print()

sum_1 = 0
for i in range(length):
    sum_1 = sum_1 + numbers_list[i] / (100 * doubling)
    sum_2 = sum_1 + numbers_list[i + 1] / (100 * doubling)
    if sum_2 >= 1:
        n = i + 1 # excluded
        break

sum_1 = 0
for i in range(n):
    sum_1 = sum_1 + (numbers_list[i] / (100 * doubling))
other_fraction = round(1 - sum_1, 5)

print("The fractions are: ")
for i in range(n):
    print(numbers_list[i] / (100 * doubling))
print(other_fraction)
What I intend to do is start off with a fraction. Say 3/10. We get to the next smaller fraction 2/10. Then I multiply both fractions by 2/2 = 1 and we get 6/20, 4/20. I can then get an in-between fraction 5/20. I repeat the process. I add these fractions up and check if the sum >= 1.
Reply
#2
This is an unusual way to make a short list when you know all the values.
numbers_list = []
numbers_list.append(numerator)
numbers_list.append(numerator - 1)
Pycharm suggests doing this:
numbers_list = [numerator, numerator - 1]
Pycharm warns about possibly using length and n when they haven't been assigned because the values are only assigned inside a loop, but are used outside the loop. Initialize the values outside the loop to silence the warning.

As for length, are you sure your code is correct? Values are added to numbers_list after calling "length = len(numbers_list)", so length != len(numbers_list) when used here:
sum_1 = 0
for i in range(length):
I doubt that this code does what you think it does.
for i in range(length - 1):
    numbers_list.insert(i + 1, numbers_list[i] - 1)
A demonstration:
numbers = [8, 6, 4, 2]
for i in range(len(numbers) - 1):
    numbers.insert(i + 1, numbers[i] - 1)
print(numbers)
Output:
[8, 7, 6, 5, 6, 4, 2]
I bet you were expecting [8, 7, 6, 5, 4, 3, 2]. As you insert numbers into the list you push numbers to the right. This is what happens.
Output:
[8, 6, 4, 2] [8, 7, 6, 4, 2] insert(1, numbers[0] - 1) [8, 7, 6, 6, 4, 2] insert(2, numbers[1] - 1) [8, 7, 6, 5, 6, 4, 2] insert(3, numbers[2] - 1)
Reading your code is challenging. I would never know what it is doing without your description. When code is too obscure to understand it's purpose, it either means the code is doing something obscure and can never be obvious, or that it is poorly written. If the purpose is obscure, fix the problem by adding comments. If the purpose is clear, write better code.

Writing better code may involve doing research and discovering that Python supports fractions.
from fractions import Fraction


numerator, denominator = map(int, input("Enter Fraction (numerator / denominator) ").split("/"))
fractions = [Fraction(numerator - 1, denominator), Fraction(numerator, denominator)]

# Starting with the fractions above, add new fractions midway between the existing
# fractions while the sum of all fractions <= 1.
while True:
    temp = []
    for a, b in zip(fractions, fractions[1:]):
        temp.extend((a, (a + b) / 2))
    temp.append(fractions[-1])
    if sum(temp) > 1.0:
        break
    fractions = temp

print(f"sum({', '.join(map(str, fractions))}) = {sum(fractions)}")
Output:
Enter Fraction (numerator / denominator) 3 / 10 sum(1/5, 1/4, 3/10) = 3/4
If you want to stay with your code, write it as a python program instead of writing it as a C++ program. Python programs don't do much indexing. Using range(len(alist)) is frowned upon.
from fractions import Fraction

numerator, denominator = map(int, input("Enter Fraction (numerator / denominator) ").split("/"))
numerators = [numerator-1, numerator]

# Starting with the fractions above, add new fractions midway between the
# existing fractions while the sum of all fractions <= 1.
while True:
    d = denominator * 2
    # To insert fraction between N/D and (N+1)/D, multiply by 2/2 and add 1 to numerator.
    # 2N/2D, (2N+1)/2D, 2(N+1)/2D.  This works because numerators are sequential.
    n = list(range(2 * numerators[0], 2 * numerators[-1] + 1))
    if sum(n) > d:
        break
    numerators = n
    denominator = d

fractions = ", ".join(f"{n}/{denominator}" for n in numerators)
print(f"sum({fractions}) = {sum(numerators) / denominator}")

fractions = ", ".join(str(Fraction(n, denominator)) for n in numerators)
print("\nNormalized")
print(f"sum({fractions}) = {sum(numerators) / denominator}")
Output:
Enter Fraction (numerator / denominator) 3/10 sum(4/20, 5/20, 6/20) = 0.75 Normalized sum(1/5, 1/4, 3/10) = 0.75
The most expensive part of finding the solution is creating and summing the numerator list. We don't have to make the numerator list each time. There is an equation that returns the sum of integers in the range A..B.
nmax, denominator = map(int, input("Enter Fraction (numerator / denominator) ").split("/"))
nmin = nmax - 1

# while sum of fraction < 1, split space between fractions in half.
# (N)/D, (N+1)/D becomes 2N/2D, (2N+1)/2D, 2(N+1)/2D.
while (nmax + nmin) * (nmax - nmin + 1) / 2 <= denominator:  # compute sum of numerators.
    nmin, nmax, denominator = nmin * 2, nmax * 2, denominator * 2  # double numerators and denominator.
nmin, nmax, denominator = nmin // 2, nmax // 2, denominator // 2  # We went too far.  Unwind one iteration.

numerators = list(range(nmin, nmax + 1))
fractions = ", ".join(f"{n}/{denominator}" for n in numerators)
print(f"sum({fractions}) = {sum(numerators) / denominator}")
Output:
Enter Fraction (numerator / denominator) 3 / 10 sum(4/20, 5/20, 6/20) = 0.75
If you want first sum >= 1, change the loop to while sum < denominator and delete the unwind after the loop.
Hudjefa likes this post
Reply
#3
(Oct-02-2024, 09:13 PM)deanhystad Wrote: This is an unusual way to make a short list when you know all the values.
numbers_list = []
numbers_list.append(numerator)
numbers_list.append(numerator - 1)
Pycharm suggests doing this:
numbers_list = [numerator, numerator - 1]
Pycharm warns about possibly using length and n when they haven't been assigned because the values are only assigned inside a loop, but are used outside the loop. Initialize the values outside the loop to silence the warning.

As for length, are you sure your code is correct? Values are added to numbers_list after calling "length = len(numbers_list)", so length != len(numbers_list) when used here:
sum_1 = 0
for i in range(length):
I doubt that this code does what you think it does.
for i in range(length - 1):
    numbers_list.insert(i + 1, numbers_list[i] - 1)
A demonstration:
numbers = [8, 6, 4, 2]
for i in range(len(numbers) - 1):
    numbers.insert(i + 1, numbers[i] - 1)
print(numbers)
Output:
[8, 7, 6, 5, 6, 4, 2]
I bet you were expecting [8, 7, 6, 5, 4, 3, 2]. As you insert numbers into the list you push numbers to the right. This is what happens.
Output:
[8, 6, 4, 2] [8, 7, 6, 4, 2] insert(1, numbers[0] - 1) [8, 7, 6, 6, 4, 2] insert(2, numbers[1] - 1) [8, 7, 6, 5, 6, 4, 2] insert(3, numbers[2] - 1)
Reading your code is challenging. I would never know what it is doing without your description. When code is too obscure to understand it's purpose, it either means the code is doing something obscure and can never be obvious, or that it is poorly written. If the purpose is obscure, fix the problem by adding comments. If the purpose is clear, write better code.

Writing better code may involve doing research and discovering that Python supports fractions.
from fractions import Fraction


numerator, denominator = map(int, input("Enter Fraction (numerator / denominator) ").split("/"))
fractions = [Fraction(numerator - 1, denominator), Fraction(numerator, denominator)]

# Starting with the fractions above, add new fractions midway between the existing
# fractions while the sum of all fractions <= 1.
while True:
    temp = []
    for a, b in zip(fractions, fractions[1:]):
        temp.extend((a, (a + b) / 2))
    temp.append(fractions[-1])
    if sum(temp) > 1.0:
        break
    fractions = temp

print(f"sum({', '.join(map(str, fractions))}) = {sum(fractions)}")
Output:
Enter Fraction (numerator / denominator) 3 / 10 sum(1/5, 1/4, 3/10) = 3/4
If you want to stay with your code, write it as a python program instead of writing it as a C++ program. Python programs don't do much indexing. Using range(len(alist)) is frowned upon.
from fractions import Fraction

numerator, denominator = map(int, input("Enter Fraction (numerator / denominator) ").split("/"))
numerators = [numerator-1, numerator]

# Starting with the fractions above, add new fractions midway between the
# existing fractions while the sum of all fractions <= 1.
while True:
    d = denominator * 2
    # To insert fraction between N/D and (N+1)/D, multiply by 2/2 and add 1 to numerator.
    # 2N/2D, (2N+1)/2D, 2(N+1)/2D.  This works because numerators are sequential.
    n = list(range(2 * numerators[0], 2 * numerators[-1] + 1))
    if sum(n) > d:
        break
    numerators = n
    denominator = d

fractions = ", ".join(f"{n}/{denominator}" for n in numerators)
print(f"sum({fractions}) = {sum(numerators) / denominator}")

fractions = ", ".join(str(Fraction(n, denominator)) for n in numerators)
print("\nNormalized")
print(f"sum({fractions}) = {sum(numerators) / denominator}")
Output:
Enter Fraction (numerator / denominator) 3/10 sum(4/20, 5/20, 6/20) = 0.75 Normalized sum(1/5, 1/4, 3/10) = 0.75
The most expensive part of finding the solution is creating and summing the numerator list. We don't have to make the numerator list each time. There is an equation that returns the sum of integers in the range A..B.
nmax, denominator = map(int, input("Enter Fraction (numerator / denominator) ").split("/"))
nmin = nmax - 1

# while sum of fraction < 1, split space between fractions in half.
# (N)/D, (N+1)/D becomes 2N/2D, (2N+1)/2D, 2(N+1)/2D.
while (nmax + nmin) * (nmax - nmin + 1) / 2 <= denominator:  # compute sum of numerators.
    nmin, nmax, denominator = nmin * 2, nmax * 2, denominator * 2  # double numerators and denominator.
nmin, nmax, denominator = nmin // 2, nmax // 2, denominator // 2  # We went too far.  Unwind one iteration.

numerators = list(range(nmin, nmax + 1))
fractions = ", ".join(f"{n}/{denominator}" for n in numerators)
print(f"sum({fractions}) = {sum(numerators) / denominator}")
Output:
Enter Fraction (numerator / denominator) 3 / 10 sum(4/20, 5/20, 6/20) = 0.75
If you want first sum >= 1, change the loop to while sum < denominator and delete the unwind after the loop.

Thank you for the reply. I admit this is not the most readable code that accomplishes the task. Sorry for that.

Yes, I want the sequence {9, 8, 7, 6, 5, 4, 3, 2, 1}. Instead of coding for it by looping down from 9 to 1 I should just create the list my_list = [9, 8, 7, 6, 5, 4, 3, 2, 1] I suppose. My goal is given a fraction (say) 3/5, I want to take 9/10 of 3/5 then 8/10 of 3/5 through to 1/10 of 3/5. I then have a 9 fractions that are less than 3/5 and which are in a some kind of logical sequence Dance . Once I have that, I shift my attention to the smallest fraction in the sequence viz. 1/10 of 3/5 = 3/50. I reiterate the process, taking 9/10 of 3/50, 8/10 of 3/50 and so on. I set some kind of limit to how small the fractions get ... and ... when I add all these fractions and then add the sum to 3/5 I want to know if the sum = 1 and if not at what value the sum levels off/plateaus.

As for the insert command/function, is the following how it works?
fruit_list = ["banana", "apple", "orange"]
number_list.insert(1, "pomegranate")
print(number_list)
Output:
["banana", "pomegranate", "apple", "orange"
Reply
#4
Quote:Yes, I want the sequence {9, 8, 7, 6, 5, 4, 3, 2, 1}. Instead of coding for it by looping down from 9 to 1 I should just create the list my_list = [9, 8, 7, 6, 5, 4, 3, 2, 1]
Would my_list always be [9, 8, 7, 6, 5, 4, 3, 2, 1]? If so, that would be a good way to build the list. If you want to build a list where the starting and ending numbers are not always the same, using range() is a good way to make a list.
my_list = list(range(9, 0, -1))
Save append() for when there is some processing involved when adding items to a list. Be leery about using insert as it can be complicated to insert multiple values int a list (unless you are always inserting at the front). I usually make a new list instead of inserting items into an existing list. If you really want to use insert, insert the last value first and work your way back to the first value. That way you are inserting into the part of the list that has not been moved by other inserts.
Hudjefa likes this post
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Pandas - error when running Pycharm, but works on cmd line zxcv101 2 2,364 Sep-09-2024, 08:03 AM
Last Post: pinkang
  Pycharm error zuri 1 1,053 Nov-01-2023, 03:38 PM
Last Post: deanhystad
  PyCharm Error? coder_sw99 4 2,829 Sep-24-2021, 06:16 PM
Last Post: Yoriz
  Keep getting Session management error when running imshow in pycharm pace 0 2,842 Mar-25-2021, 10:06 AM
Last Post: pace
  REGEX Install Error in PyCharm charlesauspicks 1 3,467 May-14-2020, 08:10 PM
Last Post: buran
  Traceback error in PyCharm but not in other IDEs? devansing 7 8,524 Mar-05-2020, 11:27 AM
Last Post: buran
  Error in importing package in pycharm fullstop 0 2,821 Dec-12-2019, 04:03 PM
Last Post: fullstop
  can't assign to literal error in pycharm ryder5227 2 3,730 Oct-07-2019, 08:57 PM
Last Post: Bmart6969
  Weird error in pycharm TheRedFedora 1 3,308 Mar-11-2018, 09:01 PM
Last Post: Larz60+
  python turtle module in pycharm error sajley 2 14,202 Dec-12-2016, 08:52 PM
Last Post: sajley

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020