Looping to get all the week's days - twig

I'm trying to get all the days of the week with a for loop in my twig view.
Here's the thing I want to do :
<table>
<thead>
</thead>
<tbody>
<tr><td>{{ "+0 day"|date("d M y") }}</td></tr>
<tr><td>{{ "+1 day"|date("d M y") }}</td></tr>
<tr><td>{{ "+2 day"|date("d M y") }}</td></tr>
<tr><td>{{ "+3 day"|date("d M y") }}</td></tr>
<tr><td>{{ "+4 day"|date("d M y") }}</td></tr>
<tr><td>{{ "+5 day"|date("d M y") }}</td></tr>
<tr><td>{{ "+6 day"|date("d M y") }}</td></tr>
</tbody>
</table>
This is what I tried so far :
[...]
{% for day in 0..6 %}
<tr>
<td>{{ ('"' ~ '+' ~ day ~ ' day' ~ '"')|date("d M y") }}</td>
</tr>
{% endfor %}
but I get this error message :
An exception has been thrown during the rendering of a template
("DateTime::__construct(): Failed to parse time string ("+0 day)
at position 0 ("): Unexpected character")
Any idea how I should do this please ?

Simply remove the double quote (") character:
{% for day in 0..7 %}
{% set myDate = '+' ~ day ~ ' day' %}
<tr>
<td>{{ myDate|date("d M y") }}</td>
</tr>
{% endfor %}
See this working twgifiddle

Related

for each key after index "number" create table , key counter Twig

I have a list of sortiments that contain shoe size and pair numbers, taken from a csv file with php and saved as an array in in Twig.
In twig this is my previous code to make a table. the problem here is, it is made to only make tables with 6 columns and not more or less.
<div class="twp-sortiment">
{% for key in page.extensions.TwpSortiment.data %}
{% set shoeSizeArray = key.shoesize|split(',') %}
{% set sortimentArray = key.sortiment|split(',') %}
{{ sortimentArray[2] }}
<table>
<tr>
<th>{{ shoeSizeArray[3] }}</th>
<th>{{ shoeSizeArray[4] }}</th>
<th>{{ shoeSizeArray[5] }}</th>
<th>{{ shoeSizeArray[6] }}</th>
<th>{{ shoeSizeArray[7] }}</th>
<th>{{ shoeSizeArray[8] }}</th>
</tr>
<tr>
<td>{{ sortimentArray[3] }}</td>
<td>{{ sortimentArray[4] }}</td>
<td>{{ sortimentArray[5] }}</td>
<td>{{ sortimentArray[6] }}</td>
<td>{{ sortimentArray[7] }}</td>
<td>{{ sortimentArray[8] }}</td>
</tr>
</table>
{% endfor %}
</div>
As you can see i have put my rows in to arrays (shoeSizeArray, shoeSizeArray).
Now i would like to create the table based on how many keys come after index 2, starting from index 3, my table should take values and increase until its at the end. so i tried this but obviously doesnt work as i lack knowladge about Twig.
<div class="twp-sortiment">
{% for key in page.extensions.TwpSortiment.data %}
{% set shoeSizeArray = key.shoesize|split(',') %}
{% set sshoeSizeArray = key.sortiment|split(',') %}
{{ sortimentArray[2] }}
<table>
<tr>
{% for key in shoeSizeArray %}
{% set counter = ( counter | default(2) ) + 1 %}
<th>{{ shoeSizeArray[counter] }}</th>
{% endfor %}
</tr>
<tr>
{% for key in sortimentArray %}
{% set counter = ( counter | default(2) ) + 1 %}
<td>{{ sortimentArray[counter] }}</td>
{% endfor %}
</tr>
</table>
{% endfor %}
</div>
This is the output:
As you can see I get 3 more emtpy table columns because im counting every key but I dont want the first 3 keys to be counted in my "for loop",now I have to say count the key of array - 3 (for till index 2: [0],[1],[2]) and then do the and for that amount of
Number of the keyCounter -3.
use slice with split filter https://twig.symfony.com/doc/3.x/filters/slice.html
like
{% set shoeSizeArray = key.shoesize|split(',')|slice(3) %}
{% set sortimentArray = key.sortiment|split(',')|slice(4) %}

Horizontally merge and divide cells in an HTML Table for Timetable based on the Data in Python File

Please note this question is an extension of this previously asked question: How to make Images/PDF of Timetable using Python
I am working on a program that generates randomized Timetable based on an algorithm. For the Final Output of that program, I require a Timetable to be stored in a PDF File.
There are multiple sections and each section must have its own timetable/schedule. Each Section can have multiple Courses whose lectures will be allocated on different slots from Monday to Friday by the algorithm. For my timetable,
There are 5 days in total (Monday to Friday)
Each day will have 5 slots (0 to 4 in indexes. With a "Lunch" Break between 3rd and 4th slot)
As an Example, I have created below a dictionary where key represents the Section and the items have a 2D Array of size 5x5. Each Index of that 2D array contains the course details for which the lecture will take place in that slot.
CS-3B : [['', '', 'DS ', '', 'COaAL '], ['', 'COaAL ', '', 'DS ', 'OOP '], ['DS-L ', 'DS-L ', 'OOP-L ', 'OOP-L ', 'FoM '], ['COaAL-L ', 'COaAL-L ', 'OOP ', '', ''], ['', 'FoM ', 'DE ', '', 'DE ']]
SE-3A : [['', 'OOP-L ', 'OOP-L ', '', 'SRE '], ['SRE ', 'OOP ', 'DS-L ', 'DS-L ', ''], ['', 'DS ', '', '', 'MM '], ['DS ', 'MM ', '', 'LA ', ''], ['OOP ', 'HCI ', '', 'LA ', 'HCI ']]
This, however, only contains "strings'. While, in actual data, there would be object of a course instead of that string. That object will contain different information regarding that course for which the lecture is going to take place on that specific slot of the day.
While generating the timetable, there are three major concerns that must be resolved,
Lectures for "Labs" are held over two consecutive slots. So, for all the labs, those two cells in the table must be merged
It is possible that at the same time, two or more than two different lectures are taking place for one section. In such a case, the cell of that slot must be horizontally divided into two or more cells
It is also possible that at the same time, two lectures are being held at one slot and one of those two lectures can be of Lab. In such a case, two consecutive cells should be merged and also horizontally divided to accomadate both the lectures.
With help of previous post, I was able to transform this Data into PDF format using Jinja library. However, it was only doing it on strings, by differentiating between consecutive lectures with space character. Now, I have complete objects and I am unable to do the same with them.
I placed a list of objects on each index of 2D Array. That list may contain no object, one object or multiple objects (one object represents one course). Moreover, there is a single object for a Lab course (and that single object is added to the two consecutive indexes in which lab lecture is being held)
Following is the complete code (I have created sample data for only two sections)
from typing import List
import pdfkit
from pdfkit.api import configuration
from jinja2 import FileSystemLoader, Environment
wkhtml_path = pdfkit.configuration(wkhtmltopdf = "C:\\Program Files\\wkhtmltopdf\\bin\\wkhtmltopdf.exe") #by using configuration you can add path value.
class section:
def __init__(self, id, course, section, instructor, room):
self.id = id
self.course = course
self.section = section
self.instructor = instructor
self.room = room
def generate_data():
data = {}
# For CS-1A
data["CS-1A"] = [[[] for i in range(5)] for j in range(5)]
data["CS-1A"][0][0].append(section(1, "Advance Programming", "CS-1A", "Mr. Ashas", "Room #2"))
data["CS-1A"][0][0].append(section(2, "Programming Fundamentals", "CS-1A", "Bilal", "Room #1"))
data["CS-1A"][0][1].append(section(3, "Applied Physics", "CS-1A", "Muhammad Bilal", "Room #5"))
obj = section(4, "Programming Lab", "CS-1A", "Mr. Abid", "Lab #01")
data["CS-1A"][0][1].append(obj)
data["CS-1A"][0][2].append(obj)
data["CS-1A"][0][4].append(section(5, "English Communication", "CS-1A1", "Ms. Ayeza", "Cal Lab"))
data["CS-1A"][0][4].append(section(6, "English Communication", "CS-1A2", "Ms. Ayesha", "GP Lab"))
data["CS-1A"][1][1].append(section(7, "Linear Algebra", "CS-1A", "Ms. Zain", "Romm #2"))
obj = section(8, "English Lab", "CS-1A", "Ms. Abida", "Lab #04")
data["CS-1A"][1][3].append(obj)
data["CS-1A"][1][4].append(obj)
data["CS-1A"][2][0].append(section(9, "Social Studies", "CS-1A", "Mr. Zain Iqbal", "Room #14"))
data["CS-1A"][2][4].append(section(10, "Programming Fundamentals", "CS-1A", "Bilal", "Room #15"))
# No lectures on Thursday i.e. 3rd index
obj = section(11, "English Lab", "CS-1A", "Ms. Abida", "Lab #03")
data["CS-1A"][4][1].append(obj)
data["CS-1A"][4][2].append(obj)
data["CS-1A"][4][2].append(section(12, "English Communication", "CS-1A1", "Ms. Ayeza", "Room #3"))
data["CS-1A"][4][2].append(section(13, "English Communication", "CS-1A2", "Ms. Ayesha", "GP Lab"))
# For CS-1B
data["CS-1B"] = [[[] for i in range(5)] for j in range(5)]
data["CS-1B"][0][1].append(section(14, "Advance Programming", "CS-1B", "Mr. Ali Hassan", "Room #2"))
data["CS-1B"][0][2].append(section(15, "English Comprehension and Communication", "CS-1B", "Mr. Bilal", "Room #1"))
obj = section(15, "Software for Mobile and Devices", "CS-1B", "Mr. Jacob", "Room #5")
data["CS-1B"][1][1].append(obj)
data["CS-1B"][1][2].append(obj)
data["CS-1B"][1][3].append(section(17, "Calculus and Geometrical Analytics", "CS-1B", "Ms. Nomi Khan", "Room #06"))
data["CS-1B"][2][3].append(section(18, "Introduction to Information and Communication Technology - Lab", "CS-1B1", "Ms. Sarah Niaz", "Lab #01"))
data["CS-1B"][2][3].append(section(19, "Introduction to Information and Communication Technology - Lab", "CS-1B2", "Ms. Julia John", "Lab #06"))
data["CS-1B"][2][4].append(section(20, "English Comprehenseion and Communication", "Cs-1B", "Mr. Lionel Boyle", "Room #02"))
data["CS-1B"][3][3].append(section(21, "Programming Fundamentals", "CS-1B", "Mr. Alex Niles", "Room #3"))
data["CS-1B"][4][2].append(section(22, "Linear Algebra", "CS-1B", "Ms. Ayesha", "GP Lab"))
return data
def organise_input_data(elements: List[List[str]]) -> List[list]:
"""
Organises the input data to find double courses for easier use in templates
"""
new_elements = []
for day in elements:
last_course = None
course_list = []
index = 0
for course in day:
# check if long course (and not lunch time)
if not course:
course_list.append(("", "", "", 1))
else:
if course[0] == last_course and index != 3:
#for sub_course in course:
course_list.remove((course[0].course, course[0].section, course[0].instructor, 1))
course_list.append((course[0].course, course[0].section, course[0].instructor, 2))
course_list.append(("none", "none", "none", 0))
last_course = course[0]
else:
#for sub_course in course:
course_list.append((course[0].course, course[0].section, course[0].instructor, 1))
last_course = course[0]
index += 1
#print(course_list)
new_elements.append(course_list)
return new_elements
def generate_html(template, name: str, elements: List[list]) -> str:
new_elements = organise_input_data(elements=elements)
rendered = template.render(
name=name,
monday=new_elements[0],
tuesday=new_elements[1],
wednesday=new_elements[2],
thursday=new_elements[3],
friday=new_elements[4]
)
with open(f"out_{name}.html", "w+") as file:
file.write(rendered)
return rendered
def run(input_data):
# Init jinja
file_loader = FileSystemLoader('.')
env = Environment(loader=file_loader)
template = env.get_template('template.html')
full_text = ""
for name, elements in input_data.items():
full_text += generate_html(template=template, name=name, elements=elements)
pdfkit.from_string(full_text, "out1.pdf", configuration = wkhtml_path)
if __name__ == '__main__':
data = generate_data()
run(data)
For now, it will only consider the first Course and will place it in the Timetable, while ignoring the rest of the courses allocated on that same slot.
A sample Final Output would be like this (but with only 5 slots, not 13 slots like here)
The template.html file for my code has this following code right now,
<!DOCTYPE html>
<html>
<style>
.center
{
text-align: center;
}
.left
{
text-align: left;
margin-left: 6px;
/*margin-top: 10px;*/
}
.right
{
text-align: right; margin-right: 4px;
}
.teacher
{
margin-left: 4px;
}
td{
height:100px;
width:150px;
}
</style>
<body>
<!-- Heading -->
<h1 class="center">{{name}}</h1>
<!-- Table -->
<table border="5" cellspacing="5" align="center">
<!-- Day/Periods -->
<tr>
<td class="center" ><br>
<b>Day/Period</b></br>
</td>
<td class="center" >
<b>I</b>
</td>
<td class="center" >
<b>II</b>
</td>
<td class="center">
<b>III</b>
</td>
<td class="center">
<b>1:15-1:45</b>
</td>
<td class="center" >
<b>IV</b>
</td>
<td class="center" >
<b>V</b>
</td>
</tr>
<!-- Monday -->
<tr>
<td class="center">
<b>Monday</b></td>
{% for course in monday %}
{% if loop.index == 4 %}
<td rowspan="6" class="center">
<h2>L<br>U<br>N<br>C<br>H</h2>
</td>
{% endif %}
{% if course[3] != 0 %}
<td colspan={{course[3]}}>
<p class="left">{{course[0]}}</p>
<p class="right">{{course[1]}}</p>
<p class="teacher">{{course[2]}}</p>
</td>
{% endif %}
{% endfor %}
</tr>
<!-- Tuesday -->
<tr>
<td class="center">
<b>Tuesday</b>
</td>
{% for course in tuesday %}
{% if course[3] != 0 %}
<td colspan={{course[3]}}>
<p class="left">{{course[0]}}</p>
<p class="right">{{course[1]}}</p>
<p class="teacher">{{course[2]}}</p>
</td>
{% endif %}
{% endfor %}
</tr>
<!-- Wednesday -->
<tr>
<td class="center">
<b>Wednesday</b>
</td>
{% for course in wednesday %}
{% if course[3] != 0 %}
<td colspan={{course[3]}}>
<p class="left">{{course[0]}}</p>
<p class="right">{{course[1]}}</p>
<p class="teacher">{{course[2]}}</p></td>
{% endif %}
{% endfor %}
</tr>
<!-- Thursday -->
<tr>
<td class="center">
<b>Thursday</b>
</td>
{% for course in thursday %}
{% if course[3] != 0 %}
<td colspan={{course[3]}}>
<p class="left">{{course[0]}}</p>
<p class="right">{{course[1]}}</p>
<p class="teacher">{{course[2]}}</p></td>
{% endif %}
{% endfor %}
</tr>
<!-- Friday -->
<tr>
<td class="center">
<b>Friday</b>
</td>
{% for course in friday %}
{% if course[3] != 0 %}
<td colspan={{course[3]}}>
<p class="left">{{course[0]}}</p>
<p class="right">{{course[1]}}</p>
<p class="teacher">{{course[2]}}</p>
</td>
{% endif %}
{% endfor %}
</tr>
</table>
</body>
</html>
I am not much familiar with Jinja, so this answer might not be the most efficient one.
By using basic hard coding in your Template.HTML file, I was able to achieve the results you are trying to. For this, I used the same code that was given by D-E-N in your previous question.
I combined all the attributes of your object into a string
An attribute is differentiated from another with # (like Course and Teacher)
Instead of using space character, I used a _ character to represent space character in the attributes.
If one slot contains multiple objects, they are differentiated with space character (just like in the code provided by D-E-N)
Here's the updated code of yours with these changes,
from typing import List
import pdfkit
from pdfkit.api import configuration
from jinja2 import FileSystemLoader, Environment
wkhtml_path = pdfkit.configuration(wkhtmltopdf = "C:\\Program Files\\wkhtmltopdf\\bin\\wkhtmltopdf.exe") #by using configuration you can add path value.
class section:
def __init__(self, id, course, section, instructor, room):
self.id = id
self.course = course
self.section = section
self.instructor = instructor
self.room = room
def generate_data():
data = {}
# For CS-1A
data["CS-1A"] = [["" for i in range(5)] for j in range(5)]
data["CS-1A"][0][0] += "Advance_Programming#Mr.Ashas#Room_#2 "
data["CS-1A"][0][0] += "Applied_Physics#Bilal#Room_#1 "
data["CS-1A"][0][1] += "Programming_Fundamentals#Muhammad_Bilal#Room_#1 "
data["CS-1A"][0][3] += "Programming_Fundamentals_Lab#Mr._Abid#Lab_#01 "
data["CS-1A"][0][4] += "Programming_Fundamentals_Lab#Mr._Abid#Lab_#01 "
# You may change all these for testing purposes.
# data["CS-1A"][0][0].append(section(2, "Programming Fundamentals", "CS-1A", "Bilal", "Room #1"))
# data["CS-1A"][0][1].append(section(3, "Applied Physics", "CS-1A", "Muhammad Bilal", "Room #5"))
# obj = section(4, "Programming Lab", "CS-1A", "Mr. Abid", "Lab #01")
# data["CS-1A"][0][1].append(obj)
# data["CS-1A"][0][2].append(obj)
# data["CS-1A"][0][4].append(section(5, "English Communication", "CS-1A1", "Ms. Ayeza", "Cal Lab"))
# data["CS-1A"][0][4].append(section(6, "English Communication", "CS-1A2", "Ms. Ayesha", "GP Lab"))
# data["CS-1A"][1][1].append(section(7, "Linear Algebra", "CS-1A", "Ms. Zain", "Romm #2"))
# obj = section(8, "English Lab", "CS-1A", "Ms. Abida", "Lab #04")
# data["CS-1A"][1][3].append(obj)
# data["CS-1A"][1][4].append(obj)
# data["CS-1A"][2][0].append(section(9, "Social Studies", "CS-1A", "Mr. Zain Iqbal", "Room #14"))
# data["CS-1A"][2][4].append(section(10, "Programming Fundamentals", "CS-1A", "Bilal", "Room #15"))
# # No lectures on Thursday i.e. 3rd index
# obj = section(11, "English Lab", "CS-1A", "Ms. Abida", "Lab #03")
# data["CS-1A"][4][1].append(obj)
# data["CS-1A"][4][2].append(obj)
# data["CS-1A"][4][2].append(section(12, "English Communication", "CS-1A1", "Ms. Ayeza", "Room #3"))
# data["CS-1A"][4][2].append(section(13, "English Communication", "CS-1A2", "Ms. Ayesha", "GP Lab"))
#
#
#
# # For CS-1B
# data["CS-1B"] = [[[] for i in range(5)] for j in range(5)]
#
# data["CS-1B"][0][1].append(section(14, "Advance Programming", "CS-1B", "Mr. Ali Hassan", "Room #2"))
# data["CS-1B"][0][2].append(section(15, "English Comprehension and Communication", "CS-1B", "Mr. Bilal", "Room #1"))
# obj = section(15, "Software for Mobile and Devices", "CS-1B", "Mr. Jacob", "Room #5")
# data["CS-1B"][1][1].append(obj)
# data["CS-1B"][1][2].append(obj)
# data["CS-1B"][1][3].append(section(17, "Calculus and Geometrical Analytics", "CS-1B", "Ms. Nomi Khan", "Room #06"))
# data["CS-1B"][2][3].append(section(18, "Introduction to Information and Communication Technology - Lab", "CS-1B1", "Ms. Sarah Niaz", "Lab #01"))
# data["CS-1B"][2][3].append(section(19, "Introduction to Information and Communication Technology - Lab", "CS-1B2", "Ms. Julia John", "Lab #06"))
# data["CS-1B"][2][4].append(section(20, "English Comprehenseion and Communication", "Cs-1B", "Mr. Lionel Boyle", "Room #02"))
# data["CS-1B"][3][3].append(section(21, "Programming Fundamentals", "CS-1B", "Mr. Alex Niles", "Room #3"))
# data["CS-1B"][4][2].append(section(22, "Linear Algebra", "CS-1B", "Ms. Ayesha", "GP Lab"))
return data
def organise_input_data(elements: List[List[str]]) -> List[list]:
"""
Organises the input data to find double courses for easier use in templates
"""
new_elements = []
for day in elements:
last_course = None
course_list = []
index = 0
for course in day:
# cleanup data
course = course.strip().replace(" ", "<hr>")
# check if long course (and not lunch time)
if course != "" and course == last_course and index != 3:
course_list.remove((course, 1))
course_list.append((course, 2))
course_list.append(("none", 0))
else:
course_list.append((course.replace(" ", "<hr>"), 1))
last_course = course
index += 1
new_elements.append(course_list)
return new_elements
def generate_html(template, name: str, elements: List[list]) -> str:
new_elements = organise_input_data(elements=elements)
rendered = template.render(
name=name,
monday=new_elements[0],
tuesday=new_elements[1],
wednesday=new_elements[2],
thursday=new_elements[3],
friday=new_elements[4]
)
with open(f"out_{name}.html", "w+") as file:
file.write(rendered)
return rendered
def run(input_data):
# Init jinja
file_loader = FileSystemLoader('.')
env = Environment(loader=file_loader)
template = env.get_template('template.html')
full_text = ""
for name, elements in input_data.items():
full_text += generate_html(template=template, name=name, elements=elements)
pdfkit.from_string(full_text, "out.pdf", configuration = wkhtml_path)
if __name__ == '__main__':
data = generate_data()
run(data)
Major changes are done in the template.html file to achieve what you are trying to achieve. Here's the Code,
<!DOCTYPE html>
<html>
<style>
.center
{
text-align: center;
}
.left
{
text-align: left;
margin-left: 6px;
/*margin-top: 10px;*/
}
.right
{
text-align: right; margin-right: 4px;
}
.teacher
{
margin-left: 4px;
}
td{
height:175px;
width:150px;
}
</style>
<body>
<!-- Heading -->
<h1 class="center">{{name}}</h1>
<!-- Table -->
<table border="5" cellspacing="5" align="center">
<!-- Day/Periods -->
<tr>
<td class="center" ><br>
<b>Day/Period</b></br>
</td>
<td class="center" >
<b>I</b>
</td>
<td class="center" >
<b>II</b>
</td>
<td class="center">
<b>III</b>
</td>
<td class="center">
<b>1:15-1:45</b>
</td>
<td class="center" >
<b>IV</b>
</td>
<td class="center" >
<b>V</b>
</td>
</tr>
<!-- Monday -->
<tr>
<td class="center">
<b>Monday</b></td>
{% for course in monday %}
{% if loop.index == 4 %}
<td rowspan="6" class="center">
<h2>L<br>U<br>N<br>C<br>H</h2>
</td>
{% endif %}
{% if course[1] != 0 %}
<td colspan={{course[1]}}>
{% set count = [] %}
{%- for y in range(0, 5) -%}
{%- if count|length < course[0]|length -%}
<p class="left">
{%- for z in range(count|length, course[0]|length) -%}
{%- if course[0][count|length] == '#' -%}
{%- else -%}
{% set __ = count.append(1) %}
{%- if course[0][count|length-1] == '_' -%}
{{' '}}
{%- else -%}
{{course[0][count|length-1]}}
{%- endif -%}
{%- endif -%}
{%- endfor -%}
</p>
{% set __ = count.append(1) %}
<p class = "right">
{%- for z in range(count|length, course[0]|length) -%}
{%- if course[0][count|length] == '#' -%}
{%- else -%}
{% set __ = count.append(1) %}
{%- if course[0][count|length-1] == '_' -%}
{{' '}}
{%- else -%}
{{course[0][count|length-1]}}
{%- endif -%}
{%- endif -%}
{%- endfor -%}
</p>
{% set __ = count.append(1) %}
<p class = "teacher">
{%- for z in range(count|length, course[0]|length) -%}
{%- if course[0][count|length] == '#' -%}
{%- else -%}
{% set __ = count.append(1) %}
{%- if course[0][count|length-1] == '_' -%}
{{' '}}
{%- else -%}
{{course[0][count|length-1]}}
{%- endif -%}
{%- endif -%}
{%- endfor -%}
</p>
<!-- <p class="left">{{course[0]}}</p>
<p class="right">{{course[1]}}</p>
<p class="teacher">{{course[2]}}</p> -->
{%- endif -%}
{%- endfor -%}
</td>
{% endif %}
{% endfor %}
</tr>
<!-- Tuesday -->
<tr>
<td class="center">
<b>Tuesday</b>
</td>
{% for course in tuesday %}
{% if course[1] != 0 %}
<td colspan={{course[1]}}>
{% set count = [] %}
{%- for y in range(0, 5) -%}
{%- if count|length < course[0]|length -%}
<p class="left">
{%- for z in range(count|length, course[0]|length) -%}
{%- if course[0][count|length] == '#' -%}
{%- else -%}
{% set __ = count.append(1) %}
{%- if course[0][count|length-1] == '_' -%}
{{' '}}
{%- else -%}
{{course[0][count|length-1]}}
{%- endif -%}
{%- endif -%}
{%- endfor -%}
</p>
{% set __ = count.append(1) %}
<p class = "right">
{%- for z in range(count|length, course[0]|length) -%}
{%- if course[0][count|length] == '#' -%}
{%- else -%}
{% set __ = count.append(1) %}
{%- if course[0][count|length-1] == '_' -%}
{{' '}}
{%- else -%}
{{course[0][count|length-1]}}
{%- endif -%}
{%- endif -%}
{%- endfor -%}
</p>
{% set __ = count.append(1) %}
<p class = "teacher">
{%- for z in range(count|length, course[0]|length) -%}
{%- if course[0][count|length] == '#' -%}
{%- else -%}
{% set __ = count.append(1) %}
{%- if course[0][count|length-1] == '_' -%}
{{' '}}
{%- else -%}
{{course[0][count|length-1]}}
{%- endif -%}
{%- endif -%}
{%- endfor -%}
</p>
<!-- <p class="left">{{course[0]}}</p>
<p class="right">{{course[1]}}</p>
<p class="teacher">{{course[2]}}</p> -->
{%- endif -%}
{%- endfor -%}
</td>
{% endif %}
{% endfor %}
</tr>
<!-- Wednesday -->
<tr>
<td class="center">
<b>Wednesday</b>
</td>
{% for course in wednesday %}
{% if course[1] != 0 %}
<td colspan={{course[1]}}>
{% set count = [] %}
{%- for y in range(0, 5) -%}
{%- if count|length < course[0]|length -%}
<p class="left">
{%- for z in range(count|length, course[0]|length) -%}
{%- if course[0][count|length] == '#' -%}
{%- else -%}
{% set __ = count.append(1) %}
{%- if course[0][count|length-1] == '_' -%}
{{' '}}
{%- else -%}
{{course[0][count|length-1]}}
{%- endif -%}
{%- endif -%}
{%- endfor -%}
</p>
{% set __ = count.append(1) %}
<p class = "right">
{%- for z in range(count|length, course[0]|length) -%}
{%- if course[0][count|length] == '#' -%}
{%- else -%}
{% set __ = count.append(1) %}
{%- if course[0][count|length-1] == '_' -%}
{{' '}}
{%- else -%}
{{course[0][count|length-1]}}
{%- endif -%}
{%- endif -%}
{%- endfor -%}
</p>
{% set __ = count.append(1) %}
<p class = "teacher">
{%- for z in range(count|length, course[0]|length) -%}
{%- if course[0][count|length] == '#' -%}
{%- else -%}
{% set __ = count.append(1) %}
{%- if course[0][count|length-1] == '_' -%}
{{' '}}
{%- else -%}
{{course[0][count|length-1]}}
{%- endif -%}
{%- endif -%}
{%- endfor -%}
</p>
<!-- <p class="left">{{course[0]}}</p>
<p class="right">{{course[1]}}</p>
<p class="teacher">{{course[2]}}</p> -->
{%- endif -%}
{%- endfor -%}
</td>
{% endif %}
{% endfor %}
</tr>
<!-- Thursday -->
<tr>
<td class="center">
<b>Thursday</b>
</td>
{% for course in thursday %}
{% if course[1] != 0 %}
<td colspan={{course[1]}}>
{% set count = [] %}
{%- for y in range(0, 5) -%}
{%- if count|length < course[0]|length -%}
<p class="left">
{%- for z in range(count|length, course[0]|length) -%}
{%- if course[0][count|length] == '#' -%}
{%- else -%}
{% set __ = count.append(1) %}
{%- if course[0][count|length-1] == '_' -%}
{{' '}}
{%- else -%}
{{course[0][count|length-1]}}
{%- endif -%}
{%- endif -%}
{%- endfor -%}
</p>
{% set __ = count.append(1) %}
<p class = "right">
{%- for z in range(count|length, course[0]|length) -%}
{%- if course[0][count|length] == '#' -%}
{%- else -%}
{% set __ = count.append(1) %}
{%- if course[0][count|length-1] == '_' -%}
{{' '}}
{%- else -%}
{{course[0][count|length-1]}}
{%- endif -%}
{%- endif -%}
{%- endfor -%}
</p>
{% set __ = count.append(1) %}
<p class = "teacher">
{%- for z in range(count|length, course[0]|length) -%}
{%- if course[0][count|length] == '#' -%}
{%- else -%}
{% set __ = count.append(1) %}
{%- if course[0][count|length-1] == '_' -%}
{{' '}}
{%- else -%}
{{course[0][count|length-1]}}
{%- endif -%}
{%- endif -%}
{%- endfor -%}
</p>
<!-- <p class="left">{{course[0]}}</p>
<p class="right">{{course[1]}}</p>
<p class="teacher">{{course[2]}}</p> -->
{%- endif -%}
{%- endfor -%}
</td>
{% endif %}
{% endfor %}
</tr>
<!-- Friday -->
<tr>
<td class="center">
<b>Friday</b>
</td>
{% for course in friday %}
{% if course[1] != 0 %}
<td colspan={{course[1]}}>
{% set count = [] %}
{%- for y in range(0, 5) -%}
{%- if count|length < course[0]|length -%}
<p class="left">
{%- for z in range(count|length, course[0]|length) -%}
{%- if course[0][count|length] == '#' -%}
{%- else -%}
{% set __ = count.append(1) %}
{%- if course[0][count|length-1] == '_' -%}
{{' '}}
{%- else -%}
{{course[0][count|length-1]}}
{%- endif -%}
{%- endif -%}
{%- endfor -%}
</p>
{% set __ = count.append(1) %}
<p class = "right">
{%- for z in range(count|length, course[0]|length) -%}
{%- if course[0][count|length] == '#' -%}
{%- else -%}
{% set __ = count.append(1) %}
{%- if course[0][count|length-1] == '_' -%}
{{' '}}
{%- else -%}
{{course[0][count|length-1]}}
{%- endif -%}
{%- endif -%}
{%- endfor -%}
</p>
{% set __ = count.append(1) %}
<p class = "teacher">
{%- for z in range(count|length, course[0]|length) -%}
{%- if course[0][count|length] == '#' -%}
{%- else -%}
{% set __ = count.append(1) %}
{%- if course[0][count|length-1] == '_' -%}
{{' '}}
{%- else -%}
{{course[0][count|length-1]}}
{%- endif -%}
{%- endif -%}
{%- endfor -%}
</p>
<!-- <p class="left">{{course[0]}}</p>
<p class="right">{{course[1]}}</p>
<p class="teacher">{{course[2]}}</p> -->
{%- endif -%}
{%- endfor -%}
</td>
{% endif %}
{% endfor %}
</tr>
</table>
</body>
</html>
This produces the following result,

CS50 Finance Index. Can't get data to appear in the HTML table

I'm working on the index portion of the finance pset. I can't get the stock information to show up in the html table. I'm having a difficult time thinking how to loop through the stock information without having to create a new dictionary with the new data. Could someone help me with this direction that I'm taking? And can someone give me a "better" approach? I feel like this is not the "best" way to solve this problem. Hopefully the code appears correctly, I'm still learning how to use this site.
#app.route("/") #login_required def index():
"""Show portfolio of stocks"""
#set portfolio GROUPED BY symbol
portfolio = db.execute("SELECT symbol, SUM(shares) AS share_total FROM portfolio WHERE user_id = :user_id GROUP BY symbol", user_id = session["user_id"])
row = db.execute("SELECT cash FROM users WHERE id = :user_id", user_id = session["user_id"])
remaining_cash = row[0]["cash"]
total_holding_value = 0
stock_info = {}
for stock in portfolio:
symbol = stock["symbol"]
shares = stock["share_total"]
quote = lookup(symbol)
price = quote["price"]
holding_value = shares * price
total_holding_value += holding_value
stock_info.update({"symbol":symbol, "shares":shares, "price":price, "holding_value":holding_value})
grand_total = total_holding_value + remaining_cash
return render_template("index.html", stock_info = stock_info, remaining_cash = remaining_cash, grand_total = grand_total)
{% extends "layout.html" %}
{% block title %}
Portfolio
{% endblock %}
{% block main %}
<table class="table table-bordered">
<thead>
<th>Symbol</th>
<th>Shares</th>
<th>Price</th>
<th>Total</th>
</thead>
<tbody>
{% for stock in stock_info %}
<tr>
<td>{{ stock.symbol }}</td>
<td>{{ stock.shares }}</td>
<td>{{ stock.price }}</td>
<td>{{ stock.holding_value }}</td>
</tr>
{% endfor %}
<tr>
<td></td>
<td></td>
<td>Remaining Balance:</td>
<td>{{ remaining_cash }}</td>
</tr>
<tr>
<td></td>
<td></td>
<td>Grand Total:</td>
<td>{{ grand_total }}</td>
</tr>
</tbody>
</table>
{% endblock %}
One problem is here stock_info.update({"symbol":symbol, "shares":shares, "price":price, "holding_value":holding_value}). From the python doc [empashis added].
update([other])
Update the dictionary with the key/value pairs from other, overwriting existing keys. Return None.
Chances are you want to send a list of dictionaries to the html. Consider declaring stock_info a list, and using the append method to add each stock.

Populate table in twig with for loop

I want to populate my table in twig with a for loop and some if statement.
{% for user in users %}
<td>
{% if user.planningday == 1 %}
{{user.name}} {{user.lastname}}
{% endif %}
</td>
<td>
{% if user.planningday == 2 %}
{{user.name}} {{user.lastname}}
{% endif %}
</td>
<td>
{% if user.planningday == 3 %}
{{user.name}} {{user.lastname}}
{% endif %}
</td>
<td>
{% if user.planningday == 4 %}
{{user.name}} {{user.lastname}}
{% endif %}
</td>
<td>
{% if user.planningday == 5 %}
{{user.name}} {{user.lastname}}
{% endif %}
</td>
{% endfor %}
But that's not working and i dont know why.
Example :
I try to populate my planning with 2 user. The first user select the day 5 so friday, the second user select the day 1 so monday. In my planning, first user have his name displaying on the friday , the second one is displaying after the friday and not on the monday . Thanks for your help.
The problem is you loop all the user, thus creating a calendar for all the users. If you want to group the users into one table try this aproach
{% for i in 1..5 %}
{% set assigned_user = '' %}
{% for user in users if user.planningday == i %}
{% set assigned_user = user %}
{% endfor %}
<td>{{user.name}} {{user.lastname}}</td>
{% endfor %}
twigfiddle

save content of include in variable

I have a twig template that uses batch() to make some columns like that:
{% set rows = collection|batch(3) %}
As documented here: http://twig.sensiolabs.org/doc/filters/batch.html this function takes a second argument to define the string that is used for "missing" elements.
I am looking for something like that:
{% set html = include 'path/to/file.html.twig' %} <-- parse error
{% set rows = collection|batch(3, html) %}
Is there a way to do that or something else I can/should do?
You can assign a chunk of text by using the following snippet:
main.twig
{% set foo %}
{% include 'foo.twig' %}
{% endset %}
{% set items = ['a', 'b', 'c', 'd', 'e', 'f', 'g'] %}
<table>
{% for row in items|batch(3, foo) %}
<tr>
{% for column in row %}
<td>{{ column }}</td>
{% endfor %}
</tr>
{% endfor %}
</table>
foo.twig
<div>
<h1>Foo</h1>
</div>
twigfiddle

Resources