Python Counting the exchanges in a selection sort - python-3.x

I apologize as this is my first question on this site and it is extremely basic, but I am somewhat lost in a current lab I am trying to complete.
Currently I am attempting to count the amount of exchanges(Or swaps? Not sure on the right word there!) during a selection sort throughout the passes.
Now according to my current understanding, the replacement section of our formula is traversing my list. However, it doubles the amount of swaps it is actually supposed to be spitting back at me. Now this would lead me to believe an if statement might need to be operating in the outer loop, but that doesn't seem quite right to me.
An example of what I have done to cause this problem below. I am curious if I am on the right path or should I slash and burn or go back to the drawing board.
The reason I am counting them independently is I am displaying when there is a swap then a grand total of all the swaps. Which I find to be a bit ironic as with a selection sort you can only have 1 swap per pass?
Any case, I apologize for the rather basic question, but I seem to be missing something so I was hoping someone could point me in the right direction of if I should be focusing on the outer loop to determine the exchanges?
print( "Original list:" , a_list, "\n" )
count =1
n = len(a_list)
comp = n -1
exchanges=1
comp_total=0
exch_total=0
for end in range(n, 1, -1): # Each pass starts here
#Setting our running total to adjust for previous value.
comp_total +=comp-(count-1)
print("Pass", count, ":", "Comparisons:",comp-(count-1), "\tExchanges:", exchanges,"\n", end="\t ")
count += 1
# --- Search for Largest ---
min_position = 0
for i in range(1, end):
if a_list[i] > a_list[min_position]: # Perform n
min_position = i
exchanges = 0
exch_total +=1
else:
exchanges = 1
# --------------------------
temp = a_list [end - 1] # Perform exchange
a_list [end - 1] = a_list [min_position]
a_list [min_position] = temp
print(a_list)
print()
print("\tTotal Comparisons:",comp_total, "Total Exchanges:", exch_total)
selection_sort(a_list)

In this case,
My issue was the the fact my print statement was before the actual loop, this was throwing off my count, by placing the if statement past this point, I was able to get an accurate running total!
Cheers!

Related

How to repeat an iteration with the same amount of jump

Wish you are all well.
I am super new in Python and at the moment am having a difficulty to construct a solution for the problem I am having, I doubt I could present the problems correctly but here goes:
I have to make a variable with the name current position and init value of 0 and should be incremented by the number of jump.
I have to make two variables that receive integer input. Jump and Target.
I have to define the number range, between 0 to 9, so range(0, 10).
The jump defines how many number does the code have to skip when it starts to iterate.
The target is the number of which when the jump lands on it, it will exit the loop.
For example, if the target is number 1 and the jump is 2, it means, in the first jump, it will skip the target. And it will continue to do so until it lands on 1.
The problem is, I could not figure out what the problem is.
Here is my humble code...
jump = int(input())
target = int(input())
current_position = 0
for i in range(0, 10):
current_position += jump
if jump == target:
print(current_position, end=" ")
I really need some advise here, please.
Thank you.
The series/range you have is increasing and there no indication or point in your requirements about a decrement, so not sure how last number will go to 0.
Please refer to code below, see if this is something you are looking for -
jump = int(input("Enter value for jump -> "))
target = int(input("Enter value for target -> "))
current_position = 0
for current_position in range(jump,10, jump):
print (current_position)
if current_position == target:
print ('Target found and current position = ', current_position)
break
elif (current_position == len(range(0,10))-jump):
print ('Target not found.')
break
else:
continue

How do I achieve this following function only using while loop?

