Python: Change range location with loop - python

I would like my program to print every other letter in the string "welcome".
like:
e
c
m
Here is the code I have so far:
stringVar = "welcome"
countInt = 7
count = 0
oneVar = 1
twoVar = 2
showVar = stringVar[oneVar:twoVar]
for count in range(countInt):
count = count + 1
oneVar = oneVar + count
twoVar = twoVar + count
print(showVar)
Though it only shows the 2nd letter "e".
How can I get the variables oneVar and twoVar to update so that the range changes for the duration of the loop?

There is a built in notation for this, called "slicing":
>>> stringVar = "welcome"
>>> print(stringVar[::2])
wloe
>>> print(stringVar[1::2])
ecm
stringVar is iterable like a list, so the notation means [start : end : step]. Leaving any one of those blank implicitly assumes from [0 : len(stringVar) : 1]. For more detail, read the linked post.

Another more complex way of the doing the same would be
string_var = "welcome"
for index, character in enumerate(string_var, start=1): # 'enumerate' provides us with an index for the string and 'start' allows us to modify the starting index.
if index%2 == 0:
print character

Why its not working in your snipet:
Even though you increase oneVar and twoVar inside the loop, there is no change in the showVar as showVar is string which is immutable type, and its printing stringVar[1:2] which is e the 2nd index of welcome:
Just to fix your snippet:
You can just try like this;
stringVar = "welcome"
countInt = 7
for count in range(1,countInt,2):
print count, stringVar[count]
Output:
e
c
m

Related

Adding text in front of separate numbers in list

