Posts: 9
Threads: 2
Joined: May 2020
Hi
Function def_length takes a list as a parameter and returns the length of the list. You must use a loop in your solution. You must not use built-in functions, list methods or string methods in your solution.
Function to_string(my_list, sep=', ') takes a list and a separator value as parameters and returns the string representation of the list (separated by the separator value) in the following form: item1, item2, item3, item4
The separator value must be a default argument.
i.e. sep=’1,1’
Given these parameters,my to_string function is giving an error UnboundLocalError: local variable 'entry' referenced before assignment as I am listing 'entry' inside and outside the loop ( I believe).
I have searched online and some solutions are telling me to make 'entry' Global. I don't know how to do this and also I don't think it's allowed within the rules anyway.
How can I iterate over my_list in the to_string () function and separate out the final entry of the list another way? (within the rules)
def length(my_list):
loop_flag = True
count = 0
for entry in my_list:
count += 1
return count
def to_string(my_list, sep=', '):
result = ''
list_length = length(my_list)
# Loop through indices except last
for entry in range(list_length -1):
result += my_list[entry] + sep
# Add last item on
result += my_list[entry + 1]
return result
Posts: 150
Threads: 3
Joined: Apr 2020
How are you calling your function(s) when you receive the error? As is, your code appears to work correctly when given a list of strings as input:
Output: >>> mystringlist = ['a','b','c','d']
>>> to_string(mystringlist)
'a, b, c, d'
It throws type errors for a list of anything other than strings, but that could be fixed by using the str() function when building your result in to_string(). (That appears to be within the rules the way I am reading them, as it only mentions not using built-in functions for the length() part of the assignment.)
Posts: 9
Threads: 2
Joined: May 2020
Jun-01-2020, 11:23 AM
(This post was last modified: Jun-01-2020, 11:58 AM by Yoriz.)
I was calling 3 lists to verify if the function was coded within the specs.
My file name was called list_function
import list_function
print("\nStart Testing!")
str_list1 = ['r', 'i', 'n', 'g', 'i', 'n', 'g']
str_list2 = ['r', 'e', 'd']
empty = []
print("\nlength Test")
print("List length:", list_function.length(str_list1))
print("List length:", list_function.length(empty)) The issue was that it gave this error when calling the last print function (empty)
Error: File line 24, in <module>
print("List is:", list_function.to_string(empty))
File line 24, in to_string
result += my_list[entry + 1]
UnboundLocalError: local variable 'entry' referenced before assignment
This was solved by adding the line
if not my_list:
return result Is this a clean way of doing things to account for the empty print function?
def length(my_list):
loop_flag = True
count = 0
for entry in my_list:
count += 1
return count
def to_string(my_list, sep=', '):
result = ''
list_length = length(my_list)
if not my_list:
return result
# Loop through indices except last entry.
for entry in range(list_length -1):
result += my_list[entry] + sep
# Add last entry on.
result += my_list[entry + 1]
return result
Posts: 150
Threads: 3
Joined: Apr 2020
Aha! When I was testing your functions I did not try an empty list, but now this makes sense. Your for loop would not execute with list_length having a value of 0, so the variable "entry" had not been assigned a value when you reached the "Add last entry" part of the code.
Yes, I think your way of handling the empty list is simple and works effectively. Are you expected to account for any scenarios other than a valid list of stings and an empty list? If not, it looks like you are done.
One thing... It doesn't appear that you ever use your loop_flag variable, so you should be able to get rid of line 3.
Posts: 9
Threads: 2
Joined: May 2020
Jun-01-2020, 12:00 PM
(This post was last modified: Jun-01-2020, 12:08 PM by drewbty.)
Thanks mate. No that's all the scenarios covered. Yes good pickup, that is just a random line there that I thought I needed to do something with earlier but had left in by mistake.
While I have you... do you know what is wrong with this?
def insert_value works perfect.
def_remove_value does not.
I know I shouldn't have the empty = '' there as that actually puts '' into the index but other than that it seems like it should just be the flipping of my insert_value function, which is the only function working as intended right now.
There are a couple of rules again... You must use a loop in your solution. You may make use of the list_name.append(item) method in order to build the new list. You must not use built-in functions (other than the range() function), slice expressions, list methods (other than the append() method) or string methods in your solution.
What I'm calling is this:
print("\ninsert_value Test")
str_list3 = ['one','three','four', 'five', 'six']
new_list = list_function.insert_value(str_list3, 'two', 1)
print(new_list)
str_list4 = ['i', 't']
str_list4 = list_function.insert_value(str_list4, 'p', 0)
print(str_list4)
str_list4 = list_function.insert_value(str_list4, 's', -1)
print(str_list4)
str_list4 = list_function.insert_value(str_list4, 's', 7)
print(str_list4)
print("\nremove_value Test")
str_list5 = ['r','i','n','g']
new_list = list_function.remove_value(str_list5, 2)
print(new_list)
new_list = list_function.remove_value(str_list5, -1)
print(new_list)
new_list = list_function.remove_value(str_list5, 10)
print(new_list) def insert_value(my_list, value, insert_position):
new_list = []
list_length = length(my_list)
list_index = 0
value_position = insert_position
#if insert pos is not valid
if insert_position <= 0:
value_position = 0
elif insert_position > list_length - 1:
value_position = list_length
while list_index < list_length:
if list_index == value_position:
new_list.append(value)
new_list.append(my_list[list_index])
list_index += 1
if value_position == list_length:
new_list.append(value)
return new_list
# Function remove_value() - place your own comments here... : )
def remove_value(my_list, remove_position):
new_list = []
list_length = length(my_list)
list_index = 0
value_position = remove_position
empty = ''
if remove_position <= 0:
value_position = 0
elif remove_position > list_length -1:
value_position = list_length
while list_index < list_length:
if list_index == value_position:
new_list.append(empty)
new_list.append(my_list[list_index])
list_index += 1
if value_position == list_length:
new_list.append(empty)
return new_list
Final part is this:
7. Write a function called reverse(my_list, number=-1) that takes a list and a number as parameters. The function returns a copy of the list with the first number of items reversed.
Again there are rules:
The number parameter must be a default argument.
- If the default argument for number is given in the function call, only the first number of items are reversed.
- If the default argument for number is not provided in the function call, then the entire list is reversed. Check for the number value exceeding the list bounds (i.e. is greater than the length of the list).
- If the number value exceeds the list bounds, then make the number value the length of the list.
- If the number value entered is less than two, then return a copy of the list with no items reversed.
I will get stuck on this for sure and be posting more jumbled up code that I would like a hint of two on :D
Posts: 353
Threads: 13
Joined: Mar 2020
Jun-01-2020, 12:10 PM
(This post was last modified: Jun-01-2020, 12:11 PM by pyzyx3qwerty.)
What is remove_value supposed to do? You have only told us about insert_value and to_string
Posts: 9
Threads: 2
Joined: May 2020
Yea soz
remove_value(my_list, remove_position) takes a list and a remove_position as parameters. The function returns a copy of the list with the item at the index specified by remove_position, removed from the list.
I will be using the earlier def length(my_list): function throughout to initialise list_length as length(my_list)
Posts: 150
Threads: 3
Joined: Apr 2020
Jun-01-2020, 12:36 PM
(This post was last modified: Jun-01-2020, 12:36 PM by GOTO10.)
(Jun-01-2020, 12:00 PM)drewbty Wrote: def insert_value works perfect.
def_remove_value does not.
I know I shouldn't have the empty = '' there as that actually puts '' into the index
You have correctly identified your problem. You are using new_list.append(empty), which adds the value of empty to the list, when what you really want to do here is nothing at all and then move on to the next index. Take another look at it and find a way to accomplish that. Just keep in mind that you don't need to add anything when you get to the remove_position, you just want to bypass it.
Also, when you are given an index out of range like in the line below, do you actually want to remove the last index or do you want to just ignore this? (I'm genuinely not certain what you want here.) Adjust your code according to your desired outcome.
new_list = list_function.remove_value(str_list5, 10) *Edit* - One other possible issue is that for a value less than 0 you are changing the index (value_position variable) to 0. Is that really what you want to do?
Posts: 9
Threads: 2
Joined: May 2020
Jun-02-2020, 06:28 AM
(This post was last modified: Jun-02-2020, 06:28 AM by drewbty.)
The following rules apply to insert_value() and remove_value()
Check for the insert_position value exceeding the list (my_list) bounds.
- If the insert_position is greater than the length of the list, insert the value at the end of the list.
- If the insert_position is less than or equal to zero, insert the value at the start of the list.
Check for the remove-position value exceeding the list (my_list) bounds.
- If the remove_position is greater than the length of the list, remove the item at the end of the list.
- If the remove_position is less than or equal to zero, remove the item stored at the start of the list.
The following rules apply to reverse()
The number parameter must be a default argument.
- If the default argument for number is given in the function call, only the first number of items are reversed.
- If the default argument for number is not provided in the function call, then the entire list is reversed. Check for the number value exceeding the list bounds (i.e. is greater than the length of the list).
- If the number value exceeds the list bounds, then make the number value the length of the list.
- If the number value entered is less than two, then return a copy of the list with no items reversed.
I'm had a good crack at the remove and reverse functions and I think I fully understand what I'm trying to do, I just lack the python knowledge to implement it.
e.g. here I have 'pass' in the remove function and .reverse in the reverse function I know isn't right (and not allowed under the rules of only being able to use append and range anyhow)
def insert_value(my_list, value, insert_position):
new_list = []
list_length = length(my_list)
list_index = 0
value_position = insert_position
#if insert position is not valid.
if insert_position <= 0:
value_position = 0
elif insert_position > list_length - 1:
value_position = list_length
while list_index < list_length:
if list_index == value_position:
new_list.append(value)
new_list.append(my_list[list_index])
list_index += 1
if value_position == list_length:
new_list.append(value)
return new_list
def remove_value(my_list, remove_position):
new_list = []
list_length = length(my_list)
list_index = 0
value_position = remove_position
#if remove position is not valid.
if remove_position <= 0:
value_position = 0
elif remove_position > list_length -1:
value_position = list_length
#iterate through the list_length
while list_index < list_length:
# remove/pass once iteration lands on the value position
if list_index == value_position:
pass
new_list.append(my_list[list_index])
list_index += 1
# if at the end of the list, also remove/pass
if value_position == list_length:
pass
return new_list
def reverse(my_list, number=-1):
new_list = []
list_length = length(my_list)
list_index = 0
reverse_pos = number
#if number value entered is less than 2, return copy of list (nothing reversed)
if reverse_pos <= 1:
my_list = new_list
#if no number given, use the default value of -1
elif reverse_pos == -1:
reverse_pos = -1
#if the position exceeds list length, make the reverse pos to be the length of the list.
elif reverse_pos > list_length -1:
reverse_pos = list_length -1
while list_index < list_length:
#iterate through and once we reach the reverse_pos
if list_index == reverse_pos:
#reverse my_list at that point from the range of 0:reverse_pos
new_list.reverse(my_list[0:list_index])
#append all values onto the new_list
new_list.append(my_list[list_index])
if list_index > reverse_pos:
#append all values onto the new_list
new_list.append(my_list[list_index])
new_list.append(my_list[list_index])
list_index += 1
return new_list I'm using this to call in my file name called list_function.py
print("\ninsert_value Test")
str_list3 = ['one','three','four', 'five', 'six']
new_list = list_function.insert_value(str_list3, 'two', 1)
print(new_list)
str_list4 = ['i', 't']
str_list4 = list_function.insert_value(str_list4, 'p', 0)
print(str_list4)
str_list4 = list_function.insert_value(str_list4, 's', -1)
print(str_list4)
str_list4 = list_function.insert_value(str_list4, 's', 7)
print(str_list4)
print("\nremove_value Test")
str_list5 = ['r','i','n','g']
new_list = list_function.remove_value(str_list5, 2)
print(new_list)
new_list = list_function.remove_value(str_list5, -1)
print(new_list)
new_list = list_function.remove_value(str_list5, 10)
print(new_list)
print("\nreverse Test")
str_list6 = ['e', 'd', 'u', 'd']
str_list7 = ['m', 'o', 'b', 'b', 'e', 'd']
new_list = list_function.reverse(str_list6, 4)
print(new_list)
new_list = list_function.reverse(str_list7, 3)
print(new_list)
new_list = list_function.reverse(str_list6)
print(new_list)
Posts: 9
Threads: 2
Joined: May 2020
I've figured out the remove position (now solved) and thrown all dices are the reverse function but no joy.
The line element -= 1 is not valid ( I want to reverse from this point). Any help would be appreciated to tidy this up.
def remove_value(my_list, remove_position):
new_list = []
list_length = length(my_list)
list_index = 0
value_position = remove_position
#if remove position is not valid.
if remove_position <= 0:
value_position = 0
elif remove_position > list_length -1:
value_position = list_length -1
#iterate through the range of my_list
while list_index < list_length:
# only append to new_list when the list_index doesn't land on the value_position
if list_index != value_position:
new_list.append(my_list[list_index])
list_index += 1
return new_list
def reverse(my_list, number=-1):
new_list = []
list_length = length(my_list)
list_index = 0
reverse_pos = number
#if number value entered is less than 2, return copy of list (nothing reversed)
if reverse_pos == -1:
reverse_pos = -1
elif reverse_pos <= 1:
my_list = new_list
#if the position exceeds list length, make the reverse pos to be the length of the list.
elif reverse_pos > list_length -1:
reverse_pos = list_length -1
else:
reverse_pos = number
while list_index < list_length:
#iterate through and once we reach the reverse_pos
for element in my_list:
if list_index == reverse_pos:
new_list.append(my_list[list_index])
element -= 1
elif list_index != reverse_pos:
new_list.append(my_list[list_index])
element += 1
list_index += 1
return new_list
|