I'm currently working on this problem that ask me to generate an arrow pattern using loops function that looks something like this:
"How many columns? 3"
*
*
*
*
*
I know I can do this with for loop(probably more efficient too), but that is not what I aimed for. I wanted to achieve this only using while loop.
I have some ideas:
1. I set up a control variable and an accumulator to control the loop
2. I then write 2 separate loops to generate the upper and lower part of the pattern. I was thinking about inserting the space before the asterisks using method like this:
(accumulator - (accumulator - integer)) * spaces.
#Ask the user how many column and direction of column
#they want to generate
Keep_going = True
Go = 0
while keep_going:
Column_num = int(input("How many columns? "))
if Column_num <= 0:
print("Invalid entry, try again!")
else:
print()
Go = 1
#Upper part
while Keep_going == True and Go == 1:
print("*")
print(""*(Column_num - (Column_num - 1) + "*")
...but I soon realized it wouldn't work because I don't know the user input and thus cannot manually calculate how many spaces to insert before asterisks. Now everything on the internet tells me to use for loop and range function, I could do that, but I think that is not helpful for me to learn python since I couldn't utilize loops very well yet and brute force it with some other method just not going to improve my skills.
I assume this is achievable only using while loop.
#Take your input in MyNumber
MyNumber = 5
i = 1
MyText = '\t*'
while i <=MyNumber:
print(MyText.expandtabs(i-1))
i = i+1
i = i-1
while i >=1:
print(MyText.expandtabs(i-1))
i = i-1
Python - While Loop
Well first you have to understand that a while loop loops until a requirement is met.
And looking at your situation, to determine the number of spaces before the * you should have an ongoing counter, a variable that counts how many spaces are needed before you continue. For example:
###Getting the number of columns###
while True:
number=int(input('Enter number of rows: '))
if number<=0:
print('Invalid')
else:
###Ending the loop###
break
#This will determine the number of spaces before a '*'
counter=0
#Loops until counter equals number
while counter!=number:
print(" "*counter + "*")
#Each time it loops the counter variable increases by 1
counter=counter+1
counter=counter-1
#Getting the second half of the arrow done
while counter!=0:
counter=counter-1
print(" "*counter + "*")
Please reply if this did not help you so that i can give a more detailed response

Python 3.7.3 Inconsistent code for song guessing code, stops working at random times

I have a python code that is a song guessing game, you are given the artist and the songs first letter, I used 2 2d arrays with on being the artist and the other being the song. I know I should've done a 3d array though to change it this late into my code I'd have to restructure the whole code and I wouldn't have time. Here is the appropriate code below:
attemptnum = 5
attempts = 0
for x in range (10):
ArtCount = len(artist)
print(ArtCount)
randNum = int(random.randint(0, ArtCount))
randArt = artist[randNum]
ArtInd = artist.index(randArt)# catches element position (number)
songSel = songs[randNum]
print ("The artist is " + randArt)
time.sleep(1)
print( "The songs first letter be " + songSel[0])
time.sleep(1)
print("")
question = input("What song do you believe it to be? ")
if question == (songSel) or ("c"):
songs.remove(songSel)
artist.remove(randArt)
print ("Correct")
print ("Next Question")
else:
attempts = attempts + 1
att = attemptnum = attemptnum - attempts
print("")
print("Wrong,")
print (att) and print (" attempts left.")
print("")
time.sleep(0.5)
if attempts == 5:
print("GAME OVER")
#input leaderboard here
print("Exiting in 3 seconds")
time.sleep(3)
exit()
Apologies if my code isn't so polished, this is a project for school. So what this code does is randomly a number from 0 to the number of how many elements the artist's list has. It then chooses an artist using the random number, it catches the number used with index so that it can be used on the songs array to get the corresponding song (I know very bad) It pitches the question and shows the first letter of the song. If you get the song you get the same code again but with the prior song and artist removed to prevent dupes. That's where the problem comes in, when usually running the code it'll randomly give me the error where the element I'm trying to output is not in the list:
randArt = artist[randNum]
IndexError: list index out of range
This can happen anywhere throughout the code when you're being asked a question, you can get to question 3 and get the error, or not even get to question 9 and get the error. It's completely random. I feel like its trying to occasionally get a hold of an artist and song that's been removed but that doesn't make sense since it only chooses from the amount counted on the list, not the original 10. I'm not sure if my way of saying it is right or if any one would understand, because I sure don't. To clarify, my code counts how many elements there are in the list, uses that number to find a song and artist, then removes it after to stop duping, but from what I can see it seems like it's trying to find and element simply out of the range of how many elements there actually are. Thanks for bearing with my amateur code.
random.randint is inclusive in both ends. randint(0, 10) will return a number in the range
0 <= _ <= 10.
However Python uses 0-based indexes.
If li is [1, 2, 3] then len(li) is 3, but li[3] does not exist.
Only li[0], li[1] and li[2] do.
When you are doing
ArtCount = len(artist)
randNum = int(random.randint(0, ArtCount))
randArt = artist[randNum]
You are asking for a number in the range 0 <= n <= len(artist). If n == len(artist) then artist[n] will cause an IndexError.
BTW, randint returns an int (hence the int in its name). int(randint(...)) is totally unnecessary.
You should either ask for a random number in the range 0 <= n <= len(artist) - 1 or simply use random.choice:
randArt = random.choice(artist)
You may want to catch an IndexError just in case artist is an empty list:
try:
randArt = random.choice(artist)
except IndexError:
print('artist list is empty')

Multiplication table in Python with # on all even numbers

I am trying to create a python multiplication table from 2 - 10. If you enter an invalid number it will tell you that it is an invalid entry and ask you to input a number again. It is also supposed to put a # on all even numbers. I am having trouble continuing after an invalid entry and also putting a # on all even numbers. My current code is below
def main():
rows = int(input("What size multiplication table would you like (2-10): "))
if rows <=1 or rows >10:
print (" Invalid Entry - Enter a number between 2 - 10 ")
else:
counter = 0
multiplicationTable(rows,counter)
def multiplicationTable(rows,counter):
size = rows + 1
for i in range (1,size):
for nums in range (1,size):
value = i*nums
print(value,sep=' ',end="\t")
counter += 1
if counter%rows == 0:
print()
else:
counter
main()
I am typing this on my phone so bear with me.
Since you are trying to only get a certain input, you want to have a loop so that we can keep asking the user to enter a number if it is outside the range we want.
So in a generic example where we repeatedly ask a user for a certain input:
While True:
rows = int(input(“enter size: “))
if 1 <= rows < 10:
multiplicationTable(rows, 0)
break
else:
print(“Invalid”)
continue
While True: will run infinitely naturally. However, the magic is in the continue and break statements. continue will make it restart at the top of the loop and break will make it exit the loop after the process is done.
note:
Some programmers consider it bad practice to use the loops in this fashion because it could imply poor logic.
If you need help with an alternate solution I can try and help when I get to my computer.
Best of luck!

Beginner Python: Where to "while"?

tl;dr: My code "works", in that it gives me the answer I need. I just can't get it to stop running when it reaches that answer. I'm stuck with scrolling back through the output.
I'm a complete novice at programming/Python. In order to hone my skills, I decided to see if I could program my own "solver" for Implied Equity Risk Premium from Prof. Damodaran's Valuation class. Essentially, the code takes some inputs and "guesses and tests" a series of interest rates until it gets a "close" value to the input.
Right now my code spits out an output list, and I can scroll back through it to find the answer. It's correct. However, I cannot for the life of me get the code to "stop" at the correct value with the while function.
I have the following code:
per = int(input("Enter the # of periods forecast ->"))
divbb = float(input("Enter the initial dividend + buyback value ->"))
divgr = float(input("Enter the div + buyback growth rate ->"))
tbondr = float(input("Enter the T-Bond rate ->"))+0.000001
sp = int(input("Enter the S&P value->"))
total=0
pv=0
for i in range(1,10000):
erp = float(i/10000)
a = divbb
b = divgr
pv = 0
temppv = 0
print (sp-total, erp)
for i in range(0, per):
a=a * (1+b)
temppv = a / pow((1+erp),i)
pv=pv+temppv
lastterm=(a*1+tbondr)/((erp-tbondr)*pow(1+erp,per))
total=(pv+lastterm)
From his example, with the inputs:
per = 5
divbb = 69.46
divgr = 0.0527
tbondr = 0.0176
sp = 1430
By scrolling back through the output, I can see my code produces the correct minimum at epr=0.0755.
My question is: where do I stick the while to stop this code at that minimum? I've tried a lot of variations, but can't get it. What I'm looking for is, basically:
while (sp-total) > |1|, keep running the code.
per = 5
divbb = 69.46
divgr = 0.0527
tbondr = 0.0176
sp = 1430
total=0
pv=0
i = 1
while(abs(sp-total)) > 1:
erp = i/10000.
a = divbb
b = divgr
pv = 0
temppv = 0
print (sp-total, erp)
for j in range(0, per):
a=a * (1+b)
temppv = a / pow((1+erp),j)
pv=pv+temppv
lastterm=(a*1+tbondr)/((erp-tbondr)*pow(1+erp,per))
total=(pv+lastterm)
i += 1
should work. Obviously, there are a million ways to do this. But the general gist here is that the while loop will stop as soon as it meets the condition. You could also test every time in the for loop and include a break statement, but because you don't know when it will stop, I think a while loop is better in this case.
Let me give you a quick rundown of two different ways you could solve a problem like this:
Using a while loop:
iterator = start value
while condition(iterator):
do some stuff
increment iterator
Using a for loop:
for i in xrange(startvalue, maxvalue):
do some stuff
if condition:
break
Two more thing: if you're doing large ranges, use the generator xrange. Also, it's probably a bad idea to reuse i inside your for loop.
I recommend CS101 from Udacity.com for learning Python. Also, if you're interested in algorithms, work through the problems at projecteuler.com

Resources