Im new to python and hit a wall with my last print in my program
I got a list of numbers created with math int(numbers that when printed looks like this
[0, 0, 0, 0] #just with random numbers from 1 - 1000
I want to add text in front of every random number in list and print it out like this
[Paul 0 Frederick 0 Ape 0 Ida 0]
Any help would be appreciated. Thanks !
Sounds like you want to make a dictionary. You could type:
d = dict()
d["Paul"] = random.randint(1,100)
....
print(d)
#output: {"Paul":1, "Fredrick":50, "Ape":25, "Ida":32}
Alternatively there is nothing stopping you from using strings and integers in the same list! Python is not strongly statically typed.
If you have a list of numbers [45,5,59,253] and you want to add names to them you probably need a loop.
nums = [45,5,59,253]
names = ["Paul", "Frederick", "Ape", "Ida"]
d = dict()
i = 0
for n in nums:
d[names[i]] = n
i+=1
or if you wanted a list
nums = [45,5,59,253]
names = ["Paul", "Frederick", "Ape", "Ida"]
list = [x for y in zip(names, nums) for x in y]
You'd have to turn your random integers into strings and add them to the text (string) you want.
Example:
lst=[]
x = str(randint(0,1000))
text = 'Alex'
final_text = text+' '+x
lst.append(final_text)
Just added the space like in your example. It'll just be a little more complex to access the numbers if you do it this way.

how can you don't replace a value in an array when you are replacing the value with nothing in python?

import sympy as sp
import math
import re
a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z = sp.symbols('a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z')
formula = input('')
unknown_values = int(input('how many unknown values?: '))
unknown_array = []
values = []
for i in range(unknown_values):
unknown_name = input('unknown value: ')
unknown_array += [unknown_name]
for i in range(len(unknown_array)):
values += [input('Enter the value of ' + unknown_array[i] + ': ')]
for word in unknown_array:
formula = formula.replace(word, values[unknown_array.index(word)])
formula = re.split(r'[=|<|>|<=|>=|==]', formula)[0:2]
split_a = sympify(formula[0])
split_b = sympify(formula[1])
split_c = simplify(split_a - split_b)
result = sp.solve(split_c, x)
for w in result:
print(w.evalf())
input: a*x**2 + b*x + c = 0
how many unknown values?: 3
unknown value: a
unknown value: b
unknown value: c
Enter the value of a: 1
Enter the value of b: 5
Enter the value of c: 6
-3.00000000000000
-2.00000000000000
this is how my code works. But when I put the values in 'unknown_array', i need to put only a,b,c and not x because it's the one I need to find. I would like to put also x in 'unknown_array' and in 'values' nothing (just press enter). The problem is that if I put nothing, then, when it will replace the values, it will just eliminate x. So I would like that in every value that I just press enter, it won't replace that value and put that value here: result = sp.solve(split_c, ...); instead of the 3 points and so solve for that value. While if there are multiple values, it will solve them one at a time and print every result.
You are doing things with strings that you don't have to but if you want to reinvent the wheel that is always a way to learn so I won't try change the code. But as for how to solve for something other than x you need to identify what variable is left. You could do that by having the user identify what they are going to supply values for and then just don't say that you are solving for x:
sp.solve(split_c) instead of sp.solve(split_c, x)
This will return a dictionary with the solved value.
Otherwise, if you have an expression like a*x+b and they say there are 3 unknowns and they want to "press return" on the one they want to solve for then when it comes to substituting in values, just skip that one during replacement (or replace it with the corresponding symbol):
for word in unknown_array:
i = unknown_array.index(word)
formula = formula.replace(word, values[i] or unknown_array[i])
And then, again, don't pass x to solve -- solve will work it out if there is one symbol left.

adding value to my matrix but the result shows an error

I am trying to append a list of 4 letters in my number as a [[a, b, c, d]] type of list.
I am looping through a list and appending the letter to a temp list and then appending it to my main list to make it into a matrix. However, the main list is only storing the number (8, 26) for some reason
ciphertext = "asfgasgsaga"
counter = 0
templist = []
xyz = []
for abc in ciphertext:
if(counter == 5):
print(templist)
xyz.append(templist)
templist.clear()
counter = 0
else:
templist.append(abc);
counter += 1
print(xyz)
The result is for some reason giving [[8, 26]]
The result is not the same as your expected because there some concepts that you need to know about objects in Python:
Immutable Objects: int, float, complex, string, tuple, frozen set, bytes. These kind of data types can't be changed the value after it is created. So that when we assign to another variable, it will copy the value to new variable. E.g:
a = 123
b = a
a = 456
print(b) #123
Mutable Objects: list, dict, set, byte array. These can be changed the value after it is created. And when you assign to another variable, it basically just assign the reference to previous variable like so:
a = []
b = a
a.append(123)
print(b) #[123]
So back to your problem, you're using list to create a list with 4 characters and then append it into another list, it's not append the expected list but instead a reference to it. That's why you got unexpected result.
And about the logic of your code, there are something go wrong, because when counter you will miss 1 character. You actually can switch to use slicing in Python:
ciphertext = "asfgasgsaga"
xyz = [ciphertext[start:start + 4] for start in range(0, len(ciphertext), 4)]
print(xyz) #['asfg', 'asgs', 'aga']
I'm using List Comprehension to append to xyz instead of call append function, create step like: 0:4, 4:8, 8:12, ... voila
Hope that helpful for you.
Just as #zvone says, don's use the same array and clear it, because they ref the same memory;
ciphertext = "asfgasgsaga"
counter = 0
templist = []
xyz = []
for abc in ciphertext:
if(counter == 4):
print(templist)
xyz.append(templist)
templist = [] # <--- use a new empty array
counter = 0
else:
templist.append(abc);
counter += 1
print(xyz)
Also, the correct logic(handle the letters less than 4) should be:
ciphertext = "asfgasgsaga"
counter = 0
templist = []
xyz = []
for abc in ciphertext:
templist.append(abc);
counter += 1
if(counter == 4):
print(templist)
xyz.append(templist)
templist = []
counter = 0
if templist:
xyz.append(templist)
print(xyz)
Just see #Toan Quoc Ho's answer, which should make more sense. Just leave the answer here to compare your origin logic.

Xpath expression, format method, using variables outside for loop, Python

I am using xpath and lxml to parse an XML file. I use format to increment the value in the item element, item[{}], so that I can get data from the first element, 2nd, and so on. I loop through based on number of times the //items/item element appears in the XML file, which works. When I get to the last item in the tuple I increase z by 1.
QUESTION:
I can't figure how to assign the tuple value outside this for loop, and still use format to increase the value of z. If I define the tuple outside the for loop, z always equals 1. It works as shown, but I don't like it.
x = 0
y = 1
z = 1
for field in xrange(1, 3):
dataFields = \
(("itemType" , "//items/item[{}]//#itemType".format(z)),
("itemClass" , "//items/item[{}]//#itemClass".format(z)),)
currentData = dataFields[x][y]
try:
r = tree.xpath(currentData)[0]
except:
r = ""
f = open(dataOutputFile, 'a')
f.write(str(r) + "\t")
f.close()
x += 1
if "itemClass" in currentData:
z += 1

In python, how would I go about linking user input to a index in a list?

I would like to create a binary puzzle with python.
At the moment I already made a 6x6, 8x8 and 10x10 layout which is shown based on the difficulty that the players wishes to play. The purpose of the puzzle can be compared with a game of sudoku, you want to input either 0 or 1 on a given location by the player. Below you will find what I currently have for the layout.
if graad == 1:
easy = [['A', 'B', 'C', 'D', 'E'],
['_','_','_','_','_','_','_'],
[0,1,0,1,0,1,' |1'],
[1,0,1,0,1,0,' |2'],
[0,1,0,1,0,1,' |3'],
[1,0,1,0,1,0,' |4'],
[0,1,0,1,0,1,' |5'],
[1,0,1,0,1,0,' |6']]
i = 0
while i < len(easy):
j = 0
s = ""
while j < len(easy[i]):
s = s + str(easy[i][j]) + " "
j = j + 1
print (s)
i = i + 1
Now the problem that I am facing is, how can I let python know that when a player fills in position 3 on column C and row 5 with a 0 for example?
I was thinking of an IF statement that checks the input on either a A, B, C D, E... Row 1,2,3,4,5.. but that is going to be a lot of if statements.
Edit1: Ok so to clarify.I wanted to post a picture but need more posts.
For example, I have a game board of 6x6 cells. Some of them are filled with a 1 and some of them are filled with 0 and most of them are empty because the goal is to have it look in the end like my layout in the python code.(That's the solution). So you want the user to fill in those empty cells.
Now, let's say that the player wants to fill in A-1 with a 1, how will python know that input A-1 is linked to index [0][0] in the list?
A simple way to convert your letter indices to numbers is to use the ord() function, which returns the numerical code of a single character. Since you are using upper-case letters, with 'A' being the label for the column with index 0, you can do
column = ord(letter) - ord('A')
That will convert 'A' to 0, 'B' to 1, etc.
Here's a short example program vaguely based on the code on your question.
It accepts moves in the form A10 to set location A1 to '1', 'B30' to set location B3 to '0'. It accepts lower case letters, too, so 'd11' is the same as 'D11'. Hit Ctrl-C to exit.
Tested on Python 2.6.6, but it should work correctly on Python 3. (To run it on Python 2, change input() to raw_input()).
#! /usr/bin/env python
def print_grid(g):
gsize = len(g)
base = ord('A')
print(' '.join([chr(base + i) for i in range(gsize)]))
print((gsize * 2) * '-')
for i, row in enumerate(g, 1):
print(' '.join(row) + ' | ' + str(i))
print('\n')
def main():
gsize = 9
rowstr = gsize * '_'
grid = [list(rowstr) for i in range(gsize)]
print_grid(grid)
while True:
move = input('Enter move: ')
letter, number, bit = move.strip()
col = ord(letter.upper()) - ord('A')
row = int(number) - 1
grid[row][col] = bit
print_grid(grid)
if __name__ == "__main__":
main()
If you work with a pandas DataFrame to hold your correct answer of the game you can easily check things. The pandas package has a good documentation (and a lot of Q&A here on stackoverflow).
The setup of your correct answer:
import pandas as pd
data = [[0,1,0,1,0,1],
[1,0,1,0,1,0],
[0,1,0,1,0,1],
[1,0,1,0,1,0],
[0,1,0,1,0,1],
[1,0,1,0,1,0]]
easy = pd.DataFrame(data)
easy.columns = ['A','B','C','D','E','F']
print easy
The item at position 'A',0 (python starts to number from 0) is given by easy['A'][0]. For more information about indexing a pandas DataFrame object visit the documentation.
Another usefull thing, a DataFrame object is printable, making it unnecessary to write a print command yourself.
If using DataFrames is overkill for you, another option is to work with a 'translation' dictionary. This dictionary will use the letters for keys and the corresponding column number as a value.
>>> column = {'A':0, 'B':1, 'C':2, 'D':3, 'E':4, 'F':5}
>>> print column['A']
0

Categories

Resources