wenjun99 commited on
Commit
cf08198
Β·
verified Β·
1 Parent(s): f6bc9a3

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +122 -64
app.py CHANGED
@@ -1,16 +1,12 @@
1
  import streamlit as st
2
  import pandas as pd
 
3
 
4
  # =========================
5
  # Streamlit App Setup
6
  # =========================
7
- st.set_page_config(page_title="ASCII β†’ Binary Label Converter", layout="wide")
8
- st.title("πŸ”’ ASCII β†’ Binary Label Converter")
9
-
10
- st.markdown("""
11
- Convert text into binary labels using the **Voyager 6-bit ASCII table**.
12
- You can control how many positions (columns) are grouped per row.
13
- """)
14
 
15
  # =========================
16
  # Voyager ASCII 6-bit Table
@@ -27,12 +23,10 @@ voyager_table = {
27
  }
28
  reverse_voyager_table = {v: k for k, v in voyager_table.items()}
29
 
30
-
31
  # =========================
32
  # Helper Functions
33
  # =========================
34
  def string_to_binary_labels(s: str) -> list[int]:
35
- """Convert string to list of 0/1 bits using the 6-bit Voyager table."""
36
  bits = []
37
  for char in s:
38
  val = reverse_voyager_table.get(char.upper(), 0)
@@ -40,9 +34,7 @@ def string_to_binary_labels(s: str) -> list[int]:
40
  bits.extend(char_bits)
41
  return bits
42
 
43
-
44
  def binary_labels_to_string(bits: list[int]) -> str:
45
- """Convert list of 0/1 bits back to string using Voyager table."""
46
  chars = []
47
  for i in range(0, len(bits), 6):
48
  chunk = bits[i:i+6]
@@ -52,58 +44,124 @@ def binary_labels_to_string(bits: list[int]) -> str:
52
  chars.append(voyager_table.get(val, '?'))
53
  return ''.join(chars)
54
 
55
-
56
- # =========================
57
- # User Controls
58
- # =========================
59
- st.subheader("Step 1 – Input Text")
60
- user_input = st.text_input("Enter your text:", value="DNA", key="input_text")
61
-
62
- col1, col2 = st.columns([2, 1])
63
- with col1:
64
- group_size = st.slider("Select number of positions per group:", min_value=12, max_value=32, value=25)
65
- with col2:
66
- custom_cols = st.number_input("Or enter custom number:", min_value=1, max_value=128, value=group_size)
67
- if custom_cols != group_size:
68
- group_size = custom_cols
69
-
70
  # =========================
71
- # Conversion and Display
72
  # =========================
73
- if user_input:
74
- binary_labels = string_to_binary_labels(user_input)
75
-
76
- st.markdown("### Step 2 – Binary Labels per Character")
77
- st.caption("Scroll to view all characters")
78
-
79
- # Prepare scrollable block
80
- grouped_bits = [binary_labels[i:i+6] for i in range(0, len(binary_labels), 6)]
81
- scroll_html = "<div style='max-height: 300px; overflow-y: auto; font-family: monospace; padding: 6px; border: 1px solid #ccc;'>"
82
- for i, bits in enumerate(grouped_bits):
83
- ch = user_input[i] if i < len(user_input) else "?"
84
- scroll_html += f"<div>'{ch}' β†’ {bits}</div>"
85
- scroll_html += "</div>"
86
- st.markdown(scroll_html, unsafe_allow_html=True)
87
-
88
- # Group into user-selected positions
89
- st.markdown("### Step 3 – Grouped Binary Matrix")
90
- groups = []
91
- for i in range(0, len(binary_labels), group_size):
92
- group = binary_labels[i:i+group_size]
93
- if len(group) < group_size:
94
- group += [0] * (group_size - len(group))
95
- groups.append(group)
96
-
97
- # Build DataFrame
98
- columns = [f"Position {i+1}" for i in range(group_size)]
99
- df = pd.DataFrame(groups, columns=columns)
100
-
101
- st.dataframe(df, use_container_width=True)
102
- st.download_button(
103
- "⬇️ Download as CSV",
104
- df.to_csv(index=False),
105
- file_name=f"binary_labels_{group_size}_positions.csv",
106
- mime="text/csv"
107
- )
108
- else:
109
- st.info("πŸ‘† Enter text above to see binary labels.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import streamlit as st
2
  import pandas as pd
3
+ import io
4
 
5
  # =========================
6
  # Streamlit App Setup
7
  # =========================
8
+ st.set_page_config(page_title="ASCII ↔ Binary Converter", layout="wide")
9
+ st.title("πŸ”’ ASCII ↔ Binary Converter")
 
 
 
 
 
10
 
11
  # =========================
12
  # Voyager ASCII 6-bit Table
 
23
  }
24
  reverse_voyager_table = {v: k for k, v in voyager_table.items()}
25
 
 
26
  # =========================
27
  # Helper Functions
28
  # =========================
29
  def string_to_binary_labels(s: str) -> list[int]:
 
30
  bits = []
31
  for char in s:
32
  val = reverse_voyager_table.get(char.upper(), 0)
 
34
  bits.extend(char_bits)
35
  return bits
36
 
 
37
  def binary_labels_to_string(bits: list[int]) -> str:
 
38
  chars = []
39
  for i in range(0, len(bits), 6):
40
  chunk = bits[i:i+6]
 
44
  chars.append(voyager_table.get(val, '?'))
