9
\$\begingroup\$

I have written a python script that has tallies representing digits 1-9 (0 is just ":" ) Unlike true Unary languages that are in the form 1^k. I represent values for n as per their decimal digits. The integer 121 is 1_11_1 Overall every k digit out of n "integer" is in Tally notation, and the amount of tallies is the sum of all the digits in a given n "integer" such as 121 = 4, 1_11_1 = 4.

Its called a many-one reduction. If you can transform Instance A(9,33,4) into Instance B(1111_1111 1, 111----111, 1111) in poly-time, then its NP-complete

Transformation rules is to just to enter each integer sequentially when asked in the while loop. Also, when your integer is a negative you do not give a "-" symbol for input. It will ask for input if its a negative integer.

Input 

(9,33,4) "9, and then 33 and then 4. One at a time for each input."

Output

'111_1111 1' = 9

    111     
33>>
    111     

    11 11    =4

Algorithm for the Reduction

# This algorithm is very simple and inconsequential.
# It converts integers into a unary like language 
# in poly time. All tallies are represented vertically.

print('If your integer is a negative, the script will ask.')
print("DO NOT GIVE -X integers for input!!!")
print('Script will output multiple - symbols for a negative integer transformation')

while 0 == 0:
  ask = input('Enter an integer from a subset-sum instance sequentially.')
  askStr = str(ask)
  res = list(map(int, str(askStr)))
  x = (res)
  asktwo = input('Is your integer a negative integer? y or n: ')
  if asktwo == str("y"):
     twinkle = str('-')
  else:
     twinkle = str(" ")  
  for n in x:
      if n == 0: 
       tallyone = ":"
       print(twinkle, tallyone)
      if n == 1:
       print(twinkle, "1")
      if n == 2:
       print(twinkle, "11")
      if n == 3:
       print(twinkle, "111")
      if n == 4:
       print(twinkle, "11 11")
      if n == 5:
       print(twinkle, "111 11")
      if n == 6:
       print(twinkle, "111 111")
      if n == 7:
       print(twinkle, "111_111 1")
      if n == 8:
       print(twinkle, "1111 1111")
      if n == 9:
       print(twinkle, "1111_1111 1")

Question

In what way, is this code sloppy? Am I using while loops and variable names in an ugly way? Is my tallies in the print statements hard to read? What is the ugliest parts of my code and how would I improve them?

The code works. But, I don't know enough about python so what mistakes are you seeing in my code?

\$\endgroup\$
13
  • 8
    \$\begingroup\$ I must admit that I don't yet see the logic of the transformation. As an example, why is 5 transformed to "111 11" and not "11111", "1111 1", or "111_11"? And how is this related to a “subset sum instance”? \$\endgroup\$
    – Martin R
    Commented Sep 19, 2019 at 4:50
  • \$\begingroup\$ @MartinR At the very least, the code does nothing like the 121 = 1_11_1 example \$\endgroup\$
    – JollyJoker
    Commented Sep 19, 2019 at 13:57
  • \$\begingroup\$ Could you try explaining a little bit more what the code is supposed to do? \$\endgroup\$
    – IEatBagels
    Commented Sep 19, 2019 at 14:06
  • \$\begingroup\$ @ Martin R Its called a many one reduction. If you can transform Instance A(9,33,4) into Instance B(1111_1111 1, 111----111, 1111) in poly-time. Then its NP-complete en.wikipedia.org/wiki/Many-one_reduction \$\endgroup\$
    – The T
    Commented Sep 19, 2019 at 21:53
  • 2
    \$\begingroup\$ @TravisWells: It may be my lacking knowledge of computability theory, but it still isn't clear to me. What exactly are the problems A and B in your reduction? How is this related to a subset-sum? And what exactly are the transformation rules? \$\endgroup\$
    – Martin R
    Commented Sep 20, 2019 at 5:43

2 Answers 2

7
\$\begingroup\$

This is a very interesting task. Good work on doing it. Here are some criticism.


print('If your integer is a negative, the script will ask.')
print("DO NOT GIVE -X integers for input!!!")
print('Script will output multiple - symbols for a negative integer transformation')
  • Do not use both double quote ("") and single quote ('') strings. Pick one. I personally prefer "".
while 0 == 0:
  ask = input('Enter an integer from a subset-sum instance sequentially.')
  • It's considered a best practice to indent using 4 spaces instead of 2.
  • Also it would be better to move actual transform functionality to a new function.
  • Also it's better to use while True instead of while 0 == 0 to indicate a endless loop.
    • Reason: This is more readable.
  askStr = str(ask)
  res = list(map(int, str(askStr))
  • You are converting ask twice to a string. This is redundant.
  • Since input() returns a string you don't need to convert this at all.
  • It is also a better to use python conventions for names. Ex: ask_str or value
  x = (res)
  • You don't need parenthesis here.
  • There is also no need to assign to x you can directly use res.
  if asktwo == str("y"):
     twinkle = str('-')
  else:
     twinkle = str(" ")
  • You don't need to convert a string literal to a string again.
  • You can directly use "y" as a string.
  • twinkle is not a good name. Use something like sign.
\$\endgroup\$
4
\$\begingroup\$

Pythonic. Zen of Python. Idioms of Python.

These are phrases that will come up in python code. Basically they refer to the readability.

Other programmers have to be able to read the code you write. Here are a few things that can be done to improve your knowledge.

  • In the console, help() can be used in conjunction of other methods to get the docstring and information on how things work in python.
  • type() will show the data type you are currently working with.
  • input() returns a string.
  • int(str, base) returns an integer with the base of the given value (2 <= base <= 36)
  • enumerate(tuple) allows for indices, is fast (because it doesn't need to make a new list).
  • while 0==0: is ugly. while True: is infinitely more beautiful.
print('user instructions')

response = input('Pick an integer value less than infinity:\n')
mapped_response = map(int, response)
response_length = len(response) - 1   # eewww!
result = ''

for index, value in enumerate(mapped_response):
  result = f"{result}\
             {':' if not value else ''.join('1' for _ in range(value))}\
             {'_' if index < response_length else ''}"

print(result)

input

543210

output

11111_1111_111_11_1_:

\$\endgroup\$
5
  • 1
    \$\begingroup\$ The points you make in this answer are all valid, but they should be targeted towards a beginner. A beginner doesn't know what you mean with "input returns a string" and what that means for the code. \$\endgroup\$ Commented Sep 19, 2019 at 7:38
  • 2
    \$\begingroup\$ Unless I am mistaken, your code produces not the same output as the original code from the question, e.g. "11111" for 5 instead of "111 11". \$\endgroup\$
    – Martin R
    Commented Sep 19, 2019 at 7:41
  • 2
    \$\begingroup\$ "Pythonic. Zen of Python. Idioms of Python." likely don't mean anything to a beginner (Roland Illig already pointed in that direction), not even I "get" anything from it (and I consider myself at least at a reasonable Python skill level). \$\endgroup\$
    – AlexV
    Commented Sep 19, 2019 at 7:45
  • \$\begingroup\$ @MartinR Formatting for individual values were not clear, and you even tried for clarification well before I tackled responding. \$\endgroup\$ Commented Sep 19, 2019 at 7:47
  • \$\begingroup\$ Awesome answer! \$\endgroup\$
    – The T
    Commented Jul 16, 2020 at 3:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.