Minimum and Maximum query not working properly (Python 3.5) - python

I wonder if you can help because I've been looking at this for a good half hour and I'm completely baffled, I think I must be missing something so I hope you can shed some light on this.
In this area of my program I am coding a query which will search a list of tuples for the salary of the person. Each tuple in the list is a separate record of a persons details, hence I have used two indexes; one for the record which is looped over, and one for the salary of the employee. What I am aiming for is for the program to ask you a minimum and maximum salary and for the program to print the names of the employees who are in that salary range.
It all seemed to work fine, until I realised that when entering in the value '100000' as a maximum value the query would output nothing. Completely baffled I tried entering in '999999' which then worked and all records were print. The only thing that I can think of is that the program is ignoring the extra digit, which I could not figure out why this would be?!
Below is my code for that specific section and output for a maximum value of 999999 (I would prefer not to paste the whole program as this is for a coursework project and I want to prevent anyone on the same course potentially copying my work, sorry if this makes my question unclear!):
The maximum salary out of all the records is 55000, hence why it doesnt make sense that a minimum of 0 and maximum of 100000 does not work, but a maximum of 999999 does!
If any more information is need to help, please ask! This probably seems unclear but like I said above, I dont want anyone from the class to plagiarise and my work to be void because of that! So I have tried to ask this without posting all my code on here!

Given your use of the print function (instead of the Python 2 print statement), it looks like you're writing Python 3 code. In Python 3, input returns a str. I'm guessing your data is also storing the salaries as str (otherwise the comparison would raise a TypeError). You need to convert both stored values and the result of input to int so it performs numerical comparisons, not ASCIIbetical comparisons.

When you read in from standard input in Python, no matter what input you get, you receive the input as a string. That means that your comparison function is resulting to:
if tuplist[x][2] > "0" and tuplist[x][2] < "999999" :
Can you see what the problem is now? Because it's a homework assignment, I don't want to give you the answer straight away.

Related

Iterating over array and slicing or making changes in Python

I'm about to pull my hair out on this. I'm not sure why the index in my array is not being implemented in the second column.
I created this array - project_information :
project_information.append([proj_id,project_text])
When I print this out, I get the rows and columns. It contains about 40 rows.
When I iterate through it to print out the contents, everything comes out fine. I am using this:
for i in range(0,len(project_information)):
project_id = project_information[i][0]
project_text = project_information[i][1]
print(project_id)
print (project_text)
The project_text column contains text, while the project_id contains integers. It prints out perfectly, and the index, changes for both project_id and project_text.
However, I need to use the project_text in a different way, and I am really struggling with this. I need to slice the text to a shorter text for reuse. To do this, I tried:
for i in range(0,len(project_information)):
project_id = project_information[i][0]
project_text = project_information[i][1]
print(project_id)
print (project_text)
if len(project_text) > 5000:
trunc_proj_text = project_text[:1000]
else:
trunc_proj_text = project_text
print (project_id)
print(trunc_proj_text)
The problem I'm having here is that though the project_id column is being iterated through properly, the project_text is not. What I am getting is just the text in the first row for the project_text, sliced, and repeated for as many times as the length of the array.
I have tried different ways, and also a while loop, but it is still not working.
I've also looked at these answers for reference - Slicing,indexing and iterating over 2D Numpy arrays,Efficient iteration over slice in Python, iteration over list slices, and I can't seem to see how they can be applied to my problem.
I'm not well-versed in using Numpy, so is this something that it could help with? I'm well aware this might be simple and I'm missing it because I've been working on various aspects of this project for the past weeks, so I would appreciate a bit of consideration in this.
Thanks in advance.
The problem was with the input list here, so the slicing with this code does in fact work. The code to create the input array has now been fixed. The original code to create the input list was concatenating the strings for each entry, so the project_texts for each appeared different from the end, but all had the same beginning. But viewing this on a console, it was hard to see.

trying add two numbers ,by reading them from list and print their index no. from their actual list

Given an array of integers, return indices of the two numbers such that they add up to a specific target.
,in each input would have not use the same element twice.
class solution():
def __init__(self,array_num,target_num):
self.array_num=array_num
self.target_num=target_num
for t in self.array_num:
for b in self.array_num:
e=t+b
w=self.array_num.index(t),self.array_num.index(b)
y=list(w)
if e==self.target_num:
if y==[0,0]:
break
else:
print(y)
p=[3,3]
so=solution(p,6)
output
[] or nothing
expected output
[0,1]
The problem is that you are asking the list to give you the index if a number like this:
self.array_num.index(t)
This will always give you the first occurrence, which is 0 here, although the loop is actually at the second position with index 1.
To avoid that, reverse the logic: create the loop for the index (use len() and range()), then get the number at that position.
As this question sounds like homework or school assignment, I'll not post a full solution. It should be possible to solve the problem now.
More hints to make your teacher happy:
[0, 0] is not the only solution that results in 6. You want to exclude other invalid combinations as well. Pro tip: there's a nice solution that doesn't require any check and will run faster. It's easy to find once you switched the logic.
Currently you do all work in the constructor of the object. Maybe you want a method that does the actual calculation.
Your variable names are not self-explaining. Don't use so many single letter variables.