45
  return ''.join(chars)
46
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
47
  # =========================
48
+ # Tabs
49
  # =========================
50
+ tab1, tab2 = st.tabs(["Text β†’ Binary", "Binary β†’ Text"])
51
+
52
+ # --------------------------------------------------
53
+ # TAB 1: Text β†’ Binary
54
+ # --------------------------------------------------
55
+ with tab1:
56
+ st.markdown("""
57
+ Convert any text into binary labels using the **Voyager 6-bit ASCII table**.
58
+ You can control how many positions (columns) are grouped per row.
59
+ """)
60
+
61
+ st.subheader("Step 1 – Input Text")
62
+ user_input = st.text_input("Enter your text:", value="DNA", key="input_text")
63
+
64
+ col1, col2 = st.columns([2, 1])
65
+ with col1:
66
+ group_size = st.slider("Select number of positions per group:", min_value=12, max_value=32, value=25)
67
+ with col2:
68
+ custom_cols = st.number_input("Or enter custom number:", min_value=1, max_value=128, value=group_size)
69
+ if custom_cols != group_size:
70
+ group_size = custom_cols
71
+
72
+ if user_input:
73
+ binary_labels = string_to_binary_labels(user_input)
74
+ binary_concat = ''.join(map(str, binary_labels))
75
+
76
+ # Step 2: Binary Labels per Character
77
+ st.markdown("### Step 2 – Binary Labels per Character")
78
+ st.caption("Scroll to view all characters")
79
+
80
+ # Scrollable block
81
+ grouped_bits = [binary_labels[i:i+6] for i in range(0, len(binary_labels), 6)]
82
+ scroll_html = "<div style='max-height: 300px; overflow-y: auto; font-family: monospace; padding: 6px; border: 1px solid #ccc;'>"
83
+ for i, bits in enumerate(grouped_bits):
84
+ ch = user_input[i] if i < len(user_input) else "?"
85
+ scroll_html += f"<div>'{ch}' β†’ {bits}</div>"
86
+ scroll_html += "</div>"
87
+ st.markdown(scroll_html, unsafe_allow_html=True)
88
+
89
+ # Download full concatenated binary text
90
+ st.download_button(
91
+ "⬇️ Download Full Binary (.txt)",
92
+ data=binary_concat,
93
+ file_name="binary_full.txt",
94
+ mime="text/plain",
95
+ key="download_binary_txt"
96
+ )
97
+
98
+ # Step 3: Grouped Binary Matrix
99
+ st.markdown("### Step 3 – Grouped Binary Matrix")
100
+ groups = []
101
+ for i in range(0, len(binary_labels), group_size):
102
+ group = binary_labels[i:i+group_size]
103
+ if len(group) < group_size:
104
+ group += [0] * (group_size - len(group))
105
+ groups.append(group)
106
+
107
+ columns = [f"Position {i+1}" for i in range(group_size)]
108
+ df = pd.DataFrame(groups, columns=columns)
109
+ st.dataframe(df, use_container_width=True)
110
+
111
+ st.download_button(
112
+ "⬇️ Download as CSV",
113
+ df.to_csv(index=False),
114
+ file_name=f"binary_labels_{group_size}_positions.csv",
115
+ mime="text/csv",
116
+ key="download_binary_csv"
117
+ )
118
+ else:
119
+ st.info("πŸ‘† Enter text above to see binary labels.")
120
+
121
+ # --------------------------------------------------
122
+ # TAB 2: Binary β†’ Text
123
+ # --------------------------------------------------
124
+ with tab2:
125
+ st.markdown("""
126
+ Convert binary data back into readable text.
127
+ Upload either:
128
+ - `.csv` file with 0/1 values (any number of columns/rows)
129
+ - `.xlsx` Excel file
130
+ - `.txt` file containing a concatenated binary string (e.g. `010101...`)
131
+ """)
132
+
133
+ uploaded = st.file_uploader("Upload your file (.csv, .xlsx, or .txt):", type=["csv", "xlsx", "txt"])
134
+
135
+ if uploaded is not None:
136
+ try:
137
+ if uploaded.name.endswith(".csv"):
138
+ df = pd.read_csv(uploaded)
139
+ bits = df.values.flatten().astype(int).tolist()
140
+ elif uploaded.name.endswith(".xlsx"):
141
+ df = pd.read_excel(uploaded)
142
+ bits = df.values.flatten().astype(int).tolist()
143
+ elif uploaded.name.endswith(".txt"):
144
+ content = uploaded.read().decode().strip()
145
+ bits = [int(b) for b in content if b in ['0', '1']]
146
+ else:
147
+ bits = []
148
+
149
+ if not bits:
150
+ st.warning("No binary data detected.")
151
+ else:
152
+ recovered_text = binary_labels_to_string(bits)
153
+ st.success("βœ… Conversion complete!")
154
+ st.markdown("**Recovered text:**")
155
+ st.text_area("Output", recovered_text, height=150)
156
+
157
+ st.download_button(
158
+ "⬇️ Download Recovered Text (.txt)",
159
+ data=recovered_text,
160
+ file_name="recovered_text.txt",
161
+ mime="text/plain",
162
+ key="download_recovered"
163
+ )
164
+ except Exception as e:
165
+ st.error(f"Error reading or converting file: {e}")
166
+ else:
167
+ st.info("πŸ‘† Upload a file to start the reverse conversion.")