How to impliment a binary search on a list created from a file

This is my first post, please be gentle. I'm attempting to sort some
files into ascending and descending order. Once I have sorted a file, I am storing it in a list which is assigned to a variable. The user is then to choose a file and search for an item. I get an error message....
TypeError: unorderable types; int() < list()
.....when ever I try to search for an item using the variable of my sorted list, the error occurs on line 27 of my code. From research, I know that an int and list cannot be compared, but I cant for the life of me think how else to search a large (600) list for an item.
At the moment I'm just playing around with binary search to get used to it.
Any suggestions would be appreciated.
year = []
with open("Year_1.txt") as file:
for line in file:
line = line.strip()
year.append(line)
def selectionSort(alist):
for fillslot in range(len(alist)-1,0,-1):
positionOfMax=0
for location in range(1,fillslot+1):
if alist[location]>alist[positionOfMax]:
positionOfMax = location
temp = alist[fillslot]
alist[fillslot] = alist[positionOfMax]
alist[positionOfMax] = temp
def binarySearch(alist, item):
first = 0
last = len(alist)-1
found = False
while first<=last and not found:
midpoint = (first + last)//2
if alist[midpoint] == item:
found = True
else:
if item < alist[midpoint]:
last = midpoint-1
else:
first = midpoint+1
return found
selectionSort(year)
testlist = []
testlist.append(year)
print(binarySearch(testlist, 2014))
Year_1.txt file consists of 600 items, all years in the format of 2016.
They are listed in descending order and start at 2017, down to 2013. Hope that makes sense.
Is there some reason you're not using the Python: bisect module?
Something like:
import bisect
sorted_year = list()
for each in year:
bisect.insort(sorted_year, each)
... is sufficient to create the sorted list. Then you can search it using functions such as those in the documentation.
(Actually you could just use year.sort() to sort the list in-place ... bisect.insort() might be marginally more efficient for building the list from the input stream in lieu of your call to year.append() ... but my point about using the `bisect module remains).
Also note that 600 items is trivial for modern computing platforms. Even 6,000 won't take but a few milliseconds. On my laptop sorting 600,000 random integers takes about 180ms and similar sized strings still takes under 200ms.
So you're probably not gaining anything by sorting this list in this application at that data scale.
On the other hand Python also includes a number of modules in its standard libraries for managing structured data and data files. For example you could use Python: SQLite3.
Using this you'd use standard SQL DDL (data definition language) to describe your data structure and schema, SQL DML (data manipulation language: INSERT, UPDATE, and DELETE statements) to manage the contents of the data and SQL queries to fetch data from it. Your data can be returned sorted on any column and any mixture of ascending and descending on any number of columns with the standard SQL ORDER BY clauses and you can add indexes to your schema to ensure that the data is stored in a manner to enable efficient querying and traversal (table scans) in any order on any key(s) you choose.
Because Python includes SQLite in its standard libraries, and because SQLite provides SQL client/server semantics over simple local files ... there's almost no downside to using it for structured data. It's not like you have to install and maintain additional software, servers, handle network connections to a remote database server nor any of that.
I'm going to walk through some steps before getting to the answer.
You need to post a [mcve]. Instead of telling us to read from "Year1.txt", which we don't have, you need to put the list itself in the code. Do you NEED 600 entries to get the error in your code? No. This is sufficient:
year = ["2001", "2002", "2003"]
If you really need 600 entries, then provide them. Either post the actual data, or
year = [str(x) for x in range(2017-600, 2017)]
The code you post needs to be Cut, Paste, Boom - reproduces the error on my computer just like that.
selectionSort is completely irrelevant to the question, so delete it from the question entirely. In fact, since you say the input was already sorted, I'm not sure what selectionSort is actually supposed to do in your code, either. :)
Next you say testlist = [].append(year). USE YOUR DEBUGGER before you ask here. Simply looking at the value in your variable would have made a problem obvious.
How to append list to second list (concatenate lists)
Fixing that means you now have a list of things to search. Before you were searching a list to see if 2014 matched the one thing in there, which was a complete list of all the years.
Now we get into binarySearch. If you look at the variables, you see you are comparing the integer 2014 with some string, maybe "1716", and the answer to that is useless, if it even lets you do that (I have python 2.7 so I am not sure exactly what you get there). But the point is you can't find the integer 2014 in a list of strings, so it will always return False.
If you don't have a debugger, then you can place strategic print statements like
print ("debug info: binarySearch comparing ", item, alist[midpoint])
Now here, what VBB said in comments worked for me, after I fixed the other problems. If you are searching for something that isn't even in the list, and expecting True, that's wrong. Searching for "2014" returns True, if you provide the correct list to search. Alternatively, you could force it to string and then search for it. You could force all the years to int during the input phase. But the int 2014 is not the same as the string "2014".

Putting an int and str into one output in an input(python)

E.g "input("what is",a,b,c,"?")"
However this doesn't work
a is a random number
b is a + sign
c is another random number
When i try and run the code it says:
:TypeError: input expected at most 1 arguments, got 5
p.s im am new to coding so please use simple language so that i can understand
I think your issue is a fundamental misunderstanding of how input works. It's really difficult to parse out what you're trying to do with the input, but I'll give it a shot.
The 'input' function asks the user for exactly that, input. It will then store that input somehow. Usually you'll want to assign it to a variable, as in:
inputString = input('What is a, b, c')
From there, you could apply formatting to inputString, and then assign that to variables as well. Reading the official documentation, as well as doing a cursory search for the '.split()' method will likely give you what you're looking for.
This existing SO question may also yield some helpful information for you
In my experience, Google is your absolute best friend, especially when starting out. I'm not here to flame you and put you down, but the majority of SO users will expect you to exhaust all your personal resources and do at least the minimum amount of basic research before posting here. All I looked for to get to the linked post was "getting multiple variables from user input python" in Google. Taking care of this beforehand will save you a lot of negative votes, and generally yield more helpful, positive experiences here.
Edit: It should be noted that a lot of what I covered in the last paragraph is clearly outlined in the rules of the site. Not following them will have negative repercussions outside of the dislike of your peers.
You need to provide a single string argument when calling input, i.e. input("enter input now"). If b is always a +, try input("what is {}+{}".format(a,c)). The first argument in format will replace the first {} in the string, the second argument in format will replace the second {} in the string, and so on.
import numpy as np
a= np.random.randint(0,10)
b = "+"
c = np.random.randint(0,10)
print("what is 'a,b,c'", eval(str(a)+str(b)+str(c)))
If you want to input a random number and assign it to a and b. You should use following:
a = input("Value of a?\n")
b = input("Value of b?\n")

How to Sort Arrays in Dictionary?

I'm currently writing a program in Python to track statistics on video games. An example of the dictionary I'm using to track the scores :
ten = 1
sec = 9
fir = 10
thi5 = 6
sec5 = 8
games = {
'adom': [ten+fir+sec+sec5, "Ancient Domain of Mysteries"],
'nethack': [fir+fir+fir+sec+thi5, "Nethack"]
}
Right now, I'm going about this the hard way, and making a big long list of nested ifs, but I don't think that's the proper way to go about it. I was trying to figure out a way to sort the dictionary, via the arrays, and then, finding a way to display the first ten that pop up... instead of having to work deep in the if statements.
So... basically, my question is : Do you have any ideas that I could use to about making this easier, instead of wayyyy, way harder?
===== EDIT ====
the ten+fir produces numbers. I want to find a way to go about sorting the lists (I lack the knowledge of proper terminology) to go by the number (basically, whichever ones have the highest number in the first part of the array go first.
Here's an example of my current way of going about it (though, it's incomplete, due to it being very tiresome : Example Nests (paste2) (let's try this one?)
==== SECOND EDIT ====
In case someone doesn't see my comment below :
ten, fir, et cetera - these are just variables for scores. Basically, it goes from a top ten list into a variable number.
ten = 1, nin = 2, fir = 10, fir5 = 10, sec5 = 8, sec = 9...
so : 'adom': [ten+fir+sec+sec5, "Ancient Domain of Mysteries"] actually registers as : 'adom': [1+10+9+8, "Ancient Domain of Mysteries"] , which ends up looking like :
'adom': [28, "Ancient Domain of Mysteries"]
So, basically, if I ended up doing the "top two" out of my example, it'd be :
((1)) Nethack (48)
((2)) ADOM (28)
I'd write an actual number, but I'm thinking of changing a few things up, so the numbers might be a touch different, and I wouldn't want to rewrite it.
== THIRD (AND HOPEFULLY THE FINAL) EDIT ==
Fixed my original code example.
How about something like this:
scores = games.items()
scores.sort(key = lambda key, value: value[0])
return scores[:10]
This will return the first 10 items, sorted by the first item in the array.
I'm not sure if this is what you want though, please update the question (and fix the example link) if you need something else...
import heapq
return heapq.nlargest(10, games.iteritems(), key=lambda k, v: v[0])
is the most direct way to get the top ten key / value pairs, sorted by the first item of each "value" list. If you can define more precisely what output you want (just the names, the name / value pairs, or what else?) and the sorting criterion, this is easy to adjust, of course.
Wim's solution is good, but I'd say that you should probably go the extra mile and push this work off onto a database, rather than relying on Python. Python interfaces well with most types of databases, where much of what you're exploring is already a solved problem.
For example, instead of worrying about shifting your dictionaries to various other data types in order to properly sort them, you can simply get all the data for each pertinent entry pre-sorted based on the criteria of your query. There goes the need for convoluted sorting and resorting right there.
While dictionaries are tempting to use, because they give the illusion of database-like abilities to access data based on its attributes, I still think they stumble quite a bit with respect to implementation. I don't really have any numbers to throw at you, but just from personal experience, anything you do on Python when it comes to manipulating large amounts of data, you can do much faster and more efficient both in code and computation with something like MySQL.
I'm not sure what you have planned as far as the structure of your data goes, but along with adding data, changing its structure is a lot easier using a database, too.

Categories

